Skip to content

Commit b2044c3

Browse files
tytsogregkh
authored andcommitted
ext4: clean up error handling when orphan list is corrupted
commit 7827a7f upstream. Instead of just printing warning messages, if the orphan list is corrupted, declare the file system is corrupted. If there are any reserved inodes in the orphaned inode list, declare the file system corrupted and stop right away to avoid doing more potential damage to the file system. Signed-off-by: Theodore Ts'o <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c5ce389 commit b2044c3

File tree

1 file changed

+22
-27
lines changed

1 file changed

+22
-27
lines changed

fs/ext4/ialloc.c

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,25 +1143,20 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
11431143
unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
11441144
ext4_group_t block_group;
11451145
int bit;
1146-
struct buffer_head *bitmap_bh;
1146+
struct buffer_head *bitmap_bh = NULL;
11471147
struct inode *inode = NULL;
1148-
long err = -EIO;
1148+
int err = -EFSCORRUPTED;
11491149

1150-
/* Error cases - e2fsck has already cleaned up for us */
1151-
if (ino > max_ino) {
1152-
ext4_warning(sb, "bad orphan ino %lu! e2fsck was run?", ino);
1153-
err = -EFSCORRUPTED;
1154-
goto error;
1155-
}
1150+
if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
1151+
goto bad_orphan;
11561152

11571153
block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
11581154
bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
11591155
bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
11601156
if (IS_ERR(bitmap_bh)) {
1161-
err = PTR_ERR(bitmap_bh);
1162-
ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
1163-
ino, err);
1164-
goto error;
1157+
ext4_error(sb, "inode bitmap error %ld for orphan %lu",
1158+
ino, PTR_ERR(bitmap_bh));
1159+
return (struct inode *) bitmap_bh;
11651160
}
11661161

11671162
/* Having the inode bit set should be a 100% indicator that this
@@ -1172,8 +1167,12 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
11721167
goto bad_orphan;
11731168

11741169
inode = ext4_iget(sb, ino);
1175-
if (IS_ERR(inode))
1176-
goto iget_failed;
1170+
if (IS_ERR(inode)) {
1171+
err = PTR_ERR(inode);
1172+
ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
1173+
ino, err);
1174+
return inode;
1175+
}
11771176

11781177
/*
11791178
* If the orphans has i_nlinks > 0 then it should be able to
@@ -1190,29 +1189,25 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
11901189
brelse(bitmap_bh);
11911190
return inode;
11921191

1193-
iget_failed:
1194-
err = PTR_ERR(inode);
1195-
inode = NULL;
11961192
bad_orphan:
1197-
ext4_warning(sb, "bad orphan inode %lu! e2fsck was run?", ino);
1198-
printk(KERN_WARNING "ext4_test_bit(bit=%d, block=%llu) = %d\n",
1199-
bit, (unsigned long long)bitmap_bh->b_blocknr,
1200-
ext4_test_bit(bit, bitmap_bh->b_data));
1201-
printk(KERN_WARNING "inode=%p\n", inode);
1193+
ext4_error(sb, "bad orphan inode %lu", ino);
1194+
if (bitmap_bh)
1195+
printk(KERN_ERR "ext4_test_bit(bit=%d, block=%llu) = %d\n",
1196+
bit, (unsigned long long)bitmap_bh->b_blocknr,
1197+
ext4_test_bit(bit, bitmap_bh->b_data));
12021198
if (inode) {
1203-
printk(KERN_WARNING "is_bad_inode(inode)=%d\n",
1199+
printk(KERN_ERR "is_bad_inode(inode)=%d\n",
12041200
is_bad_inode(inode));
1205-
printk(KERN_WARNING "NEXT_ORPHAN(inode)=%u\n",
1201+
printk(KERN_ERR "NEXT_ORPHAN(inode)=%u\n",
12061202
NEXT_ORPHAN(inode));
1207-
printk(KERN_WARNING "max_ino=%lu\n", max_ino);
1208-
printk(KERN_WARNING "i_nlink=%u\n", inode->i_nlink);
1203+
printk(KERN_ERR "max_ino=%lu\n", max_ino);
1204+
printk(KERN_ERR "i_nlink=%u\n", inode->i_nlink);
12091205
/* Avoid freeing blocks if we got a bad deleted inode */
12101206
if (inode->i_nlink == 0)
12111207
inode->i_blocks = 0;
12121208
iput(inode);
12131209
}
12141210
brelse(bitmap_bh);
1215-
error:
12161211
return ERR_PTR(err);
12171212
}
12181213

0 commit comments

Comments
 (0)