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:
committed by
David Sterba
parent
2279a27053
commit
3526302f26
@@ -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)
|
|||||||
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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user