Commit 3526302f authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba

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: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 2279a270
...@@ -238,8 +238,6 @@ int set_state_failrec(struct extent_io_tree *tree, u64 start, ...@@ -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);
......
...@@ -2450,8 +2450,8 @@ void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start, u64 end) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment