The block allocation code uses buffer_heads to store block bitmaps. Replace these buffer heads with the new ext2_buffer and update the buffer functions accordingly. Signed-off-by: Catherine Hoang <catherine.hoang@xxxxxxxxxx> --- fs/ext2/balloc.c | 108 +++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 21dafa9ae2ea..2195c6ddbc83 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -71,7 +71,7 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, static int ext2_valid_block_bitmap(struct super_block *sb, struct ext2_group_desc *desc, unsigned int block_group, - struct buffer_head *bh) + struct ext2_buffer *buf) { ext2_grpblk_t offset; ext2_grpblk_t next_zero_bit; @@ -86,7 +86,7 @@ static int ext2_valid_block_bitmap(struct super_block *sb, bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); offset = bitmap_blk - group_first_block; if (offset < 0 || offset > max_bit || - !ext2_test_bit(offset, bh->b_data)) + !ext2_test_bit(offset, buf->b_data)) /* bad block bitmap */ goto err_out; @@ -94,7 +94,7 @@ static int ext2_valid_block_bitmap(struct super_block *sb, bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); offset = bitmap_blk - group_first_block; if (offset < 0 || offset > max_bit || - !ext2_test_bit(offset, bh->b_data)) + !ext2_test_bit(offset, buf->b_data)) /* bad block bitmap */ goto err_out; @@ -104,7 +104,7 @@ static int ext2_valid_block_bitmap(struct super_block *sb, if (offset < 0 || offset > max_bit || offset + EXT2_SB(sb)->s_itb_per_group - 1 > max_bit) goto err_out; - next_zero_bit = ext2_find_next_zero_bit(bh->b_data, + next_zero_bit = ext2_find_next_zero_bit(buf->b_data, offset + EXT2_SB(sb)->s_itb_per_group, offset); if (next_zero_bit >= offset + EXT2_SB(sb)->s_itb_per_group) @@ -125,31 +125,19 @@ static int ext2_valid_block_bitmap(struct super_block *sb, * * Return buffer_head on success or NULL in case of failure. */ -static struct buffer_head * +static struct ext2_buffer * read_block_bitmap(struct super_block *sb, unsigned int block_group) { struct ext2_group_desc * desc; - struct buffer_head * bh = NULL; + struct ext2_buffer * buf = NULL; ext2_fsblk_t bitmap_blk; - int ret; desc = ext2_get_group_desc(sb, block_group, NULL); if (!desc) return NULL; bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); - bh = sb_getblk(sb, bitmap_blk); - if (unlikely(!bh)) { - ext2_error(sb, __func__, - "Cannot read block bitmap - " - "block_group = %d, block_bitmap = %u", - block_group, le32_to_cpu(desc->bg_block_bitmap)); - return NULL; - } - ret = bh_read(bh, 0); - if (ret > 0) - return bh; - if (ret < 0) { - brelse(bh); + buf = ext2_read_buffer(sb, bitmap_blk); + if (unlikely(IS_ERR(buf))) { ext2_error(sb, __func__, "Cannot read block bitmap - " "block_group = %d, block_bitmap = %u", @@ -157,12 +145,12 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) return NULL; } - ext2_valid_block_bitmap(sb, desc, block_group, bh); + ext2_valid_block_bitmap(sb, desc, block_group, buf); /* * file system mounted not to panic on error, continue with corrupt * bitmap */ - return bh; + return buf; } static void group_adjust_blocks(struct super_block *sb, int group_no, @@ -482,7 +470,7 @@ void ext2_discard_reservation(struct inode *inode) void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, unsigned long count) { - struct buffer_head *bitmap_bh = NULL; + struct ext2_buffer *bitmap_buf = NULL; struct ext2_buffer * buf2; unsigned long block_group; unsigned long bit; @@ -517,9 +505,9 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, overflow = bit + count - EXT2_BLOCKS_PER_GROUP(sb); count -= overflow; } - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, block_group); - if (!bitmap_bh) + ext2_put_buffer(sb, bitmap_buf); + bitmap_buf = read_block_bitmap(sb, block_group); + if (IS_ERR(bitmap_buf)) goto error_return; desc = ext2_get_group_desc (sb, block_group, &buf2); @@ -541,7 +529,7 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, for (i = 0, group_freed = 0; i < count; i++) { if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), - bit + i, bitmap_bh->b_data)) { + bit + i, bitmap_buf->b_data)) { ext2_error(sb, __func__, "bit already cleared for block %lu", block + i); } else { @@ -549,9 +537,9 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, } } - mark_buffer_dirty(bitmap_bh); + ext2_buffer_set_dirty(bitmap_buf); if (sb->s_flags & SB_SYNCHRONOUS) - sync_dirty_buffer(bitmap_bh); + ext2_sync_buffer_wait(sb, bitmap_buf); group_adjust_blocks(sb, block_group, desc, buf2, group_freed); freed += group_freed; @@ -562,7 +550,7 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, goto do_more; } error_return: - brelse(bitmap_bh); + ext2_put_buffer(sb, bitmap_buf); if (freed) { percpu_counter_add(&sbi->s_freeblocks_counter, freed); dquot_free_block_nodirty(inode, freed); @@ -580,12 +568,12 @@ void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block, * we find a bit free. */ static ext2_grpblk_t -bitmap_search_next_usable_block(ext2_grpblk_t start, struct buffer_head *bh, +bitmap_search_next_usable_block(ext2_grpblk_t start, struct ext2_buffer *buf, ext2_grpblk_t maxblocks) { ext2_grpblk_t next; - next = ext2_find_next_zero_bit(bh->b_data, maxblocks, start); + next = ext2_find_next_zero_bit(buf->b_data, maxblocks, start); if (next >= maxblocks) return -1; return next; @@ -604,7 +592,7 @@ bitmap_search_next_usable_block(ext2_grpblk_t start, struct buffer_head *bh, * then for any free bit in the bitmap. */ static ext2_grpblk_t -find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) +find_next_usable_block(int start, struct ext2_buffer *buf, int maxblocks) { ext2_grpblk_t here, next; char *p, *r; @@ -621,7 +609,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) ext2_grpblk_t end_goal = (start + 63) & ~63; if (end_goal > maxblocks) end_goal = maxblocks; - here = ext2_find_next_zero_bit(bh->b_data, end_goal, start); + here = ext2_find_next_zero_bit(buf->b_data, end_goal, start); if (here < end_goal) return here; ext2_debug("Bit not found near goal\n"); @@ -631,14 +619,14 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) if (here < 0) here = 0; - p = ((char *)bh->b_data) + (here >> 3); + p = ((char *)buf->b_data) + (here >> 3); r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); - next = (r - ((char *)bh->b_data)) << 3; + next = (r - ((char *)buf->b_data)) << 3; if (next < maxblocks && next >= here) return next; - here = bitmap_search_next_usable_block(here, bh, maxblocks); + here = bitmap_search_next_usable_block(here, buf, maxblocks); return here; } @@ -666,7 +654,7 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks) */ static int ext2_try_to_allocate(struct super_block *sb, int group, - struct buffer_head *bitmap_bh, ext2_grpblk_t grp_goal, + struct ext2_buffer *bitmap_buf, ext2_grpblk_t grp_goal, unsigned long *count, struct ext2_reserve_window *my_rsv) { @@ -689,7 +677,7 @@ ext2_try_to_allocate(struct super_block *sb, int group, BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb)); if (grp_goal < 0) { - grp_goal = find_next_usable_block(start, bitmap_bh, end); + grp_goal = find_next_usable_block(start, bitmap_buf, end); if (grp_goal < 0) goto fail_access; if (!my_rsv) { @@ -697,7 +685,7 @@ ext2_try_to_allocate(struct super_block *sb, int group, for (i = 0; i < 7 && grp_goal > start && !ext2_test_bit(grp_goal - 1, - bitmap_bh->b_data); + bitmap_buf->b_data); i++, grp_goal--) ; } @@ -705,7 +693,7 @@ ext2_try_to_allocate(struct super_block *sb, int group, for (; num < *count && grp_goal < end; grp_goal++) { if (ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), - grp_goal, bitmap_bh->b_data)) { + grp_goal, bitmap_buf->b_data)) { if (num == 0) continue; break; @@ -869,7 +857,7 @@ static int find_next_reservable_window( */ static int alloc_new_reservation(struct ext2_reserve_window_node *my_rsv, ext2_grpblk_t grp_goal, struct super_block *sb, - unsigned int group, struct buffer_head *bitmap_bh) + unsigned int group, struct ext2_buffer *bitmap_buf) { struct ext2_reserve_window_node *search_head; ext2_fsblk_t group_first_block, group_end_block, start_block; @@ -960,7 +948,7 @@ static int alloc_new_reservation(struct ext2_reserve_window_node *my_rsv, spin_unlock(rsv_lock); first_free_block = bitmap_search_next_usable_block( my_rsv->rsv_start - group_first_block, - bitmap_bh, group_end_block - group_first_block + 1); + bitmap_buf, group_end_block - group_first_block + 1); if (first_free_block < 0) { /* @@ -1062,7 +1050,7 @@ static void try_to_extend_reservation(struct ext2_reserve_window_node *my_rsv, */ static ext2_grpblk_t ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group, - struct buffer_head *bitmap_bh, ext2_grpblk_t grp_goal, + struct ext2_buffer *bitmap_buf, ext2_grpblk_t grp_goal, struct ext2_reserve_window_node * my_rsv, unsigned long *count) { @@ -1077,7 +1065,7 @@ ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group, * or last attempt to allocate a block with reservation turned on failed */ if (my_rsv == NULL) { - return ext2_try_to_allocate(sb, group, bitmap_bh, + return ext2_try_to_allocate(sb, group, bitmap_buf, grp_goal, count, NULL); } /* @@ -1111,7 +1099,7 @@ ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group, if (my_rsv->rsv_goal_size < *count) my_rsv->rsv_goal_size = *count; ret = alloc_new_reservation(my_rsv, grp_goal, sb, - group, bitmap_bh); + group, bitmap_buf); if (ret < 0) break; /* failed */ @@ -1137,7 +1125,7 @@ ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group, rsv_window_dump(&EXT2_SB(sb)->s_rsv_window_root, 1); return -1; } - ret = ext2_try_to_allocate(sb, group, bitmap_bh, grp_goal, + ret = ext2_try_to_allocate(sb, group, bitmap_buf, grp_goal, &num, &my_rsv->rsv_window); if (ret >= 0) { my_rsv->rsv_alloc_hit += num; @@ -1208,7 +1196,7 @@ int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk, ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, unsigned long *count, int *errp, unsigned int flags) { - struct buffer_head *bitmap_bh = NULL; + struct ext2_buffer *bitmap_buf = NULL; struct ext2_buffer *gdp_buf; int group_no; int goal_group; @@ -1297,12 +1285,12 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, * pointer and we have to release it before calling * read_block_bitmap(). */ - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, group_no); - if (!bitmap_bh) + ext2_put_buffer(sb, bitmap_buf); + bitmap_buf = read_block_bitmap(sb, group_no); + if (IS_ERR(bitmap_buf)) goto io_error; grp_alloc_blk = ext2_try_to_allocate_with_rsv(sb, group_no, - bitmap_bh, grp_target_blk, + bitmap_buf, grp_target_blk, my_rsv, &num); if (grp_alloc_blk >= 0) goto allocated; @@ -1338,15 +1326,15 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, if (my_rsv && (free_blocks <= (windowsz/2))) continue; - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, group_no); - if (!bitmap_bh) + ext2_put_buffer(sb, bitmap_buf); + bitmap_buf = read_block_bitmap(sb, group_no); + if (IS_ERR(bitmap_buf)) goto io_error; /* * try to allocate block(s) from this group, without a goal(-1). */ grp_alloc_blk = ext2_try_to_allocate_with_rsv(sb, group_no, - bitmap_bh, -1, my_rsv, &num); + bitmap_buf, -1, my_rsv, &num); if (grp_alloc_blk >= 0) goto allocated; } @@ -1406,12 +1394,12 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, group_adjust_blocks(sb, group_no, gdp, gdp_buf, -num); percpu_counter_sub(&sbi->s_freeblocks_counter, num); - mark_buffer_dirty(bitmap_bh); + ext2_buffer_set_dirty(bitmap_buf); if (sb->s_flags & SB_SYNCHRONOUS) - sync_dirty_buffer(bitmap_bh); + ext2_sync_buffer_wait(sb, bitmap_buf); *errp = 0; - brelse(bitmap_bh); + ext2_put_buffer(sb, bitmap_buf); if (num < *count) { dquot_free_block_nodirty(inode, *count-num); mark_inode_dirty(inode); @@ -1429,7 +1417,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, dquot_free_block_nodirty(inode, *count); mark_inode_dirty(inode); } - brelse(bitmap_bh); + ext2_put_buffer(sb, bitmap_buf); return 0; } -- 2.43.0