[f2fs-dev] [RFC PATCH v2 4/5] f2fs: add sysfs interface for inline extent management

Yongpeng Yang <[email protected]>
Newsgroups net.sourceforge.lists.linux-f2fs-devel
Message-ID <[email protected]>
From: Yongpeng Yang <[email protected]>

Add sysfs attributes to manage the inline extent feature at runtime:

- inline_extent_extension_list: read/write interface to manage file
  extension list that determines which files should use inline extent
  format. Writing an extension name adds it to the list; writing
  "!extension" removes it.

- inline_extent_enable: toggle to dynamically enable or disable the
  inline extent feature without remounting.

Also add inline extent code coverage statistics output under
/sys/kernel/debug/f2fs/ when CONFIG_F2FS_INLINE_EXTENT_DEBUG is
enabled, showing counters for various extent operations (merges,
splits, inserts, evictions, etc.).

Signed-off-by: Yongpeng Yang <[email protected]>
---
 fs/f2fs/debug.c   |  4 ++++
 fs/f2fs/iextent.c | 39 +++++++++++++++++++++++++++++++++++
 fs/f2fs/iextent.h |  3 +++
 fs/f2fs/sysfs.c   | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+)

diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index af88db8fdb71..b77246b6dbfc 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -19,6 +19,7 @@
 #include "node.h"
 #include "segment.h"
 #include "gc.h"
+#include "iextent.h"
 
 static LIST_HEAD(f2fs_stat_list);
 static DEFINE_SPINLOCK(f2fs_stat_lock);
@@ -762,6 +763,9 @@ static int stat_show(struct seq_file *s, void *v)
 				si->ext_mem[EX_BLOCK_AGE] >> 10);
 		seq_printf(s, "  - paged : %llu KB\n",
 				si->page_mem >> 10);
+#ifdef CONFIG_F2FS_INLINE_EXTENT_DEBUG
+		f2fs_iext_show_stat(sbi, s);
+#endif
 	}
 	spin_unlock(&f2fs_stat_lock);
 	return 0;
diff --git a/fs/f2fs/iextent.c b/fs/f2fs/iextent.c
index d919448ef740..63a3433aa9bc 100644
--- a/fs/f2fs/iextent.c
+++ b/fs/f2fs/iextent.c
@@ -821,3 +821,42 @@ int f2fs_iext_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
 	spin_unlock_irqrestore(&iext_info->iext_ext_lock, flag);
 	return ret;
 }
+
+#ifdef CONFIG_F2FS_INLINE_EXTENT_DEBUG
+void f2fs_iext_show_stat(struct f2fs_sb_info *sbi, struct seq_file *s)
+{
+	struct f2fs_iext_info *iext_info = sbi->iext_info;
+
+	seq_printf(s, "Inline extent code coverage statistics:\n"
+		"  - left_merge_count: %llu\n"
+		"  - right_merge_count: %llu\n"
+		"  - fast_right_merge_count: %llu\n"
+		"  - lr_merge_count: %llu\n"
+		"  - split_left_count: %llu\n"
+		"  - split_right_count: %llu\n"
+		"  - split_mid_count: %llu\n"
+		"  - insert_new_ext_count: %llu\n"
+		"  - overwrite_ext_count: %llu\n"
+		"  - add_ext_count: %llu\n"
+		"  - del_ext_count: %llu\n"
+		"  - evict_last_ext_cnt: %llu\n"
+		"  - truncate_last_ext_cnt: %llu\n"
+		"  - drop_insert_new_ext_cnt: %llu\n"
+		"  - trigger_ext_format_convert: %llu\n",
+		atomic64_read(&iext_info->left_merge_count),
+		atomic64_read(&iext_info->right_merge_count),
+		atomic64_read(&iext_info->fast_right_merge_count),
+		atomic64_read(&iext_info->lr_merge_count),
+		atomic64_read(&iext_info->split_left_count),
+		atomic64_read(&iext_info->split_right_count),
+		atomic64_read(&iext_info->split_mid_count),
+		atomic64_read(&iext_info->insert_new_ext_count),
+		atomic64_read(&iext_info->overwrite_ext_count),
+		atomic64_read(&iext_info->add_ext_count),
+		atomic64_read(&iext_info->del_ext_count),
+		atomic64_read(&iext_info->evict_last_ext_cnt),
+		atomic64_read(&iext_info->truncate_last_ext_cnt),
+		atomic64_read(&iext_info->drop_insert_new_ext_cnt),
+		atomic64_read(&iext_info->trigger_ext_format_convert));
+}
+#endif
diff --git a/fs/f2fs/iextent.h b/fs/f2fs/iextent.h
index e5fb028612ad..785eed312bf1 100644
--- a/fs/f2fs/iextent.h
+++ b/fs/f2fs/iextent.h
@@ -181,4 +181,7 @@ int f2fs_iext_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
 					bool set);
 int f2fs_iext_info_init(struct f2fs_sb_info *sbi);
 void f2fs_iext_info_destroy(struct f2fs_sb_info *sbi);
