btrfs: streamline btrfs_get_io_failure_record logic

Make the function directly return a pointer to a failure record and
adjust callers to handle it. Also refactor the logic inside so that
the case which allocates the failure record for the first time is not
handled in an 'if' arm, saving us a level of indentation. Finally make
the function static as it's not used outside of extent_io.c .

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Nikolay Borisov
2020-07-02 15:23:29 +03:00
committed by David Sterba
parent 2279a27053
commit 3526302f26
2 changed files with 63 additions and 68 deletions

View File

@@ -238,8 +238,6 @@ int set_state_failrec(struct extent_io_tree *tree, u64 start,
struct io_failure_record *failrec); struct io_failure_record *failrec);
void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start, void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start,
u64 end); u64 end);
int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
struct io_failure_record **failrec_ret);
int free_io_failure(struct extent_io_tree *failure_tree, int free_io_failure(struct extent_io_tree *failure_tree,
struct extent_io_tree *io_tree, struct extent_io_tree *io_tree,
struct io_failure_record *rec); struct io_failure_record *rec);

View File

@@ -2450,8 +2450,8 @@ void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start, u64 end)
spin_unlock(&failure_tree->lock); spin_unlock(&failure_tree->lock);
} }
int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, static struct io_failure_record *btrfs_get_io_failure_record(struct inode *inode,
struct io_failure_record **failrec_ret) u64 start, u64 end)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
struct io_failure_record *failrec; struct io_failure_record *failrec;
@@ -2463,10 +2463,23 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
u64 logical; u64 logical;
failrec = get_state_failrec(failure_tree, start); failrec = get_state_failrec(failure_tree, start);
if (IS_ERR(failrec)) { if (!IS_ERR(failrec)) {
btrfs_debug(fs_info,
"Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d",
failrec->logical, failrec->start, failrec->len,
failrec->in_validation);
/*
* when data can be on disk more than twice, add to failrec here
* (e.g. with a list for failed_mirror) to make
* clean_io_failure() clean all those errors at once.
*/
return failrec;
}
failrec = kzalloc(sizeof(*failrec), GFP_NOFS); failrec = kzalloc(sizeof(*failrec), GFP_NOFS);
if (!failrec) if (!failrec)
return -ENOMEM; return ERR_PTR(-ENOMEM);
failrec->start = start; failrec->start = start;
failrec->len = end - start + 1; failrec->len = end - start + 1;
@@ -2479,7 +2492,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
if (!em) { if (!em) {
read_unlock(&em_tree->lock); read_unlock(&em_tree->lock);
kfree(failrec); kfree(failrec);
return -EIO; return ERR_PTR(-EIO);
} }
if (em->start > start || em->start + em->len <= start) { if (em->start > start || em->start + em->len <= start) {
@@ -2489,7 +2502,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
read_unlock(&em_tree->lock); read_unlock(&em_tree->lock);
if (!em) { if (!em) {
kfree(failrec); kfree(failrec);
return -EIO; return ERR_PTR(-EIO);
} }
logical = start - em->start; logical = start - em->start;
@@ -2497,8 +2510,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) { if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
logical = em->block_start; logical = em->block_start;
failrec->bio_flags = EXTENT_BIO_COMPRESSED; failrec->bio_flags = EXTENT_BIO_COMPRESSED;
extent_set_compress_type(&failrec->bio_flags, extent_set_compress_type(&failrec->bio_flags, em->compress_type);
em->compress_type);
} }
btrfs_debug(fs_info, btrfs_debug(fs_info,
@@ -2508,33 +2520,19 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
failrec->logical = logical; failrec->logical = logical;
free_extent_map(em); free_extent_map(em);
/* set the bits in the private failure tree */ /* Set the bits in the private failure tree */
ret = set_extent_bits(failure_tree, start, end, ret = set_extent_bits(failure_tree, start, end,
EXTENT_LOCKED | EXTENT_DIRTY); EXTENT_LOCKED | EXTENT_DIRTY);
if (ret >= 0) if (ret >= 0) {
ret = set_state_failrec(failure_tree, start, failrec); ret = set_state_failrec(failure_tree, start, failrec);
/* set the bits in the inode's tree */ /* Set the bits in the inode's tree */
if (ret >= 0)
ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED); ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED);
if (ret < 0) { } else if (ret < 0) {
kfree(failrec); kfree(failrec);
return ret; return ERR_PTR(ret);
}
} else {
btrfs_debug(fs_info,
"Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d",
failrec->logical, failrec->start, failrec->len,
failrec->in_validation);
/*
* when data can be on disk more than twice, add to failrec here
* (e.g. with a list for failed_mirror) to make
* clean_io_failure() clean all those errors at once.
*/
} }
*failrec_ret = failrec; return failrec;
return 0;
} }
static bool btrfs_check_repairable(struct inode *inode, bool needs_validation, static bool btrfs_check_repairable(struct inode *inode, bool needs_validation,
@@ -2659,16 +2657,15 @@ blk_status_t btrfs_submit_read_repair(struct inode *inode,
struct bio *repair_bio; struct bio *repair_bio;
struct btrfs_io_bio *repair_io_bio; struct btrfs_io_bio *repair_io_bio;
blk_status_t status; blk_status_t status;
int ret;
btrfs_debug(fs_info, btrfs_debug(fs_info,
"repair read error: read error at %llu", start); "repair read error: read error at %llu", start);
BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE); BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE);
ret = btrfs_get_io_failure_record(inode, start, end, &failrec); failrec = btrfs_get_io_failure_record(inode, start, end);
if (ret) if (IS_ERR(failrec))
return errno_to_blk_status(ret); return errno_to_blk_status(PTR_ERR(failrec));
need_validation = btrfs_io_needs_validation(inode, failed_bio); need_validation = btrfs_io_needs_validation(inode, failed_bio);