Fix up patch comments for consistency
[ext4-patch-queue.git] / ext4_add_block_bitmap_validation.patch
blobc99cad09d22506b6df1b7c3539868fb5dadb9505
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 ---
12 fs/ext4/balloc.c | 97 ++++++++++++++++++++++++++++++++++++++++++++---------
13 1 files changed, 80 insertions(+), 17 deletions(-)
15 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
16 index ff3428e..3b9b07b 100644
17 --- a/fs/ext4/balloc.c
18 +++ b/fs/ext4/balloc.c
19 @@ -189,13 +189,65 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
20 return desc;
23 +static int ext4_valid_block_bitmap(struct super_block *sb,
24 + struct ext4_group_desc *desc,
25 + unsigned int block_group,
26 + struct buffer_head *bh)
28 + ext4_grpblk_t offset;
29 + ext4_grpblk_t next_zero_bit;
30 + ext4_fsblk_t bitmap_blk;
31 + ext4_fsblk_t group_first_block;
33 + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
34 + /* with FLEX_BG, the inode/block bitmaps and itable
35 + * blocks may not be in the group at all
36 + * so the bitmap validation will be skipped for those groups
37 + * or it has to also read the block group where the bitmaps
38 + * are located to verify they are set.
39 + */
40 + return 1;
41 + }
42 + group_first_block = ext4_group_first_block_no(sb, block_group);
44 + /* check whether block bitmap block number is set */
45 + bitmap_blk = ext4_block_bitmap(sb, desc);
46 + offset = bitmap_blk - group_first_block;
47 + if (!ext4_test_bit(offset, bh->b_data))
48 + /* bad block bitmap */
49 + goto err_out;
51 + /* check whether the inode bitmap block number is set */
52 + bitmap_blk = ext4_inode_bitmap(sb, desc);
53 + offset = bitmap_blk - group_first_block;
54 + if (!ext4_test_bit(offset, bh->b_data))
55 + /* bad block bitmap */
56 + goto err_out;
58 + /* check whether the inode table block number is set */
59 + bitmap_blk = ext4_inode_table(sb, desc);
60 + offset = bitmap_blk - group_first_block;
61 + next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
62 + offset + EXT4_SB(sb)->s_itb_per_group,
63 + offset);
64 + if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group)
65 + /* good bitmap for inode tables */
66 + return 1;
68 +err_out:
69 + ext4_error(sb, __FUNCTION__,
70 + "Invalid block bitmap - "
71 + "block_group = %d, block = %llu",
72 + block_group, bitmap_blk);
73 + return 0;
75 /**
76 * read_block_bitmap()
77 * @sb: super block
78 * @block_group: given block group
80 - * Read the bitmap for a given block_group, reading into the specified
81 - * slot in the superblock's bitmap cache.
82 + * Read the bitmap for a given block_group,and validate the
83 + * bits for block/inode/inode tables are set in the bitmaps
85 * Return buffer_head on success or NULL in case of failure.
87 @@ -210,25 +262,36 @@ read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
88 if (!desc)
89 return NULL;
90 bitmap_blk = ext4_block_bitmap(sb, desc);
91 + bh = sb_getblk(sb, bitmap_blk);
92 + if (unlikely(!bh)) {
93 + ext4_error(sb, __FUNCTION__,
94 + "Cannot read block bitmap - "
95 + "block_group = %d, block_bitmap = %llu",
96 + block_group, bitmap_blk);
97 + return NULL;
98 + }
99 + if (bh_uptodate_or_lock(bh))
100 + return bh;
102 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
103 - bh = sb_getblk(sb, bitmap_blk);
104 - if (!buffer_uptodate(bh)) {
105 - lock_buffer(bh);
106 - if (!buffer_uptodate(bh)) {
107 - ext4_init_block_bitmap(sb, bh, block_group,
108 - desc);
109 - set_buffer_uptodate(bh);
111 - unlock_buffer(bh);
113 - } else {
114 - bh = sb_bread(sb, bitmap_blk);
115 + ext4_init_block_bitmap(sb, bh, block_group, desc);
116 + set_buffer_uptodate(bh);
117 + unlock_buffer(bh);
118 + return bh;
120 - if (!bh)
121 - ext4_error (sb, __FUNCTION__,
122 + if (bh_submit_read(bh) < 0) {
123 + brelse(bh);
124 + ext4_error(sb, __FUNCTION__,
125 "Cannot read block bitmap - "
126 - "block_group = %lu, block_bitmap = %llu",
127 + "block_group = %d, block_bitmap = %llu",
128 block_group, bitmap_blk);
129 + return NULL;
131 + if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) {
132 + brelse(bh);
133 + return NULL;
136 return bh;
140 1.5.3.5.652.gf192c-dirty