+#ifdef CONFIG_F2FS_INLINE_EXTENT_DEBUG
+void f2fs_iext_show_stat(struct f2fs_sb_info *sbi, struct seq_file *s);
+#endif
 #endif
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 665687244c93..c3a35e033df3 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -18,6 +18,7 @@
 #include "segment.h"
 #include "gc.h"
 #include "iostat.h"
+#include "iextent.h"
 #include <trace/events/f2fs.h>
 
 static struct proc_dir_entry *f2fs_proc_root;
@@ -40,6 +41,9 @@ enum {
 	RESERVED_BLOCKS,	/* struct f2fs_sb_info */
 	CPRC_INFO,	/* struct ckpt_req_control */
 	ATGC_INFO,	/* struct atgc_management */
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+	INLINE_EXTENT,		/* struct f2fs_iext_info */
+#endif
 };
 
 static const char *gc_mode_names[MAX_GC_MODE] = {
@@ -98,6 +102,10 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
 		return (unsigned char *)&sbi->cprc_info;
 	else if (struct_type == ATGC_INFO)
 		return (unsigned char *)&sbi->am;
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+	else if (struct_type == INLINE_EXTENT)
+		return (unsigned char *)sbi->iext_info;
+#endif
 	return NULL;
 }
 
@@ -405,6 +413,22 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
 		return len;
 	}
 
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+	if (!strcmp(a->attr.name, "inline_extent_extension_list")) {
+		struct f2fs_iext_info *iext_info = sbi->iext_info;
+		__u8 (*extlist)[F2FS_EXTENSION_LEN] = iext_info->extensions;
+		int len = 0, i;
+		unsigned long flag;
+
+		spin_lock_irqsave(&iext_info->iext_ext_lock, flag);
+		for (i = 0; i < iext_info->iext_ext_cnt; i++)
+			len += sysfs_emit_at(buf, len, "%s\n", extlist[i]);
+		spin_unlock_irqrestore(&iext_info->iext_ext_lock, flag);
+
+		return len;
+	}
+#endif
+
 	if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
 		struct ckpt_req_control *cprc = &sbi->cprc_info;
 		int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio);
@@ -535,6 +559,25 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
 		return ret ? ret : count;
 	}
 
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+	if (!strcmp(a->attr.name, "inline_extent_extension_list")) {
+		const char *name = strim((char *)buf);
+		bool set = true;
+
+		if (*name == '!') {
+			name++;
+			set = false;
+		}
+
+		if (!strlen(name) || strlen(name) >= F2FS_EXTENSION_LEN)
+			return -EINVAL;
+
+		ret = f2fs_iext_update_extension_list(sbi, name, set);
+
+		return ret ? ret : count;
+	}
+#endif
+
 	if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
 		const char *name = strim((char *)buf);
 		struct ckpt_req_control *cprc = &sbi->cprc_info;
@@ -1257,6 +1300,11 @@ NM_INFO_GENERAL_RW_ATTR(dirty_nats_ratio);
 
 /* F2FS_SBI ATTR */
 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+F2FS_RW_ATTR(INLINE_EXTENT, f2fs_iext_info, inline_extent_extension_list,
+			extensions);
+F2FS_RW_ATTR(INLINE_EXTENT, f2fs_iext_info, inline_extent_enable, iext_enable);
+#endif
 F2FS_SBI_RW_ATTR(gc_idle, gc_mode);
 F2FS_SBI_RW_ATTR(gc_urgent, gc_mode);
 F2FS_SBI_RW_ATTR(cp_interval, interval_time[CP_TIME]);
@@ -1457,6 +1505,10 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(max_io_bytes),
 	ATTR_LIST(gc_pin_file_thresh),
 	ATTR_LIST(extension_list),
+#ifdef CONFIG_F2FS_INLINE_EXTENT
+	ATTR_LIST(inline_extent_extension_list),
+	ATTR_LIST(inline_extent_enable),
+#endif
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 	ATTR_LIST(inject_rate),
 	ATTR_LIST(inject_type),
-- 
2.43.0



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.