@@ -51,7 +51,7 @@ struct raid_kobject {
#define BTRFS_FEAT_ATTR(_name, _feature_set, _feature_prefix, _feature_bit) \
static struct btrfs_feature_attr btrfs_attr_features_##_name = { \
- .kobj_attr = __INIT_KOBJ_ATTR(_name, S_IRUGO, \
+ .kobj_attr = __INIT_KOBJ_ATTR(_name, 0444, \
btrfs_feature_attr_show, \
btrfs_feature_attr_store), \
.feature_set = _feature_set, \
@@ -90,6 +90,7 @@ static u64 get_features(struct btrfs_fs_info *fs_info,
enum btrfs_feature_set set)
{
struct btrfs_super_block *disk_super = fs_info->super_copy;
+
if (set == FEAT_COMPAT)
return btrfs_super_compat_flags(disk_super);
else if (set == FEAT_COMPAT_RO)
@@ -102,6 +103,7 @@ static void set_features(struct btrfs_fs_info *fs_info,
enum btrfs_feature_set set, u64 features)
{
struct btrfs_super_block *disk_super = fs_info->super_copy;
+
if (set == FEAT_COMPAT)
btrfs_set_super_compat_flags(disk_super, features);
else if (set == FEAT_COMPAT_RO)
@@ -114,6 +116,7 @@ static int can_modify_feature(struct btrfs_feature_attr *fa)
{
int val = 0;
u64 set, clear;
+
switch (fa->feature_set) {
case FEAT_COMPAT:
set = BTRFS_FEATURE_COMPAT_SAFE_SET;
@@ -147,8 +150,10 @@ static ssize_t btrfs_feature_attr_show(struct kobject *kobj,
int val = 0;
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
+
if (fs_info) {
u64 features = get_features(fs_info, fa->feature_set);
+
if (features & fa->feature_bit)
val = 1;
} else
@@ -239,7 +244,7 @@ static umode_t btrfs_feature_visible(struct kobject *kobj,
features = get_features(fs_info, fa->feature_set);
if (can_modify_feature(fa))
- mode |= S_IWUSR;
+ mode |= 0200;
else if (!(features & fa->feature_bit))
mode = 0;
}
@@ -358,6 +363,7 @@ static const struct attribute_group btrfs_debug_feature_attr_group = {
static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)
{
u64 val;
+
if (lock)
spin_lock(lock);
val = *value_ptr;
@@ -371,6 +377,7 @@ static ssize_t global_rsv_size_show(struct kobject *kobj,
{
struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
+
return btrfs_show_u64(&block_rsv->size, &block_rsv->lock, buf);
}
BTRFS_ATTR(allocation, global_rsv_size, global_rsv_size_show);
@@ -380,6 +387,7 @@ static ssize_t global_rsv_reserved_show(struct kobject *kobj,
{
struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
+
return btrfs_show_u64(&block_rsv->reserved, &block_rsv->lock, buf);
}
BTRFS_ATTR(allocation, global_rsv_reserved, global_rsv_reserved_show);
@@ -436,6 +444,7 @@ static ssize_t btrfs_space_info_show_##field(struct kobject *kobj, \
char *buf) \
{ \
struct btrfs_space_info *sinfo = to_space_info(kobj); \
+ \
return btrfs_show_u64(&sinfo->field, &sinfo->lock, buf); \
} \
BTRFS_ATTR(space_info, field, btrfs_space_info_show_##field)
@@ -446,6 +455,7 @@ static ssize_t btrfs_space_info_show_total_bytes_pinned(struct kobject *kobj,
{
struct btrfs_space_info *sinfo = to_space_info(kobj);
s64 val = percpu_counter_sum(&sinfo->total_bytes_pinned);
+
return snprintf(buf, PAGE_SIZE, "%lld\n", val);
}
@@ -479,6 +489,7 @@ ATTRIBUTE_GROUPS(space_info);
static void space_info_release(struct kobject *kobj)
{
struct btrfs_space_info *sinfo = to_space_info(kobj);
+
percpu_counter_destroy(&sinfo->total_bytes_pinned);
kfree(sinfo);
}
@@ -682,8 +693,10 @@ static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
#define NUM_FEATURE_BITS 64
#define BTRFS_FEATURE_NAME_MAX 13
-static char btrfs_unknown_feature_names[FEAT_MAX][NUM_FEATURE_BITS][BTRFS_FEATURE_NAME_MAX];
-static struct btrfs_feature_attr btrfs_feature_attrs[FEAT_MAX][NUM_FEATURE_BITS];
+static char btrfs_unknown_feature_names[FEAT_MAX][NUM_FEATURE_BITS]
+ [BTRFS_FEATURE_NAME_MAX];
+static struct btrfs_feature_attr btrfs_feature_attrs[FEAT_MAX]
+ [NUM_FEATURE_BITS];
static const u64 supported_feature_masks[FEAT_MAX] = {
[FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
@@ -703,6 +716,7 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
.attrs = attrs,
};
u64 features = get_features(fs_info, set);
+
features &= ~supported_feature_masks[set];
if (!features)
@@ -719,6 +733,7 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
attrs[0] = &fa->kobj_attr.attr;
if (add) {
int ret;
+
ret = sysfs_merge_group(&fs_info->fs_devices->fsid_kobj,
&agroup);
if (ret)
@@ -772,7 +787,8 @@ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info)
kobject_put(fs_info->space_info_kobj);
}
addrm_unknown_feature_attrs(fs_info, false);
- sysfs_remove_group(&fs_info->fs_devices->fsid_kobj, &btrfs_feature_attr_group);
+ sysfs_remove_group(&fs_info->fs_devices->fsid_kobj,
+ &btrfs_feature_attr_group);
sysfs_remove_files(&fs_info->fs_devices->fsid_kobj, btrfs_attrs);
btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL);
}
@@ -831,6 +847,7 @@ static void init_feature_attrs(void)
struct btrfs_feature_attr *sfa;
struct attribute *a = btrfs_supported_feature_attrs[i];
int bit;
+
sfa = attr_to_btrfs_feature_attr(a);
bit = ilog2(sfa->feature_bit);
fa = &btrfs_feature_attrs[sfa->feature_set][bit];
@@ -841,6 +858,7 @@ static void init_feature_attrs(void)
for (set = 0; set < FEAT_MAX; set++) {
for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) {
char *name = btrfs_unknown_feature_names[set][i];
+
fa = &btrfs_feature_attrs[set][i];
if (fa->kobj_attr.attr.name)
@@ -850,7 +868,7 @@ static void init_feature_attrs(void)
btrfs_feature_set_names[set], i);
fa->kobj_attr.attr.name = name;
- fa->kobj_attr.attr.mode = S_IRUGO;
+ fa->kobj_attr.attr.mode = 0444;
fa->feature_set = set;
fa->feature_bit = 1ULL << i;
}
@@ -1189,7 +1207,8 @@ int __init btrfs_init_sysfs(void)
goto out_remove_group;
#ifdef CONFIG_BTRFS_DEBUG
- ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_debug_feature_attr_group);
+ ret = sysfs_create_group(&btrfs_kset->kobj,
+ &btrfs_debug_feature_attr_group);
if (ret)
goto out2;
#endif
@@ -17,7 +17,7 @@ const char * const btrfs_feature_set_name(enum btrfs_feature_set set);
int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices,
struct btrfs_device *one_device);
int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices,
- struct btrfs_device *one_device);
+ struct btrfs_device *one_device);
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
struct kobject *parent);
int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs);
@@ -26,7 +26,8 @@ void btrfs_sysfs_update_sprout_fsid(struct btrfs_fs_devices *fs_devices,
const u8 *fsid);
void btrfs_sysfs_feature_update(struct btrfs_fs_info *fs_info,
u64 bit, enum btrfs_feature_set set);
-void btrfs_kobject_uevent(struct block_device *bdev, enum kobject_action action);
+void btrfs_kobject_uevent(struct block_device *bdev,
+ enum kobject_action action);
int __init btrfs_init_sysfs(void);
void __cold btrfs_exit_sysfs(void);