diff options
Diffstat (limited to 'fs/ext4/balloc.c')
| -rw-r--r-- | fs/ext4/balloc.c | 63 | 
1 files changed, 44 insertions, 19 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index f9e2cd8cf71..4bbd07a6fa1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -336,10 +336,10 @@ err_out:   * Return buffer_head on success or NULL in case of failure.   */  struct buffer_head * -ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) +ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)  {  	struct ext4_group_desc *desc; -	struct buffer_head *bh = NULL; +	struct buffer_head *bh;  	ext4_fsblk_t bitmap_blk;  	desc = ext4_get_group_desc(sb, block_group, NULL); @@ -348,9 +348,9 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)  	bitmap_blk = ext4_block_bitmap(sb, desc);  	bh = sb_getblk(sb, bitmap_blk);  	if (unlikely(!bh)) { -		ext4_error(sb, "Cannot read block bitmap - " -			    "block_group = %u, block_bitmap = %llu", -			    block_group, bitmap_blk); +		ext4_error(sb, "Cannot get buffer for block bitmap - " +			   "block_group = %u, block_bitmap = %llu", +			   block_group, bitmap_blk);  		return NULL;  	} @@ -382,25 +382,50 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)  		return bh;  	}  	/* -	 * submit the buffer_head for read. We can -	 * safely mark the bitmap as uptodate now. -	 * We do it here so the bitmap uptodate bit -	 * get set with buffer lock held. +	 * submit the buffer_head for reading  	 */ +	set_buffer_new(bh);  	trace_ext4_read_block_bitmap_load(sb, block_group); -	set_bitmap_uptodate(bh); -	if (bh_submit_read(bh) < 0) { -		put_bh(bh); +	bh->b_end_io = ext4_end_bitmap_read; +	get_bh(bh); +	submit_bh(READ, bh); +	return bh; +} + +/* Returns 0 on success, 1 on error */ +int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group, +			   struct buffer_head *bh) +{ +	struct ext4_group_desc *desc; + +	if (!buffer_new(bh)) +		return 0; +	desc = ext4_get_group_desc(sb, block_group, NULL); +	if (!desc) +		return 1; +	wait_on_buffer(bh); +	if (!buffer_uptodate(bh)) {  		ext4_error(sb, "Cannot read block bitmap - " -			    "block_group = %u, block_bitmap = %llu", -			    block_group, bitmap_blk); -		return NULL; +			   "block_group = %u, block_bitmap = %llu", +			   block_group, (unsigned long long) bh->b_blocknr); +		return 1;  	} +	clear_buffer_new(bh); +	/* Panic or remount fs read-only if block bitmap is invalid */  	ext4_valid_block_bitmap(sb, desc, block_group, bh); -	/* -	 * file system mounted not to panic on error, -	 * continue with corrupt bitmap -	 */ +	return 0; +} + +struct buffer_head * +ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) +{ +	struct buffer_head *bh; + +	bh = ext4_read_block_bitmap_nowait(sb, block_group); +	if (ext4_wait_block_bitmap(sb, block_group, bh)) { +		put_bh(bh); +		return NULL; +	}  	return bh;  }  |