Skip to content

Commit

Permalink
Btrfs: in scrub repair code, simplify alloc error handling
Browse files Browse the repository at this point in the history
In the scrub repair code, the code is changed to handle memory
allocation errors a little bit smarter. The change is to handle
it just like a read error. This simplifies the code and removes
a couple of lines of code, since the code to handle read errors
is there anyway.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
  • Loading branch information
Stefan Behrens authored and Josef Bacik committed Dec 12, 2012
1 parent cb2ced7 commit 34f5c8e
Showing 1 changed file with 26 additions and 35 deletions.
61 changes: 26 additions & 35 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx,
struct btrfs_mapping_tree *map_tree,
u64 length, u64 logical,
struct scrub_block *sblock);
static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
struct scrub_block *sblock, int is_metadata,
int have_csum, u8 *csum, u64 generation,
u16 csum_size);
static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
struct scrub_block *sblock, int is_metadata,
int have_csum, u8 *csum, u64 generation,
u16 csum_size);
static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
struct scrub_block *sblock,
int is_metadata, int have_csum,
Expand Down Expand Up @@ -718,16 +718,8 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
sblock_bad = sblocks_for_recheck + failed_mirror_index;

/* build and submit the bios for the failed mirror, check checksums */
ret = scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum,
csum, generation, sctx->csum_size);
if (ret) {
spin_lock(&sctx->stat_lock);
sctx->stat.read_errors++;
sctx->stat.uncorrectable_errors++;
spin_unlock(&sctx->stat_lock);
btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_READ_ERRS);
goto out;
}
scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum,
csum, generation, sctx->csum_size);

if (!sblock_bad->header_error && !sblock_bad->checksum_error &&
sblock_bad->no_io_error_seen) {
Expand Down Expand Up @@ -843,10 +835,11 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
sblock_other = sblocks_for_recheck + mirror_index;

/* build and submit the bios, check checksums */
ret = scrub_recheck_block(fs_info, sblock_other, is_metadata,
have_csum, csum, generation,
sctx->csum_size);
if (!ret && !sblock_other->header_error &&
scrub_recheck_block(fs_info, sblock_other, is_metadata,
have_csum, csum, generation,
sctx->csum_size);

if (!sblock_other->header_error &&
!sblock_other->checksum_error &&
sblock_other->no_io_error_seen) {
int force_write = is_metadata || have_csum;
Expand Down Expand Up @@ -931,10 +924,10 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
* is verified, but most likely the data comes out
* of the page cache.
*/
ret = scrub_recheck_block(fs_info, sblock_bad,
is_metadata, have_csum, csum,
generation, sctx->csum_size);
if (!ret && !sblock_bad->header_error &&
scrub_recheck_block(fs_info, sblock_bad,
is_metadata, have_csum, csum,
generation, sctx->csum_size);
if (!sblock_bad->header_error &&
!sblock_bad->checksum_error &&
sblock_bad->no_io_error_seen)
goto corrected_error;
Expand Down Expand Up @@ -1061,10 +1054,10 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx,
* to take those pages that are not errored from all the mirrors so that
* the pages that are errored in the just handled mirror can be repaired.
*/
static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
struct scrub_block *sblock, int is_metadata,
int have_csum, u8 *csum, u64 generation,
u16 csum_size)
static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
struct scrub_block *sblock, int is_metadata,
int have_csum, u8 *csum, u64 generation,
u16 csum_size)
{
int page_num;

Expand All @@ -1074,7 +1067,6 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,

for (page_num = 0; page_num < sblock->page_count; page_num++) {
struct bio *bio;
int ret;
struct scrub_page *page = sblock->pagev[page_num];
DECLARE_COMPLETION_ONSTACK(complete);

Expand All @@ -1086,18 +1078,17 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,

WARN_ON(!page->page);
bio = bio_alloc(GFP_NOFS, 1);
if (!bio)
return -EIO;
if (!bio) {
page->io_error = 1;
sblock->no_io_error_seen = 0;
continue;
}
bio->bi_bdev = page->dev->bdev;
bio->bi_sector = page->physical >> 9;
bio->bi_end_io = scrub_complete_bio_end_io;
bio->bi_private = &complete;

ret = bio_add_page(bio, page->page, PAGE_SIZE, 0);
if (PAGE_SIZE != ret) {
bio_put(bio);
return -EIO;
}
bio_add_page(bio, page->page, PAGE_SIZE, 0);
btrfsic_submit_bio(READ, bio);

/* this will also unplug the queue */
Expand All @@ -1114,7 +1105,7 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
have_csum, csum, generation,
csum_size);

return 0;
return;
}

static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,
Expand Down

0 comments on commit 34f5c8e

Please sign in to comment.