diff options
| -rw-r--r-- | fs/ext3/balloc.c | 78 |
1 files changed, 70 insertions, 8 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index a8ba7e831278..a26e683780be 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
| @@ -80,13 +80,57 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, | |||
| 80 | return desc + offset; | 80 | return desc + offset; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static int ext3_valid_block_bitmap(struct super_block *sb, | ||
| 84 | struct ext3_group_desc *desc, | ||
| 85 | unsigned int block_group, | ||
| 86 | struct buffer_head *bh) | ||
| 87 | { | ||
| 88 | ext3_grpblk_t offset; | ||
| 89 | ext3_grpblk_t next_zero_bit; | ||
| 90 | ext3_fsblk_t bitmap_blk; | ||
| 91 | ext3_fsblk_t group_first_block; | ||
| 92 | |||
| 93 | group_first_block = ext3_group_first_block_no(sb, block_group); | ||
| 94 | |||
| 95 | /* check whether block bitmap block number is set */ | ||
| 96 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | ||
| 97 | offset = bitmap_blk - group_first_block; | ||
| 98 | if (!ext3_test_bit(offset, bh->b_data)) | ||
| 99 | /* bad block bitmap */ | ||
| 100 | goto err_out; | ||
| 101 | |||
| 102 | /* check whether the inode bitmap block number is set */ | ||
| 103 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
| 104 | offset = bitmap_blk - group_first_block; | ||
| 105 | if (!ext3_test_bit(offset, bh->b_data)) | ||
| 106 | /* bad block bitmap */ | ||
| 107 | goto err_out; | ||
| 108 | |||
| 109 | /* check whether the inode table block number is set */ | ||
| 110 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
| 111 | offset = bitmap_blk - group_first_block; | ||
| 112 | next_zero_bit = ext3_find_next_zero_bit(bh->b_data, | ||
| 113 | offset + EXT3_SB(sb)->s_itb_per_group, | ||
| 114 | offset); | ||
| 115 | if (next_zero_bit >= offset + EXT3_SB(sb)->s_itb_per_group) | ||
| 116 | /* good bitmap for inode tables */ | ||
| 117 | return 1; | ||
| 118 | |||
| 119 | err_out: | ||
| 120 | ext3_error(sb, __FUNCTION__, | ||
| 121 | "Invalid block bitmap - " | ||
| 122 | "block_group = %d, block = %lu", | ||
| 123 | block_group, bitmap_blk); | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 83 | /** | 127 | /** |
| 84 | * read_block_bitmap() | 128 | * read_block_bitmap() |
| 85 | * @sb: super block | 129 | * @sb: super block |
| 86 | * @block_group: given block group | 130 | * @block_group: given block group |
| 87 | * | 131 | * |
| 88 | * Read the bitmap for a given block_group, reading into the specified | 132 | * Read the bitmap for a given block_group,and validate the |
| 89 | * slot in the superblock's bitmap cache. | 133 | * bits for block/inode/inode tables are set in the bitmaps |
| 90 | * | 134 | * |
| 91 | * Return buffer_head on success or NULL in case of failure. | 135 | * Return buffer_head on success or NULL in case of failure. |
| 92 | */ | 136 | */ |
| @@ -95,17 +139,35 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
| 95 | { | 139 | { |
| 96 | struct ext3_group_desc * desc; | 140 | struct ext3_group_desc * desc; |
| 97 | struct buffer_head * bh = NULL; | 141 | struct buffer_head * bh = NULL; |
| 142 | ext3_fsblk_t bitmap_blk; | ||
| 98 | 143 | ||
| 99 | desc = ext3_get_group_desc (sb, block_group, NULL); | 144 | desc = ext3_get_group_desc(sb, block_group, NULL); |
| 100 | if (!desc) | 145 | if (!desc) |
| 101 | goto error_out; | 146 | return NULL; |
| 102 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); | 147 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); |
| 103 | if (!bh) | 148 | bh = sb_getblk(sb, bitmap_blk); |
| 104 | ext3_error (sb, "read_block_bitmap", | 149 | if (unlikely(!bh)) { |
| 150 | ext3_error(sb, __FUNCTION__, | ||
| 105 | "Cannot read block bitmap - " | 151 | "Cannot read block bitmap - " |
| 106 | "block_group = %d, block_bitmap = %u", | 152 | "block_group = %d, block_bitmap = %u", |
| 107 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 153 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
| 108 | error_out: | 154 | return NULL; |
| 155 | } | ||
| 156 | if (likely(bh_uptodate_or_lock(bh))) | ||
| 157 | return bh; | ||
| 158 | |||
| 159 | if (bh_submit_read(bh) < 0) { | ||
| 160 | brelse(bh); | ||
| 161 | ext3_error(sb, __FUNCTION__, | ||
| 162 | "Cannot read block bitmap - " | ||
| 163 | "block_group = %d, block_bitmap = %u", | ||
| 164 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | ||
| 165 | return NULL; | ||
| 166 | } | ||
| 167 | if (!ext3_valid_block_bitmap(sb, desc, block_group, bh)) { | ||
| 168 | brelse(bh); | ||
| 169 | return NULL; | ||
| 170 | } | ||
| 109 | return bh; | 171 | return bh; |
| 110 | } | 172 | } |
| 111 | /* | 173 | /* |
