Add cc: stable@vger.kernel.org tags
[ext4-patch-queue.git] / delalloc-debug
blobb32c4fd2918dc61eb7e60975e7691f8e9ba82563
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>
8 ---
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
14 --- a/fs/ext4/super.c
15 +++ b/fs/ext4/super.c
16 @@ -790,6 +790,9 @@ static void ext4_put_super(struct super_block *sb)
18         if (sbi->s_proc) {
19                 remove_proc_entry("options", sbi->s_proc);
20 +#ifdef CONFIG_EXT4_DEBUG
21 +               remove_proc_entry("delalloc_debug", sbi->s_proc);
22 +#endif
23                 remove_proc_entry(sb->s_id, ext4_proc_root);
24         }
25         kobject_del(&sbi->s_kobj);
26 @@ -1832,6 +1835,74 @@ static const struct file_operations ext4_seq_options_fops = {
27         .release = single_release,
28  };
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)
35 +               return;
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)
44 +       return 0;
47 +static int options_delalloc_debug_open_fs(struct inode *proc_inode,
48 +                                         struct file *file)
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));
60 +#ifndef MODULE
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,
65 +                                   i_wb_list) {
66 +                       print_inode_delalloc_info(inode);
67 +               }
68 +       }
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,
72 +                                   i_wb_list) {
73 +                       print_inode_delalloc_info(inode);
74 +               }
75 +       }
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,
79 +                                   i_wb_list) {
80 +                       print_inode_delalloc_info(inode);
81 +               }
82 +       }
83 +       spin_unlock(&inode_sb_list_lock);
84 +       printk(KERN_DEBUG "ext4 debug delalloc done\n");
85 +#endif
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,
92 +       .read = seq_read,
93 +       .llseek = seq_lseek,
94 +       .release = single_release,
95 +};
96 +#endif
98  static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
99                             int read_only)
101 @@ -3764,9 +3835,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
102         if (ext4_proc_root)
103                 sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
105 -       if (sbi->s_proc)
106 +       if (sbi->s_proc) {
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);
112 +#endif
113 +       }
115         bgl_lock_init(sbi->s_blockgroup_lock);
117 @@ -4149,6 +4225,9 @@ failed_mount:
118                 crypto_free_shash(sbi->s_chksum_driver);
119         if (sbi->s_proc) {
120                 remove_proc_entry("options", sbi->s_proc);
121 +#ifdef CONFIG_EXT4_DEBUG
122 +               remove_proc_entry("delalloc_debug", sbi->s_proc);
123 +#endif
124                 remove_proc_entry(sb->s_id, ext4_proc_root);
125         }
126  #ifdef CONFIG_QUOTA