diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 95c212037095..24bcd5cd9cf2 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -7924,11 +7924,12 @@ err: | |||
7924 | return ret; | 7924 | return ret; |
7925 | } | 7925 | } |
7926 | 7926 | ||
7927 | static inline int submit_dio_repair_bio(struct inode *inode, struct bio *bio, | 7927 | static inline blk_status_t submit_dio_repair_bio(struct inode *inode, |
7928 | int mirror_num) | 7928 | struct bio *bio, |
7929 | int mirror_num) | ||
7929 | { | 7930 | { |
7930 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 7931 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
7931 | int ret; | 7932 | blk_status_t ret; |
7932 | 7933 | ||
7933 | BUG_ON(bio_op(bio) == REQ_OP_WRITE); | 7934 | BUG_ON(bio_op(bio) == REQ_OP_WRITE); |
7934 | 7935 | ||
@@ -7980,10 +7981,10 @@ static int btrfs_check_dio_repairable(struct inode *inode, | |||
7980 | return 1; | 7981 | return 1; |
7981 | } | 7982 | } |
7982 | 7983 | ||
7983 | static int dio_read_error(struct inode *inode, struct bio *failed_bio, | 7984 | static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio, |
7984 | struct page *page, unsigned int pgoff, | 7985 | struct page *page, unsigned int pgoff, |
7985 | u64 start, u64 end, int failed_mirror, | 7986 | u64 start, u64 end, int failed_mirror, |
7986 | bio_end_io_t *repair_endio, void *repair_arg) | 7987 | bio_end_io_t *repair_endio, void *repair_arg) |
7987 | { | 7988 | { |
7988 | struct io_failure_record *failrec; | 7989 | struct io_failure_record *failrec; |
7989 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 7990 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
@@ -7993,18 +7994,19 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, | |||
7993 | int read_mode = 0; | 7994 | int read_mode = 0; |
7994 | int segs; | 7995 | int segs; |
7995 | int ret; | 7996 | int ret; |
7997 | blk_status_t status; | ||
7996 | 7998 | ||
7997 | BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE); | 7999 | BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE); |
7998 | 8000 | ||
7999 | ret = btrfs_get_io_failure_record(inode, start, end, &failrec); | 8001 | ret = btrfs_get_io_failure_record(inode, start, end, &failrec); |
8000 | if (ret) | 8002 | if (ret) |
8001 | return ret; | 8003 | return errno_to_blk_status(ret); |
8002 | 8004 | ||
8003 | ret = btrfs_check_dio_repairable(inode, failed_bio, failrec, | 8005 | ret = btrfs_check_dio_repairable(inode, failed_bio, failrec, |
8004 | failed_mirror); | 8006 | failed_mirror); |
8005 | if (!ret) { | 8007 | if (!ret) { |
8006 | free_io_failure(failure_tree, io_tree, failrec); | 8008 | free_io_failure(failure_tree, io_tree, failrec); |
8007 | return -EIO; | 8009 | return BLK_STS_IOERR; |
8008 | } | 8010 | } |
8009 | 8011 | ||
8010 | segs = bio_segments(failed_bio); | 8012 | segs = bio_segments(failed_bio); |
@@ -8022,13 +8024,13 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, | |||
8022 | "Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n", | 8024 | "Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n", |
8023 | read_mode, failrec->this_mirror, failrec->in_validation); | 8025 | read_mode, failrec->this_mirror, failrec->in_validation); |
8024 | 8026 | ||
8025 | ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror); | 8027 | status = submit_dio_repair_bio(inode, bio, failrec->this_mirror); |
8026 | if (ret) { | 8028 | if (status) { |
8027 | free_io_failure(failure_tree, io_tree, failrec); | 8029 | free_io_failure(failure_tree, io_tree, failrec); |
8028 | bio_put(bio); | 8030 | bio_put(bio); |
8029 | } | 8031 | } |
8030 | 8032 | ||
8031 | return ret; | 8033 | return status; |
8032 | } | 8034 | } |
8033 | 8035 | ||
8034 | struct btrfs_retry_complete { | 8036 | struct btrfs_retry_complete { |
@@ -8065,8 +8067,8 @@ end: | |||
8065 | bio_put(bio); | 8067 | bio_put(bio); |
8066 | } | 8068 | } |
8067 | 8069 | ||
8068 | static int __btrfs_correct_data_nocsum(struct inode *inode, | 8070 | static blk_status_t __btrfs_correct_data_nocsum(struct inode *inode, |
8069 | struct btrfs_io_bio *io_bio) | 8071 | struct btrfs_io_bio *io_bio) |
8070 | { | 8072 | { |
8071 | struct btrfs_fs_info *fs_info; | 8073 | struct btrfs_fs_info *fs_info; |
8072 | struct bio_vec bvec; | 8074 | struct bio_vec bvec; |
@@ -8076,8 +8078,8 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, | |||
8076 | unsigned int pgoff; | 8078 | unsigned int pgoff; |
8077 | u32 sectorsize; | 8079 | u32 sectorsize; |
8078 | int nr_sectors; | 8080 | int nr_sectors; |
8079 | int ret; | 8081 | blk_status_t ret; |
8080 | int err = 0; | 8082 | blk_status_t err = BLK_STS_OK; |
8081 | 8083 | ||
8082 | fs_info = BTRFS_I(inode)->root->fs_info; | 8084 | fs_info = BTRFS_I(inode)->root->fs_info; |
8083 | sectorsize = fs_info->sectorsize; | 8085 | sectorsize = fs_info->sectorsize; |
@@ -8183,11 +8185,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode, | |||
8183 | int csum_pos; | 8185 | int csum_pos; |
8184 | bool uptodate = (err == 0); | 8186 | bool uptodate = (err == 0); |
8185 | int ret; | 8187 | int ret; |
8188 | blk_status_t status; | ||
8186 | 8189 | ||
8187 | fs_info = BTRFS_I(inode)->root->fs_info; | 8190 | fs_info = BTRFS_I(inode)->root->fs_info; |
8188 | sectorsize = fs_info->sectorsize; | 8191 | sectorsize = fs_info->sectorsize; |
8189 | 8192 | ||
8190 | err = 0; | 8193 | err = BLK_STS_OK; |
8191 | start = io_bio->logical; | 8194 | start = io_bio->logical; |
8192 | done.inode = inode; | 8195 | done.inode = inode; |
8193 | io_bio->bio.bi_iter = io_bio->iter; | 8196 | io_bio->bio.bi_iter = io_bio->iter; |
@@ -8209,12 +8212,12 @@ try_again: | |||
8209 | done.start = start; | 8212 | done.start = start; |
8210 | init_completion(&done.done); | 8213 | init_completion(&done.done); |
8211 | 8214 | ||
8212 | ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page, | 8215 | status = dio_read_error(inode, &io_bio->bio, bvec.bv_page, |
8213 | pgoff, start, start + sectorsize - 1, | 8216 | pgoff, start, start + sectorsize - 1, |
8214 | io_bio->mirror_num, | 8217 | io_bio->mirror_num, btrfs_retry_endio, |
8215 | btrfs_retry_endio, &done); | 8218 | &done); |
8216 | if (ret) { | 8219 | if (status) { |
8217 | err = errno_to_blk_status(ret); | 8220 | err = status; |
8218 | goto next; | 8221 | goto next; |
8219 | } | 8222 | } |
8220 | 8223 | ||
@@ -8250,7 +8253,7 @@ static blk_status_t btrfs_subio_endio_read(struct inode *inode, | |||
8250 | if (unlikely(err)) | 8253 | if (unlikely(err)) |
8251 | return __btrfs_correct_data_nocsum(inode, io_bio); | 8254 | return __btrfs_correct_data_nocsum(inode, io_bio); |
8252 | else | 8255 | else |
8253 | return 0; | 8256 | return BLK_STS_OK; |
8254 | } else { | 8257 | } else { |
8255 | return __btrfs_subio_endio_read(inode, io_bio, err); | 8258 | return __btrfs_subio_endio_read(inode, io_bio, err); |
8256 | } | 8259 | } |
@@ -8423,9 +8426,9 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode, | |||
8423 | return 0; | 8426 | return 0; |
8424 | } | 8427 | } |
8425 | 8428 | ||
8426 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 8429 | static inline blk_status_t |
8427 | u64 file_offset, int skip_sum, | 8430 | __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset, |
8428 | int async_submit) | 8431 | int skip_sum, int async_submit) |
8429 | { | 8432 | { |
8430 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 8433 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
8431 | struct btrfs_dio_private *dip = bio->bi_private; | 8434 | struct btrfs_dio_private *dip = bio->bi_private; |
@@ -8488,6 +8491,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, | |||
8488 | int clone_offset = 0; | 8491 | int clone_offset = 0; |
8489 | int clone_len; | 8492 | int clone_len; |
8490 | int ret; | 8493 | int ret; |
8494 | blk_status_t status; | ||
8491 | 8495 | ||
8492 | map_length = orig_bio->bi_iter.bi_size; | 8496 | map_length = orig_bio->bi_iter.bi_size; |
8493 | submit_len = map_length; | 8497 | submit_len = map_length; |
@@ -8537,9 +8541,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, | |||
8537 | */ | 8541 | */ |
8538 | atomic_inc(&dip->pending_bios); | 8542 | atomic_inc(&dip->pending_bios); |
8539 | 8543 | ||
8540 | ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, | 8544 | status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, |
8541 | async_submit); | 8545 | async_submit); |
8542 | if (ret) { | 8546 | if (status) { |
8543 | bio_put(bio); | 8547 | bio_put(bio); |
8544 | atomic_dec(&dip->pending_bios); | 8548 | atomic_dec(&dip->pending_bios); |
8545 | goto out_err; | 8549 | goto out_err; |
@@ -8557,9 +8561,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, | |||
8557 | } while (submit_len > 0); | 8561 | } while (submit_len > 0); |
8558 | 8562 | ||
8559 | submit: | 8563 | submit: |
8560 | ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, | 8564 | status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, |
8561 | async_submit); | 8565 | async_submit); |
8562 | if (!ret) | 8566 | if (!status) |
8563 | return 0; | 8567 | return 0; |
8564 | 8568 | ||
8565 | bio_put(bio); | 8569 | bio_put(bio); |