mirror of https://gitee.com/openkylin/linux.git
f2fs: clean up /sys/fs/f2fs/<disk>/features
Let's create /sys/fs/f2fs/<disk>/feature_list/ to meet sysfs rule. Note that there are three feature list entries: 1) /sys/fs/f2fs/features : shows runtime features supported by in-kernel f2fs along with Kconfig. - ref. F2FS_FEATURE_RO_ATTR() 2) /sys/fs/f2fs/$s_id/features <deprecated> : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This won't add new feature anymore, and thus, users should check entries in 3) instead of this 2). 3) /sys/fs/f2fs/$s_id/feature_list : shows on-disk features enabled by mkfs.f2fs per instance, which follows sysfs entry rule where each entry should expose single value. This list covers old feature list provided by 2) and beyond. Therefore, please add new on-disk feature in this list only. - ref. F2FS_SB_FEATURE_RO_ATTR() Reviewed-by: Chao Yu <yuchao0@huawei.com> Reviewed-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
4a196df4cf
commit
4c89b53d05
|
@ -203,7 +203,34 @@ Description: Shows total written kbytes issued to disk.
|
||||||
What: /sys/fs/f2fs/<disk>/features
|
What: /sys/fs/f2fs/<disk>/features
|
||||||
Date: July 2017
|
Date: July 2017
|
||||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||||
Description: Shows all enabled features in current device.
|
Description: <deprecated: should use /sys/fs/f2fs/<disk>/feature_list/
|
||||||
|
Shows all enabled features in current device.
|
||||||
|
Supported features:
|
||||||
|
encryption, blkzoned, extra_attr, projquota, inode_checksum,
|
||||||
|
flexible_inline_xattr, quota_ino, inode_crtime, lost_found,
|
||||||
|
verity, sb_checksum, casefold, readonly, compression, pin_file.
|
||||||
|
|
||||||
|
What: /sys/fs/f2fs/<disk>/feature_list/
|
||||||
|
Date: June 2021
|
||||||
|
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||||
|
Description: Expand /sys/fs/f2fs/<disk>/features to meet sysfs rule.
|
||||||
|
Supported on-disk features:
|
||||||
|
encryption, block_zoned (aka blkzoned), extra_attr,
|
||||||
|
project_quota (aka projquota), inode_checksum,
|
||||||
|
flexible_inline_xattr, quota_ino, inode_crtime, lost_found,
|
||||||
|
verity, sb_checksum, casefold, readonly, compression.
|
||||||
|
Note that, pin_file is moved into /sys/fs/f2fs/features/.
|
||||||
|
|
||||||
|
What: /sys/fs/f2fs/features/
|
||||||
|
Date: July 2017
|
||||||
|
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||||
|
Description: Shows all enabled kernel features.
|
||||||
|
Supported features:
|
||||||
|
encryption, block_zoned, extra_attr, project_quota,
|
||||||
|
inode_checksum, flexible_inline_xattr, quota_ino,
|
||||||
|
inode_crtime, lost_found, verity, sb_checksum,
|
||||||
|
casefold, readonly, compression, test_dummy_encryption_v2,
|
||||||
|
atomic_write, pin_file, encrypted_casefold.
|
||||||
|
|
||||||
What: /sys/fs/f2fs/<disk>/inject_rate
|
What: /sys/fs/f2fs/<disk>/inject_rate
|
||||||
Date: May 2016
|
Date: May 2016
|
||||||
|
|
|
@ -1665,6 +1665,9 @@ struct f2fs_sb_info {
|
||||||
struct kobject s_stat_kobj; /* /sys/fs/f2fs/<devname>/stat */
|
struct kobject s_stat_kobj; /* /sys/fs/f2fs/<devname>/stat */
|
||||||
struct completion s_stat_kobj_unregister;
|
struct completion s_stat_kobj_unregister;
|
||||||
|
|
||||||
|
struct kobject s_feature_list_kobj; /* /sys/fs/f2fs/<devname>/feature_list */
|
||||||
|
struct completion s_feature_list_kobj_unregister;
|
||||||
|
|
||||||
/* For shrinker support */
|
/* For shrinker support */
|
||||||
struct list_head s_list;
|
struct list_head s_list;
|
||||||
int s_ndevs; /* number of devices */
|
int s_ndevs; /* number of devices */
|
||||||
|
|
195
fs/f2fs/sysfs.c
195
fs/f2fs/sysfs.c
|
@ -566,50 +566,49 @@ static void f2fs_sb_release(struct kobject *kobj)
|
||||||
complete(&sbi->s_kobj_unregister);
|
complete(&sbi->s_kobj_unregister);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum feat_id {
|
/*
|
||||||
FEAT_CRYPTO = 0,
|
* Note that there are three feature list entries:
|
||||||
FEAT_BLKZONED,
|
* 1) /sys/fs/f2fs/features
|
||||||
FEAT_ATOMIC_WRITE,
|
* : shows runtime features supported by in-kernel f2fs along with Kconfig.
|
||||||
FEAT_EXTRA_ATTR,
|
* - ref. F2FS_FEATURE_RO_ATTR()
|
||||||
FEAT_PROJECT_QUOTA,
|
*
|
||||||
FEAT_INODE_CHECKSUM,
|
* 2) /sys/fs/f2fs/$s_id/features <deprecated>
|
||||||
FEAT_FLEXIBLE_INLINE_XATTR,
|
* : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This
|
||||||
FEAT_QUOTA_INO,
|
* won't add new feature anymore, and thus, users should check entries in 3)
|
||||||
FEAT_INODE_CRTIME,
|
* instead of this 2).
|
||||||
FEAT_LOST_FOUND,
|
*
|
||||||
FEAT_VERITY,
|
* 3) /sys/fs/f2fs/$s_id/feature_list
|
||||||
FEAT_SB_CHECKSUM,
|
* : shows on-disk features enabled by mkfs.f2fs per instance, which follows
|
||||||
FEAT_CASEFOLD,
|
* sysfs entry rule where each entry should expose single value.
|
||||||
FEAT_COMPRESSION,
|
* This list covers old feature list provided by 2) and beyond. Therefore,
|
||||||
FEAT_RO,
|
* please add new on-disk feature in this list only.
|
||||||
FEAT_TEST_DUMMY_ENCRYPTION_V2,
|
* - ref. F2FS_SB_FEATURE_RO_ATTR()
|
||||||
FEAT_ENCRYPTED_CASEFOLD,
|
*/
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t f2fs_feature_show(struct f2fs_attr *a,
|
static ssize_t f2fs_feature_show(struct f2fs_attr *a,
|
||||||
struct f2fs_sb_info *sbi, char *buf)
|
struct f2fs_sb_info *sbi, char *buf)
|
||||||
{
|
{
|
||||||
switch (a->id) {
|
return sprintf(buf, "supported\n");
|
||||||
case FEAT_CRYPTO:
|
}
|
||||||
case FEAT_BLKZONED:
|
|
||||||
case FEAT_ATOMIC_WRITE:
|
#define F2FS_FEATURE_RO_ATTR(_name) \
|
||||||
case FEAT_EXTRA_ATTR:
|
static struct f2fs_attr f2fs_attr_##_name = { \
|
||||||
case FEAT_PROJECT_QUOTA:
|
.attr = {.name = __stringify(_name), .mode = 0444 }, \
|
||||||
case FEAT_INODE_CHECKSUM:
|
.show = f2fs_feature_show, \
|
||||||
case FEAT_FLEXIBLE_INLINE_XATTR:
|
}
|
||||||
case FEAT_QUOTA_INO:
|
|
||||||
case FEAT_INODE_CRTIME:
|
static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
|
||||||
case FEAT_LOST_FOUND:
|
struct f2fs_sb_info *sbi, char *buf)
|
||||||
case FEAT_VERITY:
|
{
|
||||||
case FEAT_SB_CHECKSUM:
|
if (F2FS_HAS_FEATURE(sbi, a->id))
|
||||||
case FEAT_CASEFOLD:
|
|
||||||
case FEAT_COMPRESSION:
|
|
||||||
case FEAT_RO:
|
|
||||||
case FEAT_TEST_DUMMY_ENCRYPTION_V2:
|
|
||||||
case FEAT_ENCRYPTED_CASEFOLD:
|
|
||||||
return sprintf(buf, "supported\n");
|
return sprintf(buf, "supported\n");
|
||||||
}
|
return sprintf(buf, "unsupported\n");
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \
|
||||||
|
static struct f2fs_attr f2fs_attr_sb_##_name = { \
|
||||||
|
.attr = {.name = __stringify(_name), .mode = 0444 }, \
|
||||||
|
.show = f2fs_sb_feature_show, \
|
||||||
|
.id = F2FS_FEATURE_##_feat, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
|
#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
|
||||||
|
@ -629,13 +628,6 @@ static struct f2fs_attr f2fs_attr_##_name = { \
|
||||||
#define F2FS_GENERAL_RO_ATTR(name) \
|
#define F2FS_GENERAL_RO_ATTR(name) \
|
||||||
static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
|
static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
|
||||||
|
|
||||||
#define F2FS_FEATURE_RO_ATTR(_name, _id) \
|
|
||||||
static struct f2fs_attr f2fs_attr_##_name = { \
|
|
||||||
.attr = {.name = __stringify(_name), .mode = 0444 }, \
|
|
||||||
.show = f2fs_feature_show, \
|
|
||||||
.id = _id, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
|
#define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
|
||||||
static struct f2fs_attr f2fs_attr_##_name = { \
|
static struct f2fs_attr f2fs_attr_##_name = { \
|
||||||
.attr = {.name = __stringify(_name), .mode = 0444 }, \
|
.attr = {.name = __stringify(_name), .mode = 0444 }, \
|
||||||
|
@ -709,33 +701,33 @@ F2FS_GENERAL_RO_ATTR(avg_vblocks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FS_ENCRYPTION
|
#ifdef CONFIG_FS_ENCRYPTION
|
||||||
F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
|
F2FS_FEATURE_RO_ATTR(encryption);
|
||||||
F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2);
|
F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2);
|
||||||
#ifdef CONFIG_UNICODE
|
#ifdef CONFIG_UNICODE
|
||||||
F2FS_FEATURE_RO_ATTR(encrypted_casefold, FEAT_ENCRYPTED_CASEFOLD);
|
F2FS_FEATURE_RO_ATTR(encrypted_casefold);
|
||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_FS_ENCRYPTION */
|
#endif /* CONFIG_FS_ENCRYPTION */
|
||||||
#ifdef CONFIG_BLK_DEV_ZONED
|
#ifdef CONFIG_BLK_DEV_ZONED
|
||||||
F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED);
|
F2FS_FEATURE_RO_ATTR(block_zoned);
|
||||||
#endif
|
#endif
|
||||||
F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE);
|
F2FS_FEATURE_RO_ATTR(atomic_write);
|
||||||
F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR);
|
F2FS_FEATURE_RO_ATTR(extra_attr);
|
||||||
F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA);
|
F2FS_FEATURE_RO_ATTR(project_quota);
|
||||||
F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
|
F2FS_FEATURE_RO_ATTR(inode_checksum);
|
||||||
F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
|
F2FS_FEATURE_RO_ATTR(flexible_inline_xattr);
|
||||||
F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
|
F2FS_FEATURE_RO_ATTR(quota_ino);
|
||||||
F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
|
F2FS_FEATURE_RO_ATTR(inode_crtime);
|
||||||
F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
|
F2FS_FEATURE_RO_ATTR(lost_found);
|
||||||
#ifdef CONFIG_FS_VERITY
|
#ifdef CONFIG_FS_VERITY
|
||||||
F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
|
F2FS_FEATURE_RO_ATTR(verity);
|
||||||
#endif
|
#endif
|
||||||
F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
|
F2FS_FEATURE_RO_ATTR(sb_checksum);
|
||||||
#ifdef CONFIG_UNICODE
|
#ifdef CONFIG_UNICODE
|
||||||
F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD);
|
F2FS_FEATURE_RO_ATTR(casefold);
|
||||||
#endif
|
#endif
|
||||||
F2FS_FEATURE_RO_ATTR(readonly, FEAT_RO);
|
F2FS_FEATURE_RO_ATTR(readonly);
|
||||||
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
||||||
F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION);
|
F2FS_FEATURE_RO_ATTR(compression);
|
||||||
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
|
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
|
||||||
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
|
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
|
||||||
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
|
F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
|
||||||
|
@ -866,6 +858,40 @@ static struct attribute *f2fs_stat_attrs[] = {
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(f2fs_stat);
|
ATTRIBUTE_GROUPS(f2fs_stat);
|
||||||
|
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(verity, VERITY);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);
|
||||||
|
F2FS_SB_FEATURE_RO_ATTR(readonly, RO);
|
||||||
|
|
||||||
|
static struct attribute *f2fs_sb_feat_attrs[] = {
|
||||||
|
ATTR_LIST(sb_encryption),
|
||||||
|
ATTR_LIST(sb_block_zoned),
|
||||||
|
ATTR_LIST(sb_extra_attr),
|
||||||
|
ATTR_LIST(sb_project_quota),
|
||||||
|
ATTR_LIST(sb_inode_checksum),
|
||||||
|
ATTR_LIST(sb_flexible_inline_xattr),
|
||||||
|
ATTR_LIST(sb_quota_ino),
|
||||||
|
ATTR_LIST(sb_inode_crtime),
|
||||||
|
ATTR_LIST(sb_lost_found),
|
||||||
|
ATTR_LIST(sb_verity),
|
||||||
|
ATTR_LIST(sb_sb_checksum),
|
||||||
|
ATTR_LIST(sb_casefold),
|
||||||
|
ATTR_LIST(sb_compression),
|
||||||
|
ATTR_LIST(sb_readonly),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
ATTRIBUTE_GROUPS(f2fs_sb_feat);
|
||||||
|
|
||||||
static const struct sysfs_ops f2fs_attr_ops = {
|
static const struct sysfs_ops f2fs_attr_ops = {
|
||||||
.show = f2fs_attr_show,
|
.show = f2fs_attr_show,
|
||||||
.store = f2fs_attr_store,
|
.store = f2fs_attr_store,
|
||||||
|
@ -932,6 +958,33 @@ static struct kobj_type f2fs_stat_ktype = {
|
||||||
.release = f2fs_stat_kobj_release,
|
.release = f2fs_stat_kobj_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj,
|
||||||
|
struct attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
|
||||||
|
s_feature_list_kobj);
|
||||||
|
struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
|
||||||
|
|
||||||
|
return a->show ? a->show(a, sbi, buf) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f2fs_feature_list_kobj_release(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
|
||||||
|
s_feature_list_kobj);
|
||||||
|
complete(&sbi->s_feature_list_kobj_unregister);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sysfs_ops f2fs_feature_list_attr_ops = {
|
||||||
|
.show = f2fs_sb_feat_attr_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct kobj_type f2fs_feature_list_ktype = {
|
||||||
|
.default_groups = f2fs_sb_feat_groups,
|
||||||
|
.sysfs_ops = &f2fs_feature_list_attr_ops,
|
||||||
|
.release = f2fs_feature_list_kobj_release,
|
||||||
|
};
|
||||||
|
|
||||||
static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
|
static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
|
||||||
void *offset)
|
void *offset)
|
||||||
{
|
{
|
||||||
|
@ -1148,6 +1201,14 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
|
||||||
if (err)
|
if (err)
|
||||||
goto put_stat_kobj;
|
goto put_stat_kobj;
|
||||||
|
|
||||||
|
sbi->s_feature_list_kobj.kset = &f2fs_kset;
|
||||||
|
init_completion(&sbi->s_feature_list_kobj_unregister);
|
||||||
|
err = kobject_init_and_add(&sbi->s_feature_list_kobj,
|
||||||
|
&f2fs_feature_list_ktype,
|
||||||
|
&sbi->s_kobj, "feature_list");
|
||||||
|
if (err)
|
||||||
|
goto put_feature_list_kobj;
|
||||||
|
|
||||||
if (f2fs_proc_root)
|
if (f2fs_proc_root)
|
||||||
sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
|
sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
|
||||||
|
|
||||||
|
@ -1162,6 +1223,9 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
|
||||||
victim_bits_seq_show, sb);
|
victim_bits_seq_show, sb);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
put_feature_list_kobj:
|
||||||
|
kobject_put(&sbi->s_feature_list_kobj);
|
||||||
|
wait_for_completion(&sbi->s_feature_list_kobj_unregister);
|
||||||
put_stat_kobj:
|
put_stat_kobj:
|
||||||
kobject_put(&sbi->s_stat_kobj);
|
kobject_put(&sbi->s_stat_kobj);
|
||||||
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
||||||
|
@ -1184,6 +1248,9 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
|
||||||
kobject_del(&sbi->s_stat_kobj);
|
kobject_del(&sbi->s_stat_kobj);
|
||||||
kobject_put(&sbi->s_stat_kobj);
|
kobject_put(&sbi->s_stat_kobj);
|
||||||
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
||||||
|
kobject_del(&sbi->s_feature_list_kobj);
|
||||||
|
kobject_put(&sbi->s_feature_list_kobj);
|
||||||
|
wait_for_completion(&sbi->s_feature_list_kobj_unregister);
|
||||||
|
|
||||||
kobject_del(&sbi->s_kobj);
|
kobject_del(&sbi->s_kobj);
|
||||||
kobject_put(&sbi->s_kobj);
|
kobject_put(&sbi->s_kobj);
|
||||||
|
|
Loading…
Reference in New Issue