1 ext4: add delalloc debugging
3 This adds a file in /proc/fs/ext4/<dev> which when opened for reading,
4 will trigger debugging code that dumps a lot of information about
5 inodes subject to delayed allocation to the console.
7 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
9 fs/ext4/super.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
10 1 file changed, 80 insertions(+), 1 deletion(-)
12 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
13 index 85b3dd6..ae13cd3 100644
16 @@ -790,6 +790,9 @@ static void ext4_put_super(struct super_block *sb)
19 remove_proc_entry("options", sbi->s_proc);
20 +#ifdef CONFIG_EXT4_DEBUG
21 + remove_proc_entry("delalloc_debug", sbi->s_proc);
23 remove_proc_entry(sb->s_id, ext4_proc_root);
25 kobject_del(&sbi->s_kobj);
26 @@ -1832,6 +1835,74 @@ static const struct file_operations ext4_seq_options_fops = {
27 .release = single_release,
30 +#ifdef CONFIG_EXT4_DEBUG
31 +static void print_inode_delalloc_info(struct inode *inode)
33 + if (!EXT4_I(inode)->i_reserved_data_blocks ||
34 + !EXT4_I(inode)->i_reserved_meta_blocks)
37 + printk(KERN_DEBUG "ino %lu: %u %u\n", inode->i_ino,
38 + EXT4_I(inode)->i_reserved_data_blocks,
39 + EXT4_I(inode)->i_reserved_meta_blocks);
42 +static int debug_delalloc_show(struct seq_file *seq, void *offset)
47 +static int options_delalloc_debug_open_fs(struct inode *proc_inode,
50 + struct super_block *sb = PDE_DATA(proc_inode);
51 + struct ext4_sb_info *sbi = EXT4_SB(sb);
52 + struct inode *inode;
53 + extern spinlock_t inode_sb_list_lock;
55 + printk(KERN_DEBUG "EXT4-fs debug delalloc of %s\n", sb->s_id);
56 + printk(KERN_DEBUG "EXT4-fs: dirty clusters %lld free clusters %lld\n",
57 + percpu_counter_sum(&sbi->s_dirtyclusters_counter),
58 + percpu_counter_sum(&sbi->s_freeclusters_counter));
61 + spin_lock(&inode_sb_list_lock);
62 + if (!list_empty(&sb->s_bdi->wb.b_dirty)) {
63 + printk(KERN_DEBUG "s_bdi->wb.b_dirty list:\n");
64 + list_for_each_entry(inode, &sb->s_bdi->wb.b_dirty,
66 + print_inode_delalloc_info(inode);
69 + if (!list_empty(&sb->s_bdi->wb.b_io)) {
70 + printk(KERN_DEBUG "s_bdi->wb.b_io list:\n");
71 + list_for_each_entry(inode, &sb->s_bdi->wb.b_io,
73 + print_inode_delalloc_info(inode);
76 + if (!list_empty(&sb->s_bdi->wb.b_more_io)) {
77 + printk(KERN_DEBUG "s_bdi->wb.b_more_io list:\n");
78 + list_for_each_entry(inode, &sb->s_bdi->wb.b_more_io,
80 + print_inode_delalloc_info(inode);
83 + spin_unlock(&inode_sb_list_lock);
84 + printk(KERN_DEBUG "ext4 debug delalloc done\n");
86 + return single_open(file, debug_delalloc_show, sb);
89 +static const struct file_operations ext4_seq_delalloc_debug_fops = {
90 + .owner = THIS_MODULE,
91 + .open = options_delalloc_debug_open_fs,
93 + .llseek = seq_lseek,
94 + .release = single_release,
98 static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
101 @@ -3764,9 +3835,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
103 sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
107 proc_create_data("options", S_IRUGO, sbi->s_proc,
108 &ext4_seq_options_fops, sb);
109 +#ifdef CONFIG_EXT4_DEBUG
110 + proc_create_data("delalloc_debug", S_IRUSR, sbi->s_proc,
111 + &ext4_seq_delalloc_debug_fops, sb);
115 bgl_lock_init(sbi->s_blockgroup_lock);
117 @@ -4149,6 +4225,9 @@ failed_mount:
118 crypto_free_shash(sbi->s_chksum_driver);
120 remove_proc_entry("options", sbi->s_proc);
121 +#ifdef CONFIG_EXT4_DEBUG
122 + remove_proc_entry("delalloc_debug", sbi->s_proc);
124 remove_proc_entry(sb->s_id, ext4_proc_root);