OSDN Git Service

btrfs: streamline btrfs_get_io_failure_record logic
authorNikolay Borisov <nborisov@suse.com>
Thu, 2 Jul 2020 12:23:29 +0000 (15:23 +0300)
committerDavid Sterba <dsterba@suse.com>
Mon, 27 Jul 2020 10:55:39 +0000 (12:55 +0200)
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>
fs/btrfs/extent-io-tree.h
fs/btrfs/extent_io.c

index b6db2b1..f39d47a 100644 (file)
@@ -238,8 +238,6 @@ int set_state_failrec(struct extent_io_tree *tree, u64 start,
                      struct io_failure_record *failrec);
 void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start,
                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,
                    struct extent_io_tree *io_tree,
                    struct io_failure_record *rec);
index 59ec534..e37950a 100644 (file)
@@ -2450,8 +2450,8 @@ void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start, u64 end)
        spin_unlock(&failure_tree->lock);
 }
 
-int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
-               struct io_failure_record **failrec_ret)
+static struct io_failure_record *btrfs_get_io_failure_record(struct inode *inode,
+                                                            u64 start, u64 end)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct io_failure_record *failrec;
@@ -2463,64 +2463,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
        u64 logical;
 
        failrec = get_state_failrec(failure_tree, start);
-       if (IS_ERR(failrec)) {
-               failrec = kzalloc(sizeof(*failrec), GFP_NOFS);
-               if (!failrec)
-                       return -ENOMEM;
-
-               failrec->start = start;
-               failrec->len = end - start + 1;
-               failrec->this_mirror = 0;
-               failrec->bio_flags = 0;
-               failrec->in_validation = 0;
-
-               read_lock(&em_tree->lock);
-               em = lookup_extent_mapping(em_tree, start, failrec->len);
-               if (!em) {
-                       read_unlock(&em_tree->lock);
-                       kfree(failrec);
-                       return -EIO;
-               }
-
-               if (em->start > start || em->start + em->len <= start) {
-                       free_extent_map(em);
-                       em = NULL;
-               }
-               read_unlock(&em_tree->lock);
-               if (!em) {
-                       kfree(failrec);
-                       return -EIO;
-               }
-
-               logical = start - em->start;
-               logical = em->block_start + logical;
-               if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
-                       logical = em->block_start;
-                       failrec->bio_flags = EXTENT_BIO_COMPRESSED;
-                       extent_set_compress_type(&failrec->bio_flags,
-                                                em->compress_type);
-               }
-
-               btrfs_debug(fs_info,
-                       "Get IO Failure Record: (new) logical=%llu, start=%llu, len=%llu",
-                       logical, start, failrec->len);
-
-               failrec->logical = logical;
-               free_extent_map(em);
-
-               /* set the bits in the private failure tree */
-               ret = set_extent_bits(failure_tree, start, end,
-                                       EXTENT_LOCKED | EXTENT_DIRTY);
-               if (ret >= 0)
-                       ret = set_state_failrec(failure_tree, start, failrec);
-               /* set the bits in the inode's tree */
-               if (ret >= 0)
-                       ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED);
-               if (ret < 0) {
-                       kfree(failrec);
-                       return ret;
-               }
-       } else {
+       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,
@@ -2530,11 +2473,66 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
                 * (e.g. with a list for failed_mirror) to make
                 * clean_io_failure() clean all those errors at once.
                 */
+
+               return failrec;
        }
 
-       *failrec_ret = failrec;
+       failrec = kzalloc(sizeof(*failrec), GFP_NOFS);
+       if (!failrec)
+               return ERR_PTR(-ENOMEM);
 
-       return 0;
+       failrec->start = start;
+       failrec->len = end - start + 1;
+       failrec->this_mirror = 0;
+       failrec->bio_flags = 0;
+       failrec->in_validation = 0;
+
+       read_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, start, failrec->len);
+       if (!em) {
+               read_unlock(&em_tree->lock);
+               kfree(failrec);
+               return ERR_PTR(-EIO);
+       }
+
+       if (em->start > start || em->start + em->len <= start) {
+               free_extent_map(em);
+               em = NULL;
+       }
+       read_unlock(&em_tree->lock);
+       if (!em) {
+               kfree(failrec);
+               return ERR_PTR(-EIO);
+       }
+
+       logical = start - em->start;
+       logical = em->block_start + logical;
+       if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
+               logical = em->block_start;
+               failrec->bio_flags = EXTENT_BIO_COMPRESSED;
+               extent_set_compress_type(&failrec->bio_flags, em->compress_type);
+       }
+
+       btrfs_debug(fs_info,
+                   "Get IO Failure Record: (new) logical=%llu, start=%llu, len=%llu",
+                   logical, start, failrec->len);
+
+       failrec->logical = logical;
+       free_extent_map(em);
+
+       /* Set the bits in the private failure tree */
+       ret = set_extent_bits(failure_tree, start, end,
+                             EXTENT_LOCKED | EXTENT_DIRTY);
+       if (ret >= 0) {
+               ret = set_state_failrec(failure_tree, start, failrec);
+               /* Set the bits in the inode's tree */
+               ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED);
+       } else if (ret < 0) {
+               kfree(failrec);
+               return ERR_PTR(ret);
+       }
+
+       return failrec;
 }
 
 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 btrfs_io_bio *repair_io_bio;
        blk_status_t status;
-       int ret;
 
        btrfs_debug(fs_info,
                   "repair read error: read error at %llu", start);
 
        BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE);
 
-       ret = btrfs_get_io_failure_record(inode, start, end, &failrec);
-       if (ret)
-               return errno_to_blk_status(ret);
+       failrec = btrfs_get_io_failure_record(inode, start, end);
+       if (IS_ERR(failrec))
+               return errno_to_blk_status(PTR_ERR(failrec));
 
        need_validation = btrfs_io_needs_validation(inode, failed_bio);