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 f9e2cd8cf711..a2cff2b9d5b5 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -336,10 +336,10 @@ err_out: | |||
336 | * Return buffer_head on success or NULL in case of failure. | 336 | * Return buffer_head on success or NULL in case of failure. |
337 | */ | 337 | */ |
338 | struct buffer_head * | 338 | struct buffer_head * |
339 | ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | 339 | ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) |
340 | { | 340 | { |
341 | struct ext4_group_desc *desc; | 341 | struct ext4_group_desc *desc; |
342 | struct buffer_head *bh = NULL; | 342 | struct buffer_head *bh; |
343 | ext4_fsblk_t bitmap_blk; | 343 | ext4_fsblk_t bitmap_blk; |
344 | 344 | ||
345 | desc = ext4_get_group_desc(sb, block_group, NULL); | 345 | 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) | |||
348 | bitmap_blk = ext4_block_bitmap(sb, desc); | 348 | bitmap_blk = ext4_block_bitmap(sb, desc); |
349 | bh = sb_getblk(sb, bitmap_blk); | 349 | bh = sb_getblk(sb, bitmap_blk); |
350 | if (unlikely(!bh)) { | 350 | if (unlikely(!bh)) { |
351 | ext4_error(sb, "Cannot read block bitmap - " | 351 | ext4_error(sb, "Cannot get buffer for block bitmap - " |
352 | "block_group = %u, block_bitmap = %llu", | 352 | "block_group = %u, block_bitmap = %llu", |
353 | block_group, bitmap_blk); | 353 | block_group, bitmap_blk); |
354 | return NULL; | 354 | return NULL; |
355 | } | 355 | } |
356 | 356 | ||
@@ -382,25 +382,50 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
382 | return bh; | 382 | return bh; |
383 | } | 383 | } |
384 | /* | 384 | /* |
385 | * submit the buffer_head for read. We can | 385 | * submit the buffer_head for reading |
386 | * safely mark the bitmap as uptodate now. | ||
387 | * We do it here so the bitmap uptodate bit | ||
388 | * get set with buffer lock held. | ||
389 | */ | 386 | */ |
387 | set_buffer_new(bh); | ||
390 | trace_ext4_read_block_bitmap_load(sb, block_group); | 388 | trace_ext4_read_block_bitmap_load(sb, block_group); |
391 | set_bitmap_uptodate(bh); | 389 | bh->b_end_io = ext4_end_bitmap_read; |
392 | if (bh_submit_read(bh) < 0) { | 390 | get_bh(bh); |
393 | put_bh(bh); | 391 | submit_bh(READ, bh); |
392 | return bh; | ||
393 | } | ||
394 | |||
395 | /* Returns 0 on success, 1 on error */ | ||
396 | int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group, | ||
397 | struct buffer_head *bh) | ||
398 | { | ||
399 | struct ext4_group_desc *desc; | ||
400 | |||
401 | if (!buffer_new(bh)) | ||
402 | return 0; | ||
403 | desc = ext4_get_group_desc(sb, block_group, NULL); | ||
404 | if (!desc) | ||
405 | return 1; | ||
406 | wait_on_buffer(bh); | ||
407 | if (!buffer_uptodate(bh)) { | ||
394 | ext4_error(sb, "Cannot read block bitmap - " | 408 | ext4_error(sb, "Cannot read block bitmap - " |
395 | "block_group = %u, block_bitmap = %llu", | 409 | "block_group = %u, block_bitmap = %llu", |
396 | block_group, bitmap_blk); | 410 | block_group, bh->b_blocknr); |
397 | return NULL; | 411 | return 1; |
398 | } | 412 | } |
413 | clear_buffer_new(bh); | ||
414 | /* Panic or remount fs read-only if block bitmap is invalid */ | ||
399 | ext4_valid_block_bitmap(sb, desc, block_group, bh); | 415 | ext4_valid_block_bitmap(sb, desc, block_group, bh); |
400 | /* | 416 | return 0; |
401 | * file system mounted not to panic on error, | 417 | } |
402 | * continue with corrupt bitmap | 418 | |
403 | */ | 419 | struct buffer_head * |
420 | ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | ||
421 | { | ||
422 | struct buffer_head *bh; | ||
423 | |||
424 | bh = ext4_read_block_bitmap_nowait(sb, block_group); | ||
425 | if (ext4_wait_block_bitmap(sb, block_group, bh)) { | ||
426 | put_bh(bh); | ||
427 | return NULL; | ||
428 | } | ||
404 | return bh; | 429 | return bh; |
405 | } | 430 | } |
406 | 431 | ||