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

Reply via email to