More patch description fixups. Standardize case.
[ext4-patch-queue.git] / ext4_add_block_bitmap_validation.patch
blob60cec424d6119c237639858d24e4b94360ca36ba
1 ext4: add block bitmap validation
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 When a new block bitmap is read from disk in read_block_bitmap()
6 there are a few bits that should ALWAYS be set. In particular,
7 the blocks given corresponding to block bitmap, inode bitmap and inode tables.
8 Validate the block bitmap against these blocks.
10 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
11 ---
13 fs/ext4/balloc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++----------
14 1 files changed, 81 insertions(+), 18 deletions(-)
17 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
18 index ff3428e..a9140ea 100644
19 --- a/fs/ext4/balloc.c
20 +++ b/fs/ext4/balloc.c
21 @@ -189,13 +189,65 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
22 return desc;
25 +static int ext4_valid_block_bitmap(struct super_block *sb,
26 + struct ext4_group_desc *desc,
27 + unsigned int block_group,
28 + struct buffer_head *bh)
30 + ext4_grpblk_t offset;
31 + ext4_grpblk_t next_zero_bit;
32 + ext4_fsblk_t bitmap_blk;
33 + ext4_fsblk_t group_first_block;
35 + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
36 + /* with FLEX_BG, the inode/block bitmaps and itable
37 + * blocks may not be in the group at all
38 + * so the bitmap validation will be skipped for those groups
39 + * or it has to also read the block group where the bitmaps
40 + * are located to verify they are set.
41 + */
42 + return 1;
43 + }
44 + group_first_block = ext4_group_first_block_no(sb, block_group);
46 + /* check whether block bitmap block number is set */
47 + bitmap_blk = ext4_block_bitmap(sb, desc);
48 + offset = bitmap_blk - group_first_block;
49 + if (!ext4_test_bit(offset, bh->b_data))
50 + /* bad block bitmap */
51 + goto err_out;
53 + /* check whether the inode bitmap block number is set */
54 + bitmap_blk = ext4_inode_bitmap(sb, desc);
55 + offset = bitmap_blk - group_first_block;
56 + if (!ext4_test_bit(offset, bh->b_data))
57 + /* bad block bitmap */
58 + goto err_out;
60 + /* check whether the inode table block number is set */
61 + bitmap_blk = ext4_inode_table(sb, desc);
62 + offset = bitmap_blk - group_first_block;
63 + next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
64 + offset + EXT4_SB(sb)->s_itb_per_group,
65 + offset);
66 + if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group)
67 + /* good bitmap for inode tables */
68 + return 1;
70 +err_out:
71 + ext4_error(sb, __FUNCTION__,
72 + "Invalid block bitmap - "
73 + "block_group = %d, block = %llu",
74 + block_group, bitmap_blk);
75 + return 0;
77 /**
78 * read_block_bitmap()
79 * @sb: super block
80 * @block_group: given block group
82 - * Read the bitmap for a given block_group, reading into the specified
83 - * slot in the superblock's bitmap cache.
84 + * Read the bitmap for a given block_group,and validate the
85 + * bits for block/inode/inode tables are set in the bitmaps
87 * Return buffer_head on success or NULL in case of failure.
89 @@ -210,25 +262,36 @@ read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
90 if (!desc)
91 return NULL;
92 bitmap_blk = ext4_block_bitmap(sb, desc);
93 + bh = sb_getblk(sb, bitmap_blk);
94 + if (unlikely(!bh)) {
95 + ext4_error(sb, __FUNCTION__,
96 + "Cannot read block bitmap - "
97 + "block_group = %d, block_bitmap = %llu",
98 + (int)block_group, (unsigned long long)bitmap_blk);
99 + return NULL;
101 + if (bh_uptodate_or_lock(bh))
102 + return bh;
104 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
105 - bh = sb_getblk(sb, bitmap_blk);
106 - if (!buffer_uptodate(bh)) {
107 - lock_buffer(bh);
108 - if (!buffer_uptodate(bh)) {
109 - ext4_init_block_bitmap(sb, bh, block_group,
110 - desc);
111 - set_buffer_uptodate(bh);
113 - unlock_buffer(bh);
115 - } else {
116 - bh = sb_bread(sb, bitmap_blk);
117 + ext4_init_block_bitmap(sb, bh, block_group, desc);
118 + set_buffer_uptodate(bh);
119 + unlock_buffer(bh);
120 + return bh;
122 - if (!bh)
123 - ext4_error (sb, __FUNCTION__,
124 + if (bh_submit_read(bh) < 0) {
125 + brelse(bh);
126 + ext4_error(sb, __FUNCTION__,
127 "Cannot read block bitmap - "
128 - "block_group = %lu, block_bitmap = %llu",
129 - block_group, bitmap_blk);
130 + "block_group = %d, block_bitmap = %llu",
131 + (int)block_group, (unsigned long long)bitmap_blk);
132 + return NULL;
134 + if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) {
135 + brelse(bh);
136 + return NULL;
139 return bh;