f2fs: introduce a new per-sb directory in sysfs
Add a new directory 'stat' in path of /sys/fs/f2fs/<devname>/, later we can add new readonly stat sysfs file into this directory, it will make <devname> directory less mess. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
3fde13f817
commit
5d4daa579e
@ -1545,9 +1545,12 @@ struct f2fs_sb_info {
|
|||||||
unsigned int node_io_flag;
|
unsigned int node_io_flag;
|
||||||
|
|
||||||
/* For sysfs suppport */
|
/* For sysfs suppport */
|
||||||
struct kobject s_kobj;
|
struct kobject s_kobj; /* /sys/fs/f2fs/<devname> */
|
||||||
struct completion s_kobj_unregister;
|
struct completion s_kobj_unregister;
|
||||||
|
|
||||||
|
struct kobject s_stat_kobj; /* /sys/fs/f2fs/<devname>/stat */
|
||||||
|
struct completion s_stat_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 */
|
||||||
|
@ -702,6 +702,11 @@ static struct attribute *f2fs_feat_attrs[] = {
|
|||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(f2fs_feat);
|
ATTRIBUTE_GROUPS(f2fs_feat);
|
||||||
|
|
||||||
|
static struct attribute *f2fs_stat_attrs[] = {
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
ATTRIBUTE_GROUPS(f2fs_stat);
|
||||||
|
|
||||||
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,
|
||||||
@ -730,6 +735,44 @@ static struct kobject f2fs_feat = {
|
|||||||
.kset = &f2fs_kset,
|
.kset = &f2fs_kset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
|
||||||
|
struct attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
|
||||||
|
s_stat_kobj);
|
||||||
|
struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
|
||||||
|
|
||||||
|
return a->show ? a->show(a, sbi, buf) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t f2fs_stat_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||||
|
const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
|
||||||
|
s_stat_kobj);
|
||||||
|
struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
|
||||||
|
|
||||||
|
return a->store ? a->store(a, sbi, buf, len) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f2fs_stat_kobj_release(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
|
||||||
|
s_stat_kobj);
|
||||||
|
complete(&sbi->s_stat_kobj_unregister);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sysfs_ops f2fs_stat_attr_ops = {
|
||||||
|
.show = f2fs_stat_attr_show,
|
||||||
|
.store = f2fs_stat_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct kobj_type f2fs_stat_ktype = {
|
||||||
|
.default_groups = f2fs_stat_groups,
|
||||||
|
.sysfs_ops = &f2fs_stat_attr_ops,
|
||||||
|
.release = f2fs_stat_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)
|
||||||
{
|
{
|
||||||
@ -936,11 +979,15 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
|
|||||||
init_completion(&sbi->s_kobj_unregister);
|
init_completion(&sbi->s_kobj_unregister);
|
||||||
err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
|
err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
|
||||||
"%s", sb->s_id);
|
"%s", sb->s_id);
|
||||||
if (err) {
|
if (err)
|
||||||
kobject_put(&sbi->s_kobj);
|
goto put_sb_kobj;
|
||||||
wait_for_completion(&sbi->s_kobj_unregister);
|
|
||||||
return err;
|
sbi->s_stat_kobj.kset = &f2fs_kset;
|
||||||
}
|
init_completion(&sbi->s_stat_kobj_unregister);
|
||||||
|
err = kobject_init_and_add(&sbi->s_stat_kobj, &f2fs_stat_ktype,
|
||||||
|
&sbi->s_kobj, "stat");
|
||||||
|
if (err)
|
||||||
|
goto put_stat_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);
|
||||||
@ -956,6 +1003,13 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
|
|||||||
victim_bits_seq_show, sb);
|
victim_bits_seq_show, sb);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
put_stat_kobj:
|
||||||
|
kobject_put(&sbi->s_stat_kobj);
|
||||||
|
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
||||||
|
put_sb_kobj:
|
||||||
|
kobject_put(&sbi->s_kobj);
|
||||||
|
wait_for_completion(&sbi->s_kobj_unregister);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
|
void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
|
||||||
@ -967,6 +1021,11 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
|
|||||||
remove_proc_entry("victim_bits", sbi->s_proc);
|
remove_proc_entry("victim_bits", sbi->s_proc);
|
||||||
remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
|
remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kobject_del(&sbi->s_stat_kobj);
|
||||||
|
kobject_put(&sbi->s_stat_kobj);
|
||||||
|
wait_for_completion(&sbi->s_stat_kobj_unregister);
|
||||||
|
|
||||||
kobject_del(&sbi->s_kobj);
|
kobject_del(&sbi->s_kobj);
|
||||||
kobject_put(&sbi->s_kobj);
|
kobject_put(&sbi->s_kobj);
|
||||||
wait_for_completion(&sbi->s_kobj_unregister);
|
wait_for_completion(&sbi->s_kobj_unregister);
|
||||||
|
Loading…
Reference in New Issue
Block a user