1 fs/ext3/balloc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++----------
2 1 files changed, 81 insertions(+), 18 deletions(-)
3 diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
4 index ff3428e..a9140ea 100644
5 Index: linux-stage/fs/ext3/balloc.c
6 ===================================================================
7 --- linux-stage.orig/fs/ext3/balloc.c
8 +++ linux-stage/fs/ext3/balloc.c
9 @@ -144,9 +144,96 @@ unsigned ext3_init_block_bitmap(struct s
10 return free_blocks - sbi->s_itb_per_group - 2;
14 - * Read the bitmap for a given block_group, reading into the specified
15 - * slot in the superblock's bitmap cache.
17 +* bh_uptodate_or_lock: Test whether the buffer is uptodate
18 +* @bh: struct buffer_head
20 +* Return true if the buffer is up-to-date and false,
21 +* with the buffer locked, if not.
23 +int bh_uptodate_or_lock(struct buffer_head *bh)
25 + if (!buffer_uptodate(bh)) {
27 + if (!buffer_uptodate(bh))
35 +* bh_submit_read: Submit a locked buffer for reading
36 +* @bh: struct buffer_head
38 +* Returns a negative error
40 +int bh_submit_read(struct buffer_head *bh)
42 + if (!buffer_locked(bh))
44 + if (buffer_uptodate(bh))
47 + bh->b_end_io = end_buffer_read_sync;
48 + submit_bh(READ, bh);
50 + if (buffer_uptodate(bh))
55 +static int ext3_valid_block_bitmap(struct super_block *sb,
56 + struct ext3_group_desc *desc,
57 + unsigned int block_group,
58 + struct buffer_head *bh)
60 + unsigned long long offset;
61 + unsigned long long next_zero_bit;
62 + unsigned long long bitmap_blk;
63 + unsigned long long group_first_block;
65 + group_first_block = ext3_group_first_block_no(sb, block_group);
67 + /* check whether block bitmap block number is set */
68 + bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
69 + offset = bitmap_blk - group_first_block;
70 + if (!ext3_test_bit(offset, bh->b_data))
71 + /* bad block bitmap */
74 + /* check whether the inode bitmap block number is set */
75 + bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
76 + offset = bitmap_blk - group_first_block;
77 + if (!ext3_test_bit(offset, bh->b_data))
78 + /* bad block bitmap */
81 + /* check whether the inode table block number is set */
82 + bitmap_blk = le32_to_cpu(desc->bg_inode_table);
83 + offset = bitmap_blk - group_first_block;
84 + next_zero_bit = ext3_find_next_zero_bit(bh->b_data,
85 + offset + EXT3_SB(sb)->s_itb_per_group,
87 + if (next_zero_bit >= offset + EXT3_SB(sb)->s_itb_per_group)
88 + /* good bitmap for inode tables */
92 + ext3_error(sb, __FUNCTION__,
93 + "Invalid block bitmap - "
94 + "block_group = %d, block = %llu",
95 + block_group, bitmap_blk);
100 + * read_block_bitmap()
102 + * @block_group: given block group
104 + * Read the bitmap for a given block_group,and validate the
105 + * bits for block/inode/inode tables are set in the bitmaps.
107 * Return buffer_head on success or NULL in case of failure.
109 @@ -155,29 +242,42 @@ read_block_bitmap(struct super_block *sb
111 struct ext3_group_desc * desc;
112 struct buffer_head * bh = NULL;
113 + unsigned long long bitmap_blk;
115 desc = ext3_get_group_desc (sb, block_group, NULL);
119 + bitmap_blk = desc->bg_block_bitmap;
120 + bh = sb_getblk(sb, bitmap_blk);
121 + if (unlikely(!bh)) {
122 + ext3_error(sb, __FUNCTION__,
123 + "Can not read block bitmap - "
124 + "block group = %d, block_bitmap = %llu",
125 + (int)block_group, bitmap_blk);
128 + if (bh_uptodate_or_lock(bh))
131 if (desc->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {
132 - bh = sb_getblk(sb, le32_to_cpu(desc->bg_block_bitmap));
133 - if (!buffer_uptodate(bh)) {
135 - if (!buffer_uptodate(bh)) {
136 - ext3_init_block_bitmap(sb, bh,block_group,desc);
137 - set_buffer_uptodate(bh);
142 - bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
143 + ext3_init_block_bitmap(sb, bh, block_group, desc);
144 + set_buffer_uptodate(bh);
148 + if (bh_submit_read(bh) < 0) {
150 + ext3_error(sb, __FUNCTION__,
151 + "Cannot read block bitmap - "
152 + "block group = %d block_bitmap = %llu",
153 + (int)block_group, bitmap_blk);
157 - ext3_error (sb, "read_block_bitmap",
158 - "Cannot read block bitmap - "
159 - "block_group = %d, block_bitmap = %u",
160 - block_group, le32_to_cpu(desc->bg_block_bitmap));
162 + if (!ext3_valid_block_bitmap(sb, desc, block_group, bh)) {
170 Index: linux-stage/include/linux/ext3_fs.h
171 ===================================================================
172 --- linux-stage.orig/include/linux/ext3_fs.h
173 +++ linux-stage/include/linux/ext3_fs.h
174 @@ -872,6 +872,14 @@ struct dir_private_info {
178 +/* calculate the first block number of the group */
179 +static inline long long
180 +ext3_group_first_block_no(struct super_block *sb, unsigned long group_no)
182 + return group_no * (long long)EXT3_BLOCKS_PER_GROUP(sb) +
183 + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block);
187 * Special error return code only used by dx_probe() and its callers.