f2fs: show the list of donation files

This patch introduces a proc entry to show the currently enrolled donation
files.

- "File path" indicates a file.
- "Status"
 a. "Donated" means the file is registed in the donation list by
    fadvise(offset, length, POSIX_FADV_NOREUSE)
 b. "Evicted" means the donated pages were reclaimed.
- "Offset (kb)" and "Length (kb) show the registered donation range.
- "Cached pages (kb)" shows the amount of cached pages in the inode page cache.

For example,

 # of files  : 2
 File path                                              Status Donation offset (kb)   Donation size (kb)  File cached size (kb)
---
 /local/test2                                          Donated                    0              1048576                2097152
 /local/test                                           Evicted                    0              1048576                1048576

Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Jaegeuk Kim
2025-08-11 23:50:25 +00:00
parent ff11d8701b
commit f1a49c1b11

View File

@@ -1769,6 +1769,68 @@ static int __maybe_unused disk_map_seq_show(struct seq_file *seq,
return 0;
}
static int __maybe_unused donation_list_seq_show(struct seq_file *seq,
void *offset)
{
struct super_block *sb = seq->private;
struct f2fs_sb_info *sbi = F2FS_SB(sb);
struct inode *inode;
struct f2fs_inode_info *fi;
struct dentry *dentry;
char *buf, *path;
int i;
buf = f2fs_getname(sbi);
if (!buf)
return 0;
seq_printf(seq, "Donation List\n");
seq_printf(seq, " # of files : %u\n", sbi->donate_files);
seq_printf(seq, " %-50s %10s %20s %20s %22s\n",
"File path", "Status", "Donation offset (kb)",
"Donation size (kb)", "File cached size (kb)");
seq_printf(seq, "---\n");
for (i = 0; i < sbi->donate_files; i++) {
spin_lock(&sbi->inode_lock[DONATE_INODE]);
if (list_empty(&sbi->inode_list[DONATE_INODE])) {
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
break;
}
fi = list_first_entry(&sbi->inode_list[DONATE_INODE],
struct f2fs_inode_info, gdonate_list);
list_move_tail(&fi->gdonate_list, &sbi->inode_list[DONATE_INODE]);
inode = igrab(&fi->vfs_inode);
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
if (!inode)
continue;
inode_lock_shared(inode);
dentry = d_find_alias(inode);
if (!dentry) {
path = NULL;
} else {
path = dentry_path_raw(dentry, buf, PATH_MAX);
if (IS_ERR(path))
goto next;
}
seq_printf(seq, " %-50s %10s %20llu %20llu %22llu\n",
path ? path : "<unlinked>",
is_inode_flag_set(inode, FI_DONATE_FINISHED) ?
"Evicted" : "Donated",
(loff_t)fi->donate_start << (PAGE_SHIFT - 10),
(loff_t)(fi->donate_end + 1) << (PAGE_SHIFT - 10),
(loff_t)inode->i_mapping->nrpages << (PAGE_SHIFT - 10));
next:
inode_unlock_shared(inode);
iput(inode);
}
f2fs_putname(buf);
return 0;
}
#ifdef CONFIG_F2FS_FAULT_INJECTION
static int __maybe_unused inject_stats_seq_show(struct seq_file *seq,
void *offset)
@@ -1878,6 +1940,8 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
discard_plist_seq_show, sb);
proc_create_single_data("disk_map", 0444, sbi->s_proc,
disk_map_seq_show, sb);
proc_create_single_data("donation_list", 0444, sbi->s_proc,
donation_list_seq_show, sb);
#ifdef CONFIG_F2FS_FAULT_INJECTION
proc_create_single_data("inject_stats", 0444, sbi->s_proc,
inject_stats_seq_show, sb);