f2fs: expose /sys/fs/f2fs/features
Subsystems (2)
Jaegeuk Kim
maintainerPATCH 1/2 f2fs: expose /sys/fs/f2fs/features
This patch exposes what features are supported by current f2fs build to sysfs entry.
--- fs/f2fs/f2fs.h | 6 +++ fs/f2fs/file.c | 3 +- fs/f2fs/sysfs.c | 114 +++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 96 insertions(+), 27 deletions(-)
fs/f2fs/f2fs.h +6 -0
@@ -2864,6 +2864,12 @@ static inline int f2fs_sb_has_project_quota(struct super_block *sb)return F2FS_HAS_FEATURE (sb,F2FS_FEATURE_PRJQUOTA ); } +static inline int f2fs_sb_support_atomic_write (void ) +{ +/* Validated with sqlite */ +return 1 ; +} +#ifdef CONFIG_BLK_DEV_ZONED static inline int get_blkz_type (struct f2fs_sb_info *sbi,struct block_device *bdev,block_t blkaddr)
fs/f2fs/file.c +2 -1
@@ -2384,7 +2384,8 @@ static int f2fs_ioc_get_features(struct file *filp, unsigned long arg)u32 sb_feature =le32_to_cpu (F2FS_I_SB (inode)->raw_super->feature);/* Must validate to set it with SQLite behavior in Android. */ - sb_feature |=F2FS_FEATURE_ATOMIC_WRITE ; +if (f2fs_sb_support_atomic_write ()) + sb_feature |=F2FS_FEATURE_ATOMIC_WRITE ;return put_user (sb_feature, (u32 __user *)arg); }
fs/f2fs/sysfs.c +88 -26
192 lines not on this page · raw message
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
Jaegeuk Kim
maintainerPATCH 2/2 f2fs: don't give partially written atomic data from process crash
This patch resolves the below scenario.
== Process 1 == == Process 2 ==
open(w) open(rw)
beginwrite(new_#1)process_crash
f_op->flush
locks_remove_posix
f_op>release
read (new_#1)
In order to avoid corrupted database caused by new_#1, we must do roll-back at process_crash time. In order to check that, this patch keeps task which triggers transaction begin, and does roll-back in f_op->flush before removing file locks.
--- fs/f2fs/f2fs.h | 1 + fs/f2fs/file.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+)
fs/f2fs/f2fs.h +1 -0
@@ -565,6 +565,7 @@ struct f2fs_inode_info {struct list_head dirty_list;/* dirty list for dirs and files */ struct list_head gdirty_list;/* linked in global dirty list */ struct list_head inmem_pages;/* inmemory pages managed by f2fs */ +struct task_struct *inmem_task;/* store inmemory task */ struct mutex inmem_lock;/* lock for inmemory pages */ struct extent_tree *extent_tree;/* cached extent_tree entry */ struct rw_semaphore dio_rwsem[2 ];/* avoid racing between dio and gc */
fs/f2fs/file.c +18 -0
@@ -1502,6 +1502,22 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)return 0 ; } +static int f2fs_file_flush (struct file *file,fl_owner_t id) +{ +struct inode *inode =file_inode (file); + +/* +* If the process doing a transaction is crashed, we should do +* roll-back. Otherwise, other reader/write can see corrupted database +* until all the writers close its file. Since this should be done +* before dropping file lock, it needs to do in ->flush. +*/ +if (f2fs_is_atomic_file (inode) && +F2FS_I (inode)->inmem_task == current) +drop_inmem_pages (inode); +return 0 ; +} +static int f2fs_ioc_getflags (struct file *filp,unsigned long arg) {struct inode *inode =file_inode (filp);
@@ -1608,6 +1624,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) } inc_stat: +F2FS_I (inode)->inmem_task = current;stat_inc_atomic_write (inode);stat_update_max_atomic_write (inode); out:
@@ -2514,6 +2531,7 @@ const struct file_operations f2fs_file_operations = { .open = f2fs_file_open, .release = f2fs_release_file, .mmap = f2fs_file_mmap, + .flush = f2fs_file_flush, .fsync = f2fs_sync_file, .fallocate = f2fs_fallocate, .unlocked_ioctl = f2fs_ioctl,
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
Re: [f2fs-dev] [PATCH 2/2] f2fs: don't give partially written atomic data from process crash
Quoted 10 lines · Jaegeuk Kim
This patch resolves the below scenario.
== Process 1 == == Process 2 ==
open(w) open(rw)
beginwrite(new_#1)process_crash
f_op->flush
locks_remove_posix
f_op>release
Quoted 8 lines
read (new_#1)In order to avoid corrupted database caused by new_#1, we must do roll-back at
process_crashtime. In order to check that, this patch keeps task which triggers transaction begin, and does roll-back inf_op->flushbefore removing file locks.Signed-off-by Jaegeuk Kim <[email protected]>
Thanks,
Quoted 61 lines
--- fs/f2fs/f2fs.h | 1 + fs/f2fs/file.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+)fs/f2fs/f2fs.h +1
-0@@ -565,6 +565,7 @@ struct f2fs_inode_info {struct list_head dirty_list;/* dirty list for dirs and files */ struct list_head gdirty_list;/* linked in global dirty list */ struct list_head inmem_pages;/* inmemory pages managed by f2fs */ +struct task_struct *inmem_task;/* store inmemory task */ struct mutex inmem_lock;/* lock for inmemory pages */ struct extent_tree *extent_tree;/* cached extent_tree entry */ struct rw_semaphore dio_rwsem[2 ];/* avoid racing between dio and gc */ fs/f2fs/file.c +18
-0@@ -1502,6 +1502,22 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)return 0 ; } +static int f2fs_file_flush (struct file *file,fl_owner_t id) +{ +struct inode *inode =file_inode (file); + +/* +* If the process doing a transaction is crashed, we should do +* roll-back. Otherwise, other reader/write can see corrupted database +* until all the writers close its file. Since this should be done +* before dropping file lock, it needs to do in ->flush. +*/ +if (f2fs_is_atomic_file (inode) && +F2FS_I (inode)->inmem_task == current) +drop_inmem_pages (inode); +return 0 ; +} +static int f2fs_ioc_getflags (struct file *filp,unsigned long arg) {struct inode *inode =file_inode (filp);@@ -1608,6 +1624,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) } inc_stat: +F2FS_I (inode)->inmem_task = current;stat_inc_atomic_write (inode);stat_update_max_atomic_write (inode); out:@@ -2514,6 +2531,7 @@ const struct file_operations f2fs_file_operations = { .open = f2fs_file_open, .release = f2fs_release_file, .mmap = f2fs_file_mmap, + .flush = f2fs_file_flush, .fsync = f2fs_sync_file, .fallocate = f2fs_fallocate, .unlocked_ioctl = f2fs_ioctl,
Quoted 4 lines · Jaegeuk Kim
This patch exposes what features are supported by current f2fs build to sysfs entry.
Signed-off-by Jaegeuk Kim <[email protected]>
Minor thing, can you exchange below function name to follow ext4:f2fs_init_sysfs <-> f2fs_register_sysfsf2fs_exit_sysfs <-> f2fs_unregister_sysfs
Thanks,
Quoted 243 lines
--- fs/f2fs/f2fs.h | 6 +++ fs/f2fs/file.c | 3 +- fs/f2fs/sysfs.c | 114 +++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 96 insertions(+), 27 deletions(-)fs/f2fs/f2fs.h +6
-0@@ -2864,6 +2864,12 @@ static inline int f2fs_sb_has_project_quota(struct super_block *sb)return F2FS_HAS_FEATURE (sb,F2FS_FEATURE_PRJQUOTA ); } +static inline int f2fs_sb_support_atomic_write (void ) +{ +/* Validated with sqlite */ +return 1 ; +} +#ifdef CONFIG_BLK_DEV_ZONED static inline int get_blkz_type (struct f2fs_sb_info *sbi,struct block_device *bdev,block_t blkaddr)fs/f2fs/file.c +2
-1@@ -2384,7 +2384,8 @@ static int f2fs_ioc_get_features(struct file *filp, unsigned long arg)u32 sb_feature =le32_to_cpu (F2FS_I_SB (inode)->raw_super->feature);/* Must validate to set it with SQLite behavior in Android. */ - sb_feature |=F2FS_FEATURE_ATOMIC_WRITE ; +if (f2fs_sb_support_atomic_write ()) + sb_feature |=F2FS_FEATURE_ATOMIC_WRITE ;return put_user (sb_feature, (u32 __user *)arg); }fs/f2fs/sysfs.c +88
-26@@ -18,7 +18,6 @@#include "gc.h" static struct proc_dir_entry *f2fs_proc_root; -static struct kset *f2fs_kset;/* Sysfs support for f2fs */ enum {@@ -41,6 +40,7 @@ struct f2fs_attr { const char *, size_t);int struct_type;int offset; +int id; };static unsigned char *__struct_ptr (struct f2fs_sb_info *sbi,int struct_type)@@ -155,6 +155,24 @@ static void f2fs_sb_release(struct kobject *kobj)complete (&sbi->s_kobj_unregister); } +enum feat_id { +FEAT_CRYPTO =0 , +FEAT_BLKZONED , +FEAT_ATOMIC_WRITE , +}; + +static ssize_t f2fs_feature_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +switch (a->id) { +case FEAT_CRYPTO : +case FEAT_BLKZONED : +case FEAT_ATOMIC_WRITE : +return snprintf (buf,PAGE_SIZE ,"supported\n" ); + } +return 0 ; +} +#define F2FS_ATTR_OFFSET (_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \@@ -172,6 +190,13 @@ static struct f2fs_attr f2fs_attr_##_name = { \#define F2FS_GENERAL_RO_ATTR (name) \ 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, \ +} +F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);@@ -197,6 +222,14 @@ F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);#endif F2FS_GENERAL_RO_ATTR (lifetime_write_kbytes); +#ifdef CONFIG_F2FS_FS_ENCRYPTION +F2FS_FEATURE_RO_ATTR (encryption,FEAT_CRYPTO ); +#endif +#ifdef CONFIG_BLK_DEV_ZONED +F2FS_FEATURE_RO_ATTR (block_zoned,FEAT_BLKZONED ); +#endif +F2FS_FEATURE_RO_ATTR (atomic_write,FEAT_ATOMIC_WRITE ); +#define ATTR_LIST (name) (&f2fs_attr_##name.attr)static struct attribute *f2fs_attrs[] = {ATTR_LIST (gc_min_sleep_time),@@ -226,17 +259,45 @@ static struct attribute *f2fs_attrs[] = { NULL, }; +static struct attribute *f2fs_feat_attrs[] = { +#ifdef CONFIG_F2FS_FS_ENCRYPTION + ATTR_LIST(encryption), +#endif +#ifdef CONFIG_BLK_DEV_ZONED +ATTR_LIST (block_zoned), +#endif +ATTR_LIST (atomic_write), + NULL, +}; +static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, }; -static struct kobj_type f2fs_ktype = { +static struct kobj_type f2fs_sb_ktype = { .default_attrs = f2fs_attrs, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; +static struct kobj_type f2fs_ktype = { + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, +}; + +static struct kobj_type f2fs_feat_ktype = { + .default_attrs = f2fs_feat_attrs, + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kobject f2fs_feat = { + .kset = &f2fs_kset, +}; +static int segment_info_seq_show (struct seq_file *seq,void *offset) {struct super_block *sb = seq->private;@@ -306,18 +367,29 @@ F2FS_PROC_FILE_DEF(segment_bits);int __init f2fs_register_sysfs (void ) { - f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +int ret; - f2fs_kset =kset_create_and_add ("f2fs" ,NULL , fs_kobj); -if (!f2fs_kset) -return -ENOMEM ; -return 0 ; +kobject_set_name (&f2fs_kset.kobj,"f2fs" ); + f2fs_kset.kobj.parent = fs_kobj; + ret =kset_register (&f2fs_kset); +if (ret) +return ret; + + ret =kobject_init_and_add (&f2fs_feat, &f2fs_feat_ktype, +NULL ,"features" ); +if (ret) +kset_unregister (&f2fs_kset); +else + f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +return ret; }void f2fs_unregister_sysfs (void ) { -kset_unregister (f2fs_kset); +kobject_put (&f2fs_feat); +kset_unregister (&f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); + f2fs_proc_root =NULL ; }int f2fs_init_sysfs (struct f2fs_sb_info *sbi)@@ -325,6 +397,13 @@ int f2fs_init_sysfs(struct f2fs_sb_info *sbi)struct super_block *sb = sbi->sb;int err; + sbi->s_kobj.kset = &f2fs_kset; +init_completion (&sbi->s_kobj_unregister); + err =kobject_init_and_add (&sbi->s_kobj, &f2fs_sb_ktype,NULL , +"%s" , sb->s_id); +if (err) +return err; +if (f2fs_proc_root) sbi->s_proc =proc_mkdir (sb->s_id, f2fs_proc_root);@@ -334,32 +413,15 @@ int f2fs_init_sysfs(struct f2fs_sb_info *sbi)proc_create_data ("segment_bits" ,S_IRUGO , sbi->s_proc, &f2fs_seq_segment_bits_fops, sb); } - - sbi->s_kobj.kset = f2fs_kset; -init_completion (&sbi->s_kobj_unregister); - err =kobject_init_and_add (&sbi->s_kobj, &f2fs_ktype,NULL , -"%s" , sb->s_id); -if (err) - goto err_out;return 0 ; -err_out: -if (sbi->s_proc) { -remove_proc_entry ("segment_info" , sbi->s_proc); -remove_proc_entry ("segment_bits" , sbi->s_proc); -remove_proc_entry (sb->s_id, f2fs_proc_root); - } -return err; }void f2fs_exit_sysfs (struct f2fs_sb_info *sbi) { -kobject_del (&sbi->s_kobj); -kobject_put (&sbi->s_kobj); -wait_for_completion (&sbi->s_kobj_unregister); -if (sbi->s_proc) {remove_proc_entry ("segment_info" , sbi->s_proc);remove_proc_entry ("segment_bits" , sbi->s_proc);remove_proc_entry (sbi->sb->s_id, f2fs_proc_root); } +kobject_del (&sbi->s_kobj); }
Jaegeuk Kim
maintainerQuoted 6 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim
This patch exposes what features are supported by current f2fs build to sysfs entry.
Signed-off-by Jaegeuk Kim <[email protected]>
Quoted 7 lines
Reviewed-by Chao Yu <[email protected]>Minor thing, can you exchange below function name to follow ext4:
f2fs_init_sysfs<->f2fs_register_sysfsf2fs_exit_sysfs<->f2fs_unregister_sysfsFrom
4cf8a3138f3ee171750ae279fefd4de672a0ee29Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <[email protected]>
Date: Wed, 26 Jul 2017 11:24:13 -0700
Subject: [PATCH] f2fs: avoid naming confusion of sysfs init
This patch changes the function names of sysfs init to follow ext4.
f2fs_init_sysfs <-> f2fs_register_sysfs f2fs_exit_sysfs <-> f2fs_unregister_sysfs
--- fs/f2fs/f2fs.h | 8 ++++---- fs/f2fs/super.c | 10 +++++----- fs/f2fs/sysfs.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-)
fs/f2fs/f2fs.h +4 -4
@@ -2820,10 +2820,10 @@ void destroy_extent_cache(void);/* * sysfs.c */ -int __init f2fs_register_sysfs (void ); -void f2fs_unregister_sysfs (void ); -int f2fs_init_sysfs (struct f2fs_sb_info *sbi); -void f2fs_exit_sysfs (struct f2fs_sb_info *sbi); +int __init f2fs_init_sysfs (void ); +void f2fs_exit_sysfs (void ); +int f2fs_register_sysfs (struct f2fs_sb_info *sbi); +void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi);/* * crypto support
fs/f2fs/super.c +5 -5
@@ -649,7 +649,7 @@ static void f2fs_put_super(struct super_block *sb)kfree (sbi->ckpt); -f2fs_exit_sysfs (sbi); +f2fs_unregister_sysfs (sbi); sb->s_fs_info =NULL ;if (sbi->s_chksum_driver)
@@ -2145,7 +2145,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_root_inode; } - err =f2fs_init_sysfs (sbi); + err =f2fs_register_sysfs (sbi);if (err) goto free_root_inode;
@@ -2216,7 +2216,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) free_sysfs:f2fs_sync_inode_meta (sbi); -f2fs_exit_sysfs (sbi); +f2fs_unregister_sysfs (sbi); free_root_inode:dput (sb->s_root); sb->s_root =NULL ;
@@ -2334,7 +2334,7 @@ static int __init init_f2fs_fs(void) err =create_extent_cache ();if (err) goto free_checkpoint_caches; - err =f2fs_register_sysfs (); + err =f2fs_init_sysfs ();if (err) goto free_extent_cache; err =register_shrinker (&f2fs_shrinker_info);
@@ -2373,7 +2373,7 @@ static void __exit exit_f2fs_fs(void)f2fs_destroy_root_stats ();unregister_filesystem (&f2fs_fs_type);unregister_shrinker (&f2fs_shrinker_info); -f2fs_unregister_sysfs (); +f2fs_exit_sysfs ();destroy_extent_cache ();destroy_checkpoint_caches ();destroy_segment_manager_caches ();
fs/f2fs/sysfs.c +4 -4
@@ -304,7 +304,7 @@ static const struct file_operations f2fs_seq_##_name##_fops = { \F2FS_PROC_FILE_DEF (segment_info);F2FS_PROC_FILE_DEF (segment_bits); -int __init f2fs_register_sysfs (void ) +int __init f2fs_init_sysfs (void ) { f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL );
@@ -314,13 +314,13 @@ int __init f2fs_register_sysfs(void)return 0 ; } -void f2fs_unregister_sysfs (void ) +void f2fs_exit_sysfs (void ) {kset_unregister (f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); } -int f2fs_init_sysfs (struct f2fs_sb_info *sbi) +int f2fs_register_sysfs (struct f2fs_sb_info *sbi) {struct super_block *sb = sbi->sb;int err;
@@ -351,7 +351,7 @@ int f2fs_init_sysfs(struct f2fs_sb_info *sbi)return err; } -void f2fs_exit_sysfs (struct f2fs_sb_info *sbi) +void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi) {kobject_del (&sbi->s_kobj);kobject_put (&sbi->s_kobj);
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
Quoted 18 lines · Jaegeuk Kim
Quoted 6 lines · Chao Yu
Quoted 4 lines · Jaegeuk Kim
This patch exposes what features are supported by current f2fs build to sysfs entry.
Signed-off-by Jaegeuk Kim <[email protected]>Quoted 7 lines
Reviewed-by Chao Yu <[email protected]>Minor thing, can you exchange below function name to follow ext4:
f2fs_init_sysfs<->f2fs_register_sysfsf2fs_exit_sysfs<->f2fs_unregister_sysfsFrom
4cf8a3138f3ee171750ae279fefd4de672a0ee29Mon Sep 17 00:00:00 2001From: Jaegeuk Kim <[email protected]>
Date: Wed, 26 Jul 2017 11:24:13 -0700
Subject: [PATCH] f2fs: avoid naming confusion of sysfs init
Quoted 7 lines
This patch changes the function names of sysfs init to follow ext4.
f2fs_init_sysfs<->f2fs_register_sysfsf2fs_exit_sysfs<->f2fs_unregister_sysfsSuggested-by Chao Yu <[email protected]>Signed-off-by Jaegeuk Kim <[email protected]>
Thanks,
Quoted 105 lines
--- fs/f2fs/f2fs.h | 8 ++++---- fs/f2fs/super.c | 10 +++++----- fs/f2fs/sysfs.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-)fs/f2fs/f2fs.h +4
-4@@ -2820,10 +2820,10 @@ void destroy_extent_cache(void);/* * sysfs.c */ -int __init f2fs_register_sysfs (void ); -void f2fs_unregister_sysfs (void ); -int f2fs_init_sysfs (struct f2fs_sb_info *sbi); -void f2fs_exit_sysfs (struct f2fs_sb_info *sbi); +int __init f2fs_init_sysfs (void ); +void f2fs_exit_sysfs (void ); +int f2fs_register_sysfs (struct f2fs_sb_info *sbi); +void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi);/* * crypto support fs/f2fs/super.c +5
-5@@ -649,7 +649,7 @@ static void f2fs_put_super(struct super_block *sb)kfree (sbi->ckpt); -f2fs_exit_sysfs (sbi); +f2fs_unregister_sysfs (sbi); sb->s_fs_info =NULL ;if (sbi->s_chksum_driver)@@ -2145,7 +2145,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_root_inode; } - err =f2fs_init_sysfs (sbi); + err =f2fs_register_sysfs (sbi);if (err) goto free_root_inode;@@ -2216,7 +2216,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) free_sysfs:f2fs_sync_inode_meta (sbi); -f2fs_exit_sysfs (sbi); +f2fs_unregister_sysfs (sbi); free_root_inode:dput (sb->s_root); sb->s_root =NULL ;@@ -2334,7 +2334,7 @@ static int __init init_f2fs_fs(void) err =create_extent_cache ();if (err) goto free_checkpoint_caches; - err =f2fs_register_sysfs (); + err =f2fs_init_sysfs ();if (err) goto free_extent_cache; err =register_shrinker (&f2fs_shrinker_info);@@ -2373,7 +2373,7 @@ static void __exit exit_f2fs_fs(void)f2fs_destroy_root_stats ();unregister_filesystem (&f2fs_fs_type);unregister_shrinker (&f2fs_shrinker_info); -f2fs_unregister_sysfs (); +f2fs_exit_sysfs ();destroy_extent_cache ();destroy_checkpoint_caches ();destroy_segment_manager_caches ();fs/f2fs/sysfs.c +3
-3@@ -304,7 +304,7 @@ static const struct file_operations f2fs_seq_##_name##_fops = { \F2FS_PROC_FILE_DEF (segment_info);F2FS_PROC_FILE_DEF (segment_bits); -int __init f2fs_register_sysfs (void ) +int __init f2fs_init_sysfs (void ) { f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL );@@ -314,13 +314,13 @@ int __init f2fs_register_sysfs(void)return 0 ; } -void f2fs_unregister_sysfs (void ) +void f2fs_exit_sysfs (void ) {kset_unregister (f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); } -int f2fs_init_sysfs (struct f2fs_sb_info *sbi) +int f2fs_register_sysfs (struct f2fs_sb_info *sbi) {struct super_block *sb = sbi->sb;int err;
fs/f2fs/sysfs.c int f2fs_init_sysfs(struct f2fs_sb_info *sbi) · line 357
Quoted 8 lines
fs/f2fs/sysfs.c +1
-1@@ -351,7 +351,7 @@ int f2fs_init_sysfs(struct f2fs_sb_info *sbi)return err; } -void f2fs_exit_sysfs (struct f2fs_sb_info *sbi) +void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi) {kobject_del (&sbi->s_kobj);kobject_put (&sbi->s_kobj);
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Jaegeuk Kim
maintainerChange log from v1:
- add /sys/fs/f2fs/dev/features
This patch exposes what features are supported by current f2fs build to sysfs entry via:
/sys/fs/f2fs/features//sys/fs/f2fs/dev/features
--- fs/f2fs/sysfs.c | 138 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 26 deletions(-)
fs/f2fs/sysfs.c +112 -26
@@ -18,7 +18,6 @@#include "gc.h" static struct proc_dir_entry *f2fs_proc_root; -static struct kset *f2fs_kset;/* Sysfs support for f2fs */ enum {
@@ -41,6 +40,7 @@ struct f2fs_attr { const char *, size_t);int struct_type;int offset; +int id; };static unsigned char *__struct_ptr (struct f2fs_sb_info *sbi,int struct_type)
@@ -76,6 +76,28 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, BD_PART_WRITTEN(sbi))); } +static ssize_t features_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +struct super_block *sb = sbi->sb; +int len =0 ; + +if (!sb->s_bdev->bd_part) +return snprintf (buf,PAGE_SIZE ,"0\n" ); + +if (f2fs_sb_has_crypto (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,"encryption" ); +if (f2fs_sb_mounted_blkzoned (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", blkzoned" ); +if (f2fs_sb_has_extra_attr (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", extra_attr" ); +if (f2fs_sb_has_project_quota (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", projquota" ); +if (f2fs_sb_has_inode_chksum (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", inode_checksum" ); +return len; +} +static ssize_t f2fs_sbi_show (struct f2fs_attr *a,struct f2fs_sb_info *sbi,char *buf) {
@@ -155,6 +177,24 @@ static void f2fs_sb_release(struct kobject *kobj)complete (&sbi->s_kobj_unregister); } +enum feat_id { +FEAT_CRYPTO =0 , +FEAT_BLKZONED , +FEAT_ATOMIC_WRITE , +}; + +static ssize_t f2fs_feature_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +switch (a->id) { +case FEAT_CRYPTO : +case FEAT_BLKZONED : +case FEAT_ATOMIC_WRITE : +return snprintf (buf,PAGE_SIZE ,"supported\n" ); + } +return 0 ; +} +#define F2FS_ATTR_OFFSET (_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -172,6 +212,13 @@ static struct f2fs_attr f2fs_attr_##_name = { \#define F2FS_GENERAL_RO_ATTR (name) \ 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, \ +} +F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
@@ -196,6 +243,15 @@ F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);F2FS_RW_ATTR (FAULT_INFO_TYPE , f2fs_fault_info, inject_type, inject_type);#endif F2FS_GENERAL_RO_ATTR (lifetime_write_kbytes); +F2FS_GENERAL_RO_ATTR (features); + +#ifdef CONFIG_F2FS_FS_ENCRYPTION +F2FS_FEATURE_RO_ATTR (encryption,FEAT_CRYPTO ); +#endif +#ifdef CONFIG_BLK_DEV_ZONED +F2FS_FEATURE_RO_ATTR (block_zoned,FEAT_BLKZONED ); +#endif +F2FS_FEATURE_RO_ATTR (atomic_write,FEAT_ATOMIC_WRITE );#define ATTR_LIST (name) (&f2fs_attr_##name.attr)static struct attribute *f2fs_attrs[] = {
@@ -222,21 +278,50 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(inject_type), #endif ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(features), ATTR_LIST(reserved_blocks), NULL, }; +static struct attribute *f2fs_feat_attrs[] = { +#ifdef CONFIG_F2FS_FS_ENCRYPTION + ATTR_LIST(encryption), +#endif +#ifdef CONFIG_BLK_DEV_ZONED + ATTR_LIST(block_zoned), +#endif + ATTR_LIST(atomic_write), + NULL, +}; + static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, }; -static struct kobj_type f2fs_ktype = { +static struct kobj_type f2fs_sb_ktype = { .default_attrs = f2fs_attrs, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; +static struct kobj_type f2fs_ktype = { + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, +}; + +static struct kobj_type f2fs_feat_ktype = { + .default_attrs = f2fs_feat_attrs, + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kobject f2fs_feat = { + .kset = &f2fs_kset, +}; + static int segment_info_seq_show(struct seq_file *seq, void *offset) { struct super_block *sb = seq->private;
@@ -306,18 +391,29 @@ F2FS_PROC_FILE_DEF(segment_bits);int __init f2fs_init_sysfs (void ) { - f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +int ret; - f2fs_kset =kset_create_and_add ("f2fs" ,NULL , fs_kobj); -if (!f2fs_kset) -return -ENOMEM ; -return 0 ; +kobject_set_name (&f2fs_kset.kobj,"f2fs" ); + f2fs_kset.kobj.parent = fs_kobj; + ret =kset_register (&f2fs_kset); +if (ret) +return ret; + + ret =kobject_init_and_add (&f2fs_feat, &f2fs_feat_ktype, +NULL ,"features" ); +if (ret) +kset_unregister (&f2fs_kset); +else + f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +return ret; }void f2fs_exit_sysfs (void ) { -kset_unregister (f2fs_kset); +kobject_put (&f2fs_feat); +kset_unregister (&f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); + f2fs_proc_root =NULL ; }int f2fs_register_sysfs (struct f2fs_sb_info *sbi)
@@ -325,6 +421,13 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)struct super_block *sb = sbi->sb;int err; + sbi->s_kobj.kset = &f2fs_kset; +init_completion (&sbi->s_kobj_unregister); + err =kobject_init_and_add (&sbi->s_kobj, &f2fs_sb_ktype,NULL , +"%s" , sb->s_id); +if (err) +return err; +if (f2fs_proc_root) sbi->s_proc =proc_mkdir (sb->s_id, f2fs_proc_root);
@@ -334,32 +437,15 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)proc_create_data ("segment_bits" ,S_IRUGO , sbi->s_proc, &f2fs_seq_segment_bits_fops, sb); } - - sbi->s_kobj.kset = f2fs_kset; -init_completion (&sbi->s_kobj_unregister); - err =kobject_init_and_add (&sbi->s_kobj, &f2fs_ktype,NULL , -"%s" , sb->s_id); -if (err) - goto err_out;return 0 ; -err_out: -if (sbi->s_proc) { -remove_proc_entry ("segment_info" , sbi->s_proc); -remove_proc_entry ("segment_bits" , sbi->s_proc); -remove_proc_entry (sb->s_id, f2fs_proc_root); - } -return err; }void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi) { -kobject_del (&sbi->s_kobj); -kobject_put (&sbi->s_kobj); -wait_for_completion (&sbi->s_kobj_unregister); -if (sbi->s_proc) {remove_proc_entry ("segment_info" , sbi->s_proc);remove_proc_entry ("segment_bits" , sbi->s_proc);remove_proc_entry (sbi->sb->s_id, f2fs_proc_root); } +kobject_del (&sbi->s_kobj); }
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
Chao Yu
maintainerHi Jaegeuk,
Quoted 38 lines · Jaegeuk Kim
Change log from v1:
- add/sys/fs/f2fs/dev/featuresThis patch exposes what features are supported by current f2fs build to sysfs entry via:
/sys/fs/f2fs/features/>/sys/fs/f2fs/dev/featuresSigned-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/sysfs.c | 138 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 26 deletions(-)fs/f2fs/sysfs.c +2
-1@@ -18,7 +18,6 @@#include "gc.h" static struct proc_dir_entry *f2fs_proc_root; -static struct kset *f2fs_kset;/* Sysfs support for f2fs */ enum {@@ -41,6 +40,7 @@ struct f2fs_attr { const char *, size_t);int struct_type;int offset; +int id; };static unsigned char *__struct_ptr (struct f2fs_sb_info *sbi,int struct_type)@@ -76,6 +76,28 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, BD_PART_WRITTEN(sbi))); } +static ssize_t features_show(struct f2fs_attr *a,
fs/f2fs/sysfs.c static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, · line 89
Quoted 10 lines
fs/f2fs/sysfs.c +10
-0+ struct f2fs_sb_info *sbi, char *buf) +{ + struct super_block *sb = sbi->sb; +int len =0 ; + +if (!sb->s_bdev->bd_part) +return snprintf (buf,PAGE_SIZE ,"0\n" ); + +if (f2fs_sb_has_crypto (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,"encryption" );
How about printing as below:
len += snprintf(buf, PAGE_SIZE - len, "%s\n", "encryption ");
It avoids unneeded ',' in the beginning of output string:
cat /sys/fs/f2fs/zram0/features
, extra_attr, projquota, inode_checksum
fs/f2fs/sysfs.c static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, · line 91
Quoted 2 lines
fs/f2fs/sysfs.c +2
-0+if (f2fs_sb_mounted_blkzoned (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", blkzoned" );
len += snprintf(buf, PAGE_SIZE - len, "%s\n", "blkzoned ");
fs/f2fs/sysfs.c static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, · line 93
Quoted 2 lines
fs/f2fs/sysfs.c +2
-0+if (f2fs_sb_has_extra_attr (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", extra_attr" );
ditto
fs/f2fs/sysfs.c static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, · line 95
Quoted 2 lines
fs/f2fs/sysfs.c +2
-0+if (f2fs_sb_has_project_quota (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", projquota" );
ditto
fs/f2fs/sysfs.c static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, · line 97
Quoted 2 lines
fs/f2fs/sysfs.c +2
-0+if (f2fs_sb_has_inode_chksum (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s\n" ,", inode_checksum" );
ditto
Quoted 7 lines
fs/f2fs/sysfs.c +3
-0+return len; +} +static ssize_t f2fs_sbi_show (struct f2fs_attr *a,struct f2fs_sb_info *sbi,char *buf) {
fs/f2fs/sysfs.c static void f2fs_sb_release(struct kobject *kobj) · line 183
Quoted 7 lines
fs/f2fs/sysfs.c +4
-0@@ -155,6 +177,24 @@ static void f2fs_sb_release(struct kobject *kobj)complete (&sbi->s_kobj_unregister); } +enum feat_id { +FEAT_CRYPTO =0 , +FEAT_BLKZONED , +FEAT_ATOMIC_WRITE ,
Adds below missing macro:FEAT_EXTRA_ATTR,FEAT_PROJECT_QUOTA,FEAT_INODE_CHECKSUM,
fs/f2fs/sysfs.c static void f2fs_sb_release(struct kobject *kobj) · line 192
Quoted 9 lines
fs/f2fs/sysfs.c +9
-0+}; + +static ssize_t f2fs_feature_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +switch (a->id) { +case FEAT_CRYPTO : +case FEAT_BLKZONED : +case FEAT_ATOMIC_WRITE :
case FEAT_EXTRA_ATTR:
case FEAT_PROJECT_QUOTA:
case FEAT_INODE_CHECKSUM:
Quoted 25 lines
fs/f2fs/sysfs.c +12
-0+return snprintf (buf,PAGE_SIZE ,"supported\n" ); + } +return 0 ; +} +#define F2FS_ATTR_OFFSET (_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \@@ -172,6 +212,13 @@ static struct f2fs_attr f2fs_attr_##_name = { \#define F2FS_GENERAL_RO_ATTR (name) \ 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, \ +} +F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);@@ -196,6 +243,15 @@ F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);F2FS_RW_ATTR (FAULT_INFO_TYPE , f2fs_fault_info, inject_type, inject_type);#endif
fs/f2fs/sysfs.c F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); · line 254
Quoted 10 lines
fs/f2fs/sysfs.c +9
-0F2FS_GENERAL_RO_ATTR (lifetime_write_kbytes); +F2FS_GENERAL_RO_ATTR (features); + +#ifdef CONFIG_F2FS_FS_ENCRYPTION +F2FS_FEATURE_RO_ATTR (encryption,FEAT_CRYPTO ); +#endif +#ifdef CONFIG_BLK_DEV_ZONED +F2FS_FEATURE_RO_ATTR (block_zoned,FEAT_BLKZONED ); +#endif +F2FS_FEATURE_RO_ATTR (atomic_write,FEAT_ATOMIC_WRITE );
F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
Quoted 10 lines
fs/f2fs/sysfs.c +1
-0#define ATTR_LIST (name) (&f2fs_attr_##name.attr)static struct attribute *f2fs_attrs[] = {@@ -222,21 +278,50 @@ static struct attribute *f2fs_attrs[] = {ATTR_LIST (inject_type), #endifATTR_LIST (lifetime_write_kbytes), +ATTR_LIST (features),ATTR_LIST (reserved_blocks), NULL,
fs/f2fs/sysfs.c static struct attribute *f2fs_attrs[] = { · line 293
Quoted 10 lines
fs/f2fs/sysfs.c +8
-0}; +static struct attribute *f2fs_feat_attrs[] = { +#ifdef CONFIG_F2FS_FS_ENCRYPTION + ATTR_LIST(encryption), +#endif +#ifdef CONFIG_BLK_DEV_ZONED + ATTR_LIST(block_zoned), +#endif + ATTR_LIST(atomic_write),
ATTR_LIST(extra_attr),ATTR_LIST(project_quota),ATTR_LIST(inode_checksum),
Thanks,
Quoted 120 lines
fs/f2fs/sysfs.c +46
-25+ NULL, +}; +static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, }; -static struct kobj_type f2fs_ktype = { +static struct kobj_type f2fs_sb_ktype = { .default_attrs = f2fs_attrs, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; +static struct kobj_type f2fs_ktype = { + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, +}; + +static struct kobj_type f2fs_feat_ktype = { + .default_attrs = f2fs_feat_attrs, + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kobject f2fs_feat = { + .kset = &f2fs_kset, +}; +static int segment_info_seq_show (struct seq_file *seq,void *offset) {struct super_block *sb = seq->private;@@ -306,18 +391,29 @@ F2FS_PROC_FILE_DEF(segment_bits);int __init f2fs_init_sysfs (void ) { - f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +int ret; - f2fs_kset =kset_create_and_add ("f2fs" ,NULL , fs_kobj); -if (!f2fs_kset) -return -ENOMEM ; -return 0 ; +kobject_set_name (&f2fs_kset.kobj,"f2fs" ); + f2fs_kset.kobj.parent = fs_kobj; + ret =kset_register (&f2fs_kset); +if (ret) +return ret; + + ret =kobject_init_and_add (&f2fs_feat, &f2fs_feat_ktype, +NULL ,"features" ); +if (ret) +kset_unregister (&f2fs_kset); +else + f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +return ret; }void f2fs_exit_sysfs (void ) { -kset_unregister (f2fs_kset); +kobject_put (&f2fs_feat); +kset_unregister (&f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); + f2fs_proc_root =NULL ; }int f2fs_register_sysfs (struct f2fs_sb_info *sbi)@@ -325,6 +421,13 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)struct super_block *sb = sbi->sb;int err; + sbi->s_kobj.kset = &f2fs_kset; +init_completion (&sbi->s_kobj_unregister); + err =kobject_init_and_add (&sbi->s_kobj, &f2fs_sb_ktype,NULL , +"%s" , sb->s_id); +if (err) +return err; +if (f2fs_proc_root) sbi->s_proc =proc_mkdir (sb->s_id, f2fs_proc_root);@@ -334,32 +437,15 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)proc_create_data ("segment_bits" ,S_IRUGO , sbi->s_proc, &f2fs_seq_segment_bits_fops, sb); } - - sbi->s_kobj.kset = f2fs_kset; -init_completion (&sbi->s_kobj_unregister); - err =kobject_init_and_add (&sbi->s_kobj, &f2fs_ktype,NULL , -"%s" , sb->s_id); -if (err) - goto err_out;return 0 ; -err_out: -if (sbi->s_proc) { -remove_proc_entry ("segment_info" , sbi->s_proc); -remove_proc_entry ("segment_bits" , sbi->s_proc); -remove_proc_entry (sb->s_id, f2fs_proc_root); - } -return err; }void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi) { -kobject_del (&sbi->s_kobj); -kobject_put (&sbi->s_kobj); -wait_for_completion (&sbi->s_kobj_unregister); -if (sbi->s_proc) {remove_proc_entry ("segment_info" , sbi->s_proc);remove_proc_entry ("segment_bits" , sbi->s_proc);remove_proc_entry (sbi->sb->s_id, f2fs_proc_root); } +kobject_del (&sbi->s_kobj); }
Jaegeuk Kim
maintainer Change log from v2:
- add missing new features
- fix print out features
Change log from v1:
- add /sys/fs/f2fs/dev/features
Quoted 1 line
From
cf512bfeed89d760138ade12014f17fc5779ca04Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <[email protected]>
Date: Fri, 21 Jul 2017 17:14:09 -0700
Subject: [PATCH] f2fs: expose features to sysfs entry
This patch exposes what features are supported by current f2fs build to sysfs entry via:
/sys/fs/f2fs/features//sys/fs/f2fs/dev/features
--- fs/f2fs/sysfs.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 26 deletions(-)
fs/f2fs/sysfs.c +130 -26
@@ -18,7 +18,6 @@#include "gc.h" static struct proc_dir_entry *f2fs_proc_root; -static struct kset *f2fs_kset;/* Sysfs support for f2fs */ enum {
@@ -41,6 +40,7 @@ struct f2fs_attr { const char *, size_t);int struct_type;int offset; +int id; };static unsigned char *__struct_ptr (struct f2fs_sb_info *sbi,int struct_type)
@@ -76,6 +76,34 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, BD_PART_WRITTEN(sbi))); } +static ssize_t features_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +struct super_block *sb = sbi->sb; +int len =0 ; + +if (!sb->s_bdev->bd_part) +return snprintf (buf,PAGE_SIZE ,"0\n" ); + +if (f2fs_sb_has_crypto (sb)) + len +=snprintf (buf,PAGE_SIZE - len,"%s" , +"encryption" ); +if (f2fs_sb_mounted_blkzoned (sb)) + len +=snprintf (buf + len,PAGE_SIZE - len,"%s%s" , + len ?", " :"" ,"blkzoned" ); +if (f2fs_sb_has_extra_attr (sb)) + len +=snprintf (buf + len,PAGE_SIZE - len,"%s%s" , + len ?", " :"" ,"extra_attr" ); +if (f2fs_sb_has_project_quota (sb)) + len +=snprintf (buf + len,PAGE_SIZE - len,"%s%s" , + len ?", " :"" ,"projquota" ); +if (f2fs_sb_has_inode_chksum (sb)) + len +=snprintf (buf + len,PAGE_SIZE - len,"%s%s" , + len ?", " :"" ,"inode_checksum" ); + len +=snprintf (buf + len,PAGE_SIZE - len,"\n" ); +return len; +} +static ssize_t f2fs_sbi_show (struct f2fs_attr *a,struct f2fs_sb_info *sbi,char *buf) {
@@ -155,6 +183,30 @@ static void f2fs_sb_release(struct kobject *kobj)complete (&sbi->s_kobj_unregister); } +enum feat_id { +FEAT_CRYPTO =0 , +FEAT_BLKZONED , +FEAT_ATOMIC_WRITE , +FEAT_EXTRA_ATTR , +FEAT_PROJECT_QUOTA , +FEAT_INODE_CHECKSUM , +}; + +static ssize_t f2fs_feature_show (struct f2fs_attr *a, +struct f2fs_sb_info *sbi,char *buf) +{ +switch (a->id) { +case FEAT_CRYPTO : +case FEAT_BLKZONED : +case FEAT_ATOMIC_WRITE : +case FEAT_EXTRA_ATTR : +case FEAT_PROJECT_QUOTA : +case FEAT_INODE_CHECKSUM : +return snprintf (buf,PAGE_SIZE ,"supported\n" ); + } +return 0 ; +} +#define F2FS_ATTR_OFFSET (_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -172,6 +224,13 @@ static struct f2fs_attr f2fs_attr_##_name = { \#define F2FS_GENERAL_RO_ATTR (name) \ 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, \ +} +F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);F2FS_RW_ATTR (GC_THREAD , f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
@@ -197,6 +256,18 @@ F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);F2FS_RW_ATTR (FAULT_INFO_TYPE , f2fs_fault_info, inject_type, inject_type);#endif F2FS_GENERAL_RO_ATTR (lifetime_write_kbytes); +F2FS_GENERAL_RO_ATTR (features); + +#ifdef CONFIG_F2FS_FS_ENCRYPTION +F2FS_FEATURE_RO_ATTR (encryption,FEAT_CRYPTO ); +#endif +#ifdef CONFIG_BLK_DEV_ZONED +F2FS_FEATURE_RO_ATTR (block_zoned,FEAT_BLKZONED ); +#endif +F2FS_FEATURE_RO_ATTR (atomic_write,FEAT_ATOMIC_WRITE ); +F2FS_FEATURE_RO_ATTR (extra_attr,FEAT_EXTRA_ATTR ); +F2FS_FEATURE_RO_ATTR (project_quota,FEAT_PROJECT_QUOTA ); +F2FS_FEATURE_RO_ATTR (inode_checksum,FEAT_INODE_CHECKSUM );#define ATTR_LIST (name) (&f2fs_attr_##name.attr)static struct attribute *f2fs_attrs[] = {
@@ -224,21 +295,53 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(inject_type), #endif ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(features), ATTR_LIST(reserved_blocks), NULL, }; +static struct attribute *f2fs_feat_attrs[] = { +#ifdef CONFIG_F2FS_FS_ENCRYPTION + ATTR_LIST(encryption), +#endif +#ifdef CONFIG_BLK_DEV_ZONED + ATTR_LIST(block_zoned), +#endif + ATTR_LIST(atomic_write), + ATTR_LIST(extra_attr), + ATTR_LIST(project_quota), + ATTR_LIST(inode_checksum), + NULL, +}; + static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, }; -static struct kobj_type f2fs_ktype = { +static struct kobj_type f2fs_sb_ktype = { .default_attrs = f2fs_attrs, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; +static struct kobj_type f2fs_ktype = { + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, +}; + +static struct kobj_type f2fs_feat_ktype = { + .default_attrs = f2fs_feat_attrs, + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kobject f2fs_feat = { + .kset = &f2fs_kset, +}; + static int segment_info_seq_show(struct seq_file *seq, void *offset) { struct super_block *sb = seq->private;
@@ -308,18 +411,29 @@ F2FS_PROC_FILE_DEF(segment_bits);int __init f2fs_init_sysfs (void ) { - f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +int ret; - f2fs_kset =kset_create_and_add ("f2fs" ,NULL , fs_kobj); -if (!f2fs_kset) -return -ENOMEM ; -return 0 ; +kobject_set_name (&f2fs_kset.kobj,"f2fs" ); + f2fs_kset.kobj.parent = fs_kobj; + ret =kset_register (&f2fs_kset); +if (ret) +return ret; + + ret =kobject_init_and_add (&f2fs_feat, &f2fs_feat_ktype, +NULL ,"features" ); +if (ret) +kset_unregister (&f2fs_kset); +else + f2fs_proc_root =proc_mkdir ("fs/f2fs" ,NULL ); +return ret; }void f2fs_exit_sysfs (void ) { -kset_unregister (f2fs_kset); +kobject_put (&f2fs_feat); +kset_unregister (&f2fs_kset);remove_proc_entry ("fs/f2fs" ,NULL ); + f2fs_proc_root =NULL ; }int f2fs_register_sysfs (struct f2fs_sb_info *sbi)
@@ -327,6 +441,13 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)struct super_block *sb = sbi->sb;int err; + sbi->s_kobj.kset = &f2fs_kset; +init_completion (&sbi->s_kobj_unregister); + err =kobject_init_and_add (&sbi->s_kobj, &f2fs_sb_ktype,NULL , +"%s" , sb->s_id); +if (err) +return err; +if (f2fs_proc_root) sbi->s_proc =proc_mkdir (sb->s_id, f2fs_proc_root);
@@ -336,32 +457,15 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)proc_create_data ("segment_bits" ,S_IRUGO , sbi->s_proc, &f2fs_seq_segment_bits_fops, sb); } - - sbi->s_kobj.kset = f2fs_kset; -init_completion (&sbi->s_kobj_unregister); - err =kobject_init_and_add (&sbi->s_kobj, &f2fs_ktype,NULL , -"%s" , sb->s_id); -if (err) - goto err_out;return 0 ; -err_out: -if (sbi->s_proc) { -remove_proc_entry ("segment_info" , sbi->s_proc); -remove_proc_entry ("segment_bits" , sbi->s_proc); -remove_proc_entry (sb->s_id, f2fs_proc_root); - } -return err; }void f2fs_unregister_sysfs (struct f2fs_sb_info *sbi) { -kobject_del (&sbi->s_kobj); -kobject_put (&sbi->s_kobj); -wait_for_completion (&sbi->s_kobj_unregister); -if (sbi->s_proc) {remove_proc_entry ("segment_info" , sbi->s_proc);remove_proc_entry ("segment_bits" , sbi->s_proc);remove_proc_entry (sbi->sb->s_id, f2fs_proc_root); } +kobject_del (&sbi->s_kobj); }
Signature · 1 line
2.13.0.rc1.294.g07d810a77f-goog
Chao Yu
Reviewed-byQuoted 12 lines · Jaegeuk Kim
Change log from v2:
- add missing new features
- fix print out featuresChange log from v1:
- add/sys/fs/f2fs/dev/featuresQuoted 1 line
From
cf512bfeed89d760138ade12014f17fc5779ca04Mon Sep 17 00:00:00 2001From: Jaegeuk Kim <[email protected]>
Date: Fri, 21 Jul 2017 17:14:09 -0700
Subject: [PATCH] f2fs: expose features to sysfs entry
Quoted 7 lines
This patch exposes what features are supported by current f2fs build to sysfs entry via:
/sys/fs/f2fs/features//sys/fs/f2fs/dev/featuresSigned-off-by Jaegeuk Kim <[email protected]>
Thanks,