diff options
| author | Omar Sandoval <osandov@fb.com> | 2017-08-23 02:45:59 -0400 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2017-08-24 11:19:02 -0400 |
| commit | 58efbc9f5463308c43d812fd0748a4dee44c8a16 (patch) | |
| tree | 400bd7ce429cf0ef769c3736dcb153f28dfdbcee | |
| parent | 14ccee78fc82f5512908f4424f541549a5705b89 (diff) | |
Btrfs: fix blk_status_t/errno confusion
This fixes several instances of blk_status_t and bare errno ints being
mixed up, some of which are real bugs.
In the normal case, 0 matches BLK_STS_OK, so we don't observe any
effects of the missing conversion, but in case of errors or passes
through the repair/retry paths, the errors get mixed up.
The changes were identified using 'sparse', we don't have reports of the
buggy behaviour.
Fixes: 4e4cbee93d56 ("block: switch bios to blk_status_t")
Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
| -rw-r--r-- | fs/btrfs/disk-io.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 70 | ||||
| -rw-r--r-- | fs/btrfs/raid56.c | 34 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/volumes.h | 6 |
5 files changed, 64 insertions, 60 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 080e2ebb8aa0..f45b61fe9a9a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -3516,7 +3516,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device) | |||
| 3516 | struct bio *bio = device->flush_bio; | 3516 | struct bio *bio = device->flush_bio; |
| 3517 | 3517 | ||
| 3518 | if (!device->flush_bio_sent) | 3518 | if (!device->flush_bio_sent) |
| 3519 | return 0; | 3519 | return BLK_STS_OK; |
| 3520 | 3520 | ||
| 3521 | device->flush_bio_sent = 0; | 3521 | device->flush_bio_sent = 0; |
| 3522 | wait_for_completion_io(&device->flush_wait); | 3522 | wait_for_completion_io(&device->flush_wait); |
| @@ -3563,7 +3563,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info) | |||
| 3563 | continue; | 3563 | continue; |
| 3564 | 3564 | ||
| 3565 | write_dev_flush(dev); | 3565 | write_dev_flush(dev); |
| 3566 | dev->last_flush_error = 0; | 3566 | dev->last_flush_error = BLK_STS_OK; |
| 3567 | } | 3567 | } |
| 3568 | 3568 | ||
| 3569 | /* wait for all the barriers */ | 3569 | /* wait for all the barriers */ |
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 | |||
