fix orphan list handling problem
[ext4-patch-queue.git] / clean-up-error-handling-for-orphan-list-problems
blob35e56d7ba7d256eb2143853d999c8121b24654b2
1 ext4: clean up error handling when orphan list is corrupted
3 Instead of just printing warning messages, if the orphan list is
4 corrupted, declare the file system is corrupted.  If there are any
5 reserved inodes in the orphaned inode list, declare the file system
6 corrupted and stop right away to avoid doing more potential damage to
7 the file system.
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  fs/ext4/ialloc.c | 49 ++++++++++++++++++++++---------------------------
12  1 file changed, 22 insertions(+), 27 deletions(-)
14 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
15 index c2caf2d..3da4cf8 100644
16 --- a/fs/ext4/ialloc.c
17 +++ b/fs/ext4/ialloc.c
18 @@ -1150,25 +1150,20 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
19         unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
20         ext4_group_t block_group;
21         int bit;
22 -       struct buffer_head *bitmap_bh;
23 +       struct buffer_head *bitmap_bh = NULL;
24         struct inode *inode = NULL;
25 -       long err = -EIO;
26 +       int err = -EFSCORRUPTED;
28 -       /* Error cases - e2fsck has already cleaned up for us */
29 -       if (ino > max_ino) {
30 -               ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
31 -               err = -EFSCORRUPTED;
32 -               goto error;
33 -       }
34 +       if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
35 +               goto bad_orphan;
37         block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
38         bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
39         bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
40         if (IS_ERR(bitmap_bh)) {
41 -               err = PTR_ERR(bitmap_bh);
42 -               ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
43 -                            ino, err);
44 -               goto error;
45 +               ext4_error(sb, "inode bitmap error %ld for orphan %lu",
46 +                          ino, PTR_ERR(bitmap_bh));
47 +               return (struct inode *) bitmap_bh;
48         }
50         /* Having the inode bit set should be a 100% indicator that this
51 @@ -1179,8 +1174,12 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
52                 goto bad_orphan;
54         inode = ext4_iget(sb, ino);
55 -       if (IS_ERR(inode))
56 -               goto iget_failed;
57 +       if (IS_ERR(inode)) {
58 +               err = PTR_ERR(inode);
59 +               ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
60 +                          ino, err);
61 +               return inode;
62 +       }
64         /*
65          * If the orphans has i_nlinks > 0 then it should be able to
66 @@ -1197,29 +1196,25 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
67         brelse(bitmap_bh);
68         return inode;
70 -iget_failed:
71 -       err = PTR_ERR(inode);
72 -       inode = NULL;
73  bad_orphan:
74 -       ext4_warning(sb, "bad orphan inode %lu!  e2fsck was run?", ino);
75 -       printk(KERN_WARNING "ext4_test_bit(bit=%d, block=%llu) = %d\n",
76 -              bit, (unsigned long long)bitmap_bh->b_blocknr,
77 -              ext4_test_bit(bit, bitmap_bh->b_data));
78 -       printk(KERN_WARNING "inode=%p\n", inode);
79 +       ext4_error(sb, "bad orphan inode %lu", ino);
80 +       if (bitmap_bh)
81 +               printk(KERN_ERR "ext4_test_bit(bit=%d, block=%llu) = %d\n",
82 +                      bit, (unsigned long long)bitmap_bh->b_blocknr,
83 +                      ext4_test_bit(bit, bitmap_bh->b_data));
84         if (inode) {
85 -               printk(KERN_WARNING "is_bad_inode(inode)=%d\n",
86 +               printk(KERN_ERR "is_bad_inode(inode)=%d\n",
87                        is_bad_inode(inode));
88 -               printk(KERN_WARNING "NEXT_ORPHAN(inode)=%u\n",
89 +               printk(KERN_ERR "NEXT_ORPHAN(inode)=%u\n",
90                        NEXT_ORPHAN(inode));
91 -               printk(KERN_WARNING "max_ino=%lu\n", max_ino);
92 -               printk(KERN_WARNING "i_nlink=%u\n", inode->i_nlink);
93 +               printk(KERN_ERR "max_ino=%lu\n", max_ino);
94 +               printk(KERN_ERR "i_nlink=%u\n", inode->i_nlink);
95                 /* Avoid freeing blocks if we got a bad deleted inode */
96                 if (inode->i_nlink == 0)
97                         inode->i_blocks = 0;
98                 iput(inode);
99         }
100         brelse(bitmap_bh);
101 -error:
102         return ERR_PTR(err);