aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/balloc.c78
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
83static 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
119err_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));
108error_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/*