[f2fs-dev] [PATCH 3/3] f2fs: dump read extent cache via sysfs for debugging
Yongpeng Yang <[email protected]> Sat, 15 Aug 2026 00:49:28 +0800
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Yongpeng Yang <[email protected]> Add a write-only per-sb sysfs entry "extent_cache_debug": writing a file descriptor resolves the inode in the writer's context, dumps the largest extent and every rbtree node (fofs/blk/len) to the kernel log via f2fs_info(). A matching f2fs_io "extent_cache" subcommand is added in f2fs-tools. Signed-off-by: Yongpeng Yang <[email protected]> --- fs/f2fs/extent_cache.c | 45 ++++++++++++++++++++++++++++++++++++++++++ fs/f2fs/f2fs.h | 1 + fs/f2fs/sysfs.c | 18 +++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index aaad72fa1553..d5d57bc642c8 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -13,6 +13,7 @@ */ #include <linux/fs.h> +#include <linux/file.h> #include <linux/f2fs_fs.h> #include "f2fs.h" @@ -1268,6 +1269,50 @@ static void __init_extent_tree_info(struct extent_tree_info *eti) atomic_set(&eti->total_ext_node, 0); } +/* Dump the read extent cache of the inode behind @fd to the kernel log. */ +int f2fs_dump_read_extent_cache(struct f2fs_sb_info *sbi, int fd) +{ + struct fd f = fdget(fd); + struct inode *inode; + struct extent_tree *et; + struct rb_node *node; + struct extent_node *en; + unsigned int count = 0; + int ret = 0; + + if (fd_empty(f)) + return -EBADF; + + inode = file_inode(fd_file(f)); + if (inode->i_sb != sbi->sb) { + fdput(f); + return -EINVAL; + } + + et = F2FS_I(inode)->extent_tree[EX_READ]; + if (!et) { + f2fs_info(sbi, "ino=%llu: read extent cache disabled", + (unsigned long long)inode->i_ino); + goto out; + } + + read_lock(&et->lock); + f2fs_info(sbi, "ino=%llu largest: fofs=%u blk=%u len=%u node_count=%u", + (unsigned long long)inode->i_ino, et->largest.fofs, + et->largest.blk, et->largest.len, + atomic_read(&et->node_cnt)); + for (node = rb_first_cached(&et->root); node; node = rb_next(node)) { + en = rb_entry(node, struct extent_node, rb_node); + f2fs_info(sbi, " [%u] fofs=%u blk=%u len=%u", + count, en->ei.fofs, en->ei.blk, en->ei.len); + count++; + } + read_unlock(&et->lock); +out: + fdput(f); + return ret; +} + void f2fs_init_extent_cache_info(struct f2fs_sb_info *sbi) { __init_extent_tree_info(&sbi->extent_tree[EX_READ]); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1b96d8718c5c..be2bd6e2a2bd 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4648,6 +4648,7 @@ void f2fs_update_read_extent_cache_range(struct dnode_of_data *dn, pgoff_t fofs, block_t blkaddr, unsigned int len); unsigned int f2fs_shrink_read_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink); +int f2fs_dump_read_extent_cache(struct f2fs_sb_info *sbi, int fd); /* block age extent cache ops */ void f2fs_init_age_extent_tree(struct inode *inode); diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 3201e2185fea..046d68962d18 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -1368,6 +1368,23 @@ F2FS_GENERAL_RO_ATTR(avg_vblocks); F2FS_GENERAL_RO_ATTR(defrag_blocks); #endif +static ssize_t extent_cache_debug_store(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, const char *buf, size_t count) +{ + int fd, ret; + + ret = kstrtoint(buf, 0, &fd); + if (ret < 0) + return ret; + ret = f2fs_dump_read_extent_cache(sbi, fd); + if (ret < 0) + return ret; + return count; +} + +static struct f2fs_attr f2fs_attr_extent_cache_debug = __ATTR( + extent_cache_debug, 0200, NULL, extent_cache_debug_store); + #ifdef CONFIG_FS_ENCRYPTION F2FS_FEATURE_RO_ATTR(encryption); F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2); @@ -1491,6 +1508,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(avg_vblocks), ATTR_LIST(defrag_blocks), #endif + ATTR_LIST(extent_cache_debug), #ifdef CONFIG_BLK_DEV_ZONED ATTR_LIST(unusable_blocks_per_sec), ATTR_LIST(max_open_zones), -- 2.43.0 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel