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