diff options
Diffstat (limited to 'fs/btrfs/sysfs.c')
| -rw-r--r-- | fs/btrfs/sysfs.c | 52 | 
1 files changed, 46 insertions, 6 deletions
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 4848a4318fb5..4a4e960c7c66 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -210,12 +210,42 @@ static struct attribute *btrfs_supported_feature_attrs[] = {  	NULL  }; +/* + * Features which depend on feature bits and may differ between each fs. + * + * /sys/fs/btrfs/features lists all available features of this kernel while + * /sys/fs/btrfs/UUID/features shows features of the fs which are enabled or + * can be changed online. + */  static const struct attribute_group btrfs_feature_attr_group = {  	.name = "features",  	.is_visible = btrfs_feature_visible,  	.attrs = btrfs_supported_feature_attrs,  }; +static ssize_t rmdir_subvol_show(struct kobject *kobj, +				 struct kobj_attribute *ka, char *buf) +{ +	return snprintf(buf, PAGE_SIZE, "0\n"); +} +BTRFS_ATTR(static_feature, rmdir_subvol, rmdir_subvol_show); + +static struct attribute *btrfs_supported_static_feature_attrs[] = { +	BTRFS_ATTR_PTR(static_feature, rmdir_subvol), +	NULL +}; + +/* + * Features which only depend on kernel version. + * + * These are listed in /sys/fs/btrfs/features along with + * btrfs_feature_attr_group + */ +static const struct attribute_group btrfs_static_feature_attr_group = { +	.name = "features", +	.attrs = btrfs_supported_static_feature_attrs, +}; +  static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)  {  	u64 val; @@ -514,10 +544,11 @@ static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)  }  #define NUM_FEATURE_BITS 64 -static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13]; -static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS]; +#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 const u64 supported_feature_masks[3] = { +static const u64 supported_feature_masks[FEAT_MAX] = {  	[FEAT_COMPAT]    = BTRFS_FEATURE_COMPAT_SUPP,  	[FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,  	[FEAT_INCOMPAT]  = BTRFS_FEATURE_INCOMPAT_SUPP, @@ -589,7 +620,7 @@ void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)  		return;  	} -	list_for_each_entry(fs_devs, fs_uuids, list) { +	list_for_each_entry(fs_devs, fs_uuids, fs_list) {  		__btrfs_sysfs_remove_fsid(fs_devs);  	}  } @@ -609,7 +640,7 @@ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info)  	btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL);  } -const char * const btrfs_feature_set_names[3] = { +const char * const btrfs_feature_set_names[FEAT_MAX] = {  	[FEAT_COMPAT]	 = "compat",  	[FEAT_COMPAT_RO] = "compat_ro",  	[FEAT_INCOMPAT]	 = "incompat", @@ -673,7 +704,7 @@ static void init_feature_attrs(void)  			if (fa->kobj_attr.attr.name)  				continue; -			snprintf(name, 13, "%s:%u", +			snprintf(name, BTRFS_FEATURE_NAME_MAX, "%s:%u",  				 btrfs_feature_set_names[set], i);  			fa->kobj_attr.attr.name = name; @@ -900,8 +931,15 @@ int __init btrfs_init_sysfs(void)  	ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);  	if (ret)  		goto out2; +	ret = sysfs_merge_group(&btrfs_kset->kobj, +				&btrfs_static_feature_attr_group); +	if (ret) +		goto out_remove_group;  	return 0; + +out_remove_group: +	sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);  out2:  	debugfs_remove_recursive(btrfs_debugfs_root_dentry);  out1: @@ -912,6 +950,8 @@ out1:  void __cold btrfs_exit_sysfs(void)  { +	sysfs_unmerge_group(&btrfs_kset->kobj, +			    &btrfs_static_feature_attr_group);  	sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);  	kset_unregister(btrfs_kset);  	debugfs_remove_recursive(btrfs_debugfs_root_dentry);  | 
