Commit 58efbc9f authored by Omar Sandoval's avatar Omar Sandoval Committed by David Sterba

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: 4e4cbee9 ("block: switch bios to blk_status_t")
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Reviewed-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 14ccee78
...@@ -3516,7 +3516,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device) ...@@ -3516,7 +3516,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device)
struct bio *bio = device->flush_bio; struct bio *bio = device->flush_bio;
if (!device->flush_bio_sent) if (!device->flush_bio_sent)
return 0; return BLK_STS_OK;
device->flush_bio_sent = 0; device->flush_bio_sent = 0;
wait_for_completion_io(&device->flush_wait); wait_for_completion_io(&device->flush_wait);
...@@ -3563,7 +3563,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info) ...@@ -3563,7 +3563,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
continue; continue;
write_dev_flush(dev); write_dev_flush(dev);
dev->last_flush_error = 0; dev->last_flush_error = BLK_STS_OK;
} }
/* wait for all the barriers */ /* wait for all the barriers */
......
...@@ -7924,11 +7924,12 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, ...@@ -7924,11 +7924,12 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
return ret; return ret;
} }
static inline int submit_dio_repair_bio(struct inode *inode, struct bio *bio, static inline blk_status_t submit_dio_repair_bio(struct inode *inode,
struct bio *bio,
int mirror_num) int mirror_num)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
int ret; blk_status_t ret;
BUG_ON(bio_op(bio) == REQ_OP_WRITE); BUG_ON(bio_op(bio) == REQ_OP_WRITE);
...@@ -7980,7 +7981,7 @@ static int btrfs_check_dio_repairable(struct inode *inode, ...@@ -7980,7 +7981,7 @@ static int btrfs_check_dio_repairable(struct inode *inode,
return 1; return 1;
} }
static int dio_read_error(struct inode *inode, struct bio *failed_bio, static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio,
struct page *page, unsigned int pgoff, struct page *page, unsigned int pgoff,
u64 start, u64 end, int failed_mirror, u64 start, u64 end, int failed_mirror,
bio_end_io_t *repair_endio, void *repair_arg) bio_end_io_t *repair_endio, void *repair_arg)
...@@ -7993,18 +7994,19 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, ...@@ -7993,18 +7994,19 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
int read_mode = 0; int read_mode = 0;
int segs; int segs;
int ret; int ret;
blk_status_t status;
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); ret = btrfs_get_io_failure_record(inode, start, end, &failrec);
if (ret) if (ret)
return ret; return errno_to_blk_status(ret);
ret = btrfs_check_dio_repairable(inode, failed_bio, failrec, ret = btrfs_check_dio_repairable(inode, failed_bio, failrec,
failed_mirror); failed_mirror);
if (!ret) { if (!ret) {
free_io_failure(failure_tree, io_tree, failrec); free_io_failure(failure_tree, io_tree, failrec);
return -EIO; return BLK_STS_IOERR;
} }
segs = bio_segments(failed_bio); segs = bio_segments(failed_bio);
...@@ -8022,13 +8024,13 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, ...@@ -8022,13 +8024,13 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
"Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n", "Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n",
read_mode, failrec->this_mirror, failrec->in_validation); read_mode, failrec->this_mirror, failrec->in_validation);
ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror); status = submit_dio_repair_bio(inode, bio, failrec->this_mirror);
if (ret) { if (status) {
free_io_failure(failure_tree, io_tree, failrec); free_io_failure(failure_tree, io_tree, failrec);
bio_put(bio); bio_put(bio);
} }
return ret; return status;
} }
struct btrfs_retry_complete { struct btrfs_retry_complete {
...@@ -8065,7 +8067,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) ...@@ -8065,7 +8067,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
bio_put(bio); bio_put(bio);
} }
static int __btrfs_correct_data_nocsum(struct inode *inode, static blk_status_t __btrfs_correct_data_nocsum(struct inode *inode,
struct btrfs_io_bio *io_bio) struct btrfs_io_bio *io_bio)
{ {
struct btrfs_fs_info *fs_info; struct btrfs_fs_info *fs_info;
...@@ -8076,8 +8078,8 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, ...@@ -8076,8 +8078,8 @@ static int __btrfs_correct_data_nocsum(struct inode *inode,
unsigned int pgoff; unsigned int pgoff;
u32 sectorsize; u32 sectorsize;
int nr_sectors; int nr_sectors;
int ret; blk_status_t ret;
int err = 0; blk_status_t err = BLK_STS_OK;
fs_info = BTRFS_I(inode)->root->fs_info; fs_info = BTRFS_I(inode)->root->fs_info;
sectorsize = fs_info->sectorsize; sectorsize = fs_info->sectorsize;
...@@ -8183,11 +8185,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode, ...@@ -8183,11 +8185,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode,
int csum_pos; int csum_pos;
bool uptodate = (err == 0); bool uptodate = (err == 0);
int ret; int ret;
blk_status_t status;
fs_info = BTRFS_I(inode)->root->fs_info; fs_info = BTRFS_I(inode)->root->fs_info;
sectorsize = fs_info->sectorsize; sectorsize = fs_info->sectorsize;
err = 0; err = BLK_STS_OK;
start = io_bio->logical; start = io_bio->logical;
done.inode = inode; done.inode = inode;
io_bio->bio.bi_iter = io_bio->iter; io_bio->bio.bi_iter = io_bio->iter;
...@@ -8209,12 +8212,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode, ...@@ -8209,12 +8212,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode,
done.start = start; done.start = start;
init_completion(&done.done); init_completion(&done.done);
ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page, status = dio_read_error(inode, &io_bio->bio, bvec.bv_page,
pgoff, start, start + sectorsize - 1, pgoff, start, start + sectorsize - 1,
io_bio->mirror_num, io_bio->mirror_num, btrfs_retry_endio,
btrfs_retry_endio, &done); &done);
if (ret) { if (status) {
err = errno_to_blk_status(ret); err = status;
goto next; goto next;
} }
...@@ -8250,7 +8253,7 @@ static blk_status_t btrfs_subio_endio_read(struct inode *inode, ...@@ -8250,7 +8253,7 @@ static blk_status_t btrfs_subio_endio_read(struct inode *inode,
if (unlikely(err)) if (unlikely(err))
return __btrfs_correct_data_nocsum(inode, io_bio); return __btrfs_correct_data_nocsum(inode, io_bio);
else else
return 0; return BLK_STS_OK;
} else { } else {
return __btrfs_subio_endio_read(inode, io_bio, err); return __btrfs_subio_endio_read(inode, io_bio, err);
} }
...@@ -8423,9 +8426,9 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode, ...@@ -8423,9 +8426,9 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode,
return 0; return 0;
} }
static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, static inline blk_status_t
u64 file_offset, int skip_sum, __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset,
int async_submit) int skip_sum, int async_submit)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
struct btrfs_dio_private *dip = bio->bi_private; struct btrfs_dio_private *dip = bio->bi_private;
...@@ -8488,6 +8491,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, ...@@ -8488,6 +8491,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
int clone_offset = 0; int clone_offset = 0;
int clone_len; int clone_len;
int ret; int ret;
blk_status_t status;
map_length = orig_bio->bi_iter.bi_size; map_length = orig_bio->bi_iter.bi_size;
submit_len = map_length; submit_len = map_length;
...@@ -8537,9 +8541,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, ...@@ -8537,9 +8541,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
*/ */
atomic_inc(&dip->pending_bios); atomic_inc(&dip->pending_bios);
ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
async_submit); async_submit);
if (ret) { if (status) {
bio_put(bio); bio_put(bio);
atomic_dec(&dip->pending_bios); atomic_dec(&dip->pending_bios);
goto out_err; goto out_err;
...@@ -8557,9 +8561,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, ...@@ -8557,9 +8561,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
} while (submit_len > 0); } while (submit_len > 0);
submit: submit:
ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
async_submit); async_submit);
if (!ret) if (!status)
return 0; return 0;
bio_put(bio); bio_put(bio);
......
...@@ -905,7 +905,7 @@ static void raid_write_end_io(struct bio *bio) ...@@ -905,7 +905,7 @@ static void raid_write_end_io(struct bio *bio)
if (!atomic_dec_and_test(&rbio->stripes_pending)) if (!atomic_dec_and_test(&rbio->stripes_pending))
return; return;
err = 0; err = BLK_STS_OK;
/* OK, we have read all the stripes we need to. */ /* OK, we have read all the stripes we need to. */
max_errors = (rbio->operation == BTRFS_RBIO_PARITY_SCRUB) ? max_errors = (rbio->operation == BTRFS_RBIO_PARITY_SCRUB) ?
...@@ -1324,7 +1324,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1324,7 +1324,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
return; return;
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
} }
/* /*
...@@ -1475,7 +1475,7 @@ static void raid_rmw_end_io(struct bio *bio) ...@@ -1475,7 +1475,7 @@ static void raid_rmw_end_io(struct bio *bio)
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
} }
static void async_rmw_stripe(struct btrfs_raid_bio *rbio) static void async_rmw_stripe(struct btrfs_raid_bio *rbio)
...@@ -1579,7 +1579,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio) ...@@ -1579,7 +1579,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
return 0; return 0;
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
return -EIO; return -EIO;
finish: finish:
...@@ -1795,12 +1795,12 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) ...@@ -1795,12 +1795,12 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
void **pointers; void **pointers;
int faila = -1, failb = -1; int faila = -1, failb = -1;
struct page *page; struct page *page;
int err; blk_status_t err;
int i; int i;
pointers = kcalloc(rbio->real_stripes, sizeof(void *), GFP_NOFS); pointers = kcalloc(rbio->real_stripes, sizeof(void *), GFP_NOFS);
if (!pointers) { if (!pointers) {
err = -ENOMEM; err = BLK_STS_RESOURCE;
goto cleanup_io; goto cleanup_io;
} }
...@@ -1856,7 +1856,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) ...@@ -1856,7 +1856,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
* a bad data or Q stripe. * a bad data or Q stripe.
* TODO, we should redo the xor here. * TODO, we should redo the xor here.
*/ */
err = -EIO; err = BLK_STS_IOERR;
goto cleanup; goto cleanup;
} }
/* /*
...@@ -1882,7 +1882,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) ...@@ -1882,7 +1882,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
if (rbio->bbio->raid_map[failb] == RAID6_Q_STRIPE) { if (rbio->bbio->raid_map[failb] == RAID6_Q_STRIPE) {
if (rbio->bbio->raid_map[faila] == if (rbio->bbio->raid_map[faila] ==
RAID5_P_STRIPE) { RAID5_P_STRIPE) {
err = -EIO; err = BLK_STS_IOERR;
goto cleanup; goto cleanup;
} }
/* /*
...@@ -1954,13 +1954,13 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) ...@@ -1954,13 +1954,13 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
} }
} }
err = 0; err = BLK_STS_OK;
cleanup: cleanup:
kfree(pointers); kfree(pointers);
cleanup_io: cleanup_io:
if (rbio->operation == BTRFS_RBIO_READ_REBUILD) { if (rbio->operation == BTRFS_RBIO_READ_REBUILD) {
if (err == 0) if (err == BLK_STS_OK)
cache_rbio_pages(rbio); cache_rbio_pages(rbio);
else else
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags); clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
...@@ -1968,7 +1968,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) ...@@ -1968,7 +1968,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
rbio_orig_end_io(rbio, err); rbio_orig_end_io(rbio, err);
} else if (rbio->operation == BTRFS_RBIO_REBUILD_MISSING) { } else if (rbio->operation == BTRFS_RBIO_REBUILD_MISSING) {
rbio_orig_end_io(rbio, err); rbio_orig_end_io(rbio, err);
} else if (err == 0) { } else if (err == BLK_STS_OK) {
rbio->faila = -1; rbio->faila = -1;
rbio->failb = -1; rbio->failb = -1;
...@@ -2005,7 +2005,7 @@ static void raid_recover_end_io(struct bio *bio) ...@@ -2005,7 +2005,7 @@ static void raid_recover_end_io(struct bio *bio)
return; return;
if (atomic_read(&rbio->error) > rbio->bbio->max_errors) if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
else else
__raid_recover_end_io(rbio); __raid_recover_end_io(rbio);
} }
...@@ -2104,7 +2104,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) ...@@ -2104,7 +2104,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
cleanup: cleanup:
if (rbio->operation == BTRFS_RBIO_READ_REBUILD || if (rbio->operation == BTRFS_RBIO_READ_REBUILD ||
rbio->operation == BTRFS_RBIO_REBUILD_MISSING) rbio->operation == BTRFS_RBIO_REBUILD_MISSING)
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
return -EIO; return -EIO;
} }
...@@ -2431,7 +2431,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2431,7 +2431,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
nr_data = bio_list_size(&bio_list); nr_data = bio_list_size(&bio_list);
if (!nr_data) { if (!nr_data) {
/* Every parity is right */ /* Every parity is right */
rbio_orig_end_io(rbio, 0); rbio_orig_end_io(rbio, BLK_STS_OK);
return; return;
} }
...@@ -2451,7 +2451,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2451,7 +2451,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
return; return;
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
} }
static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe) static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
...@@ -2519,7 +2519,7 @@ static void validate_rbio_for_parity_scrub(struct btrfs_raid_bio *rbio) ...@@ -2519,7 +2519,7 @@ static void validate_rbio_for_parity_scrub(struct btrfs_raid_bio *rbio)
return; return;
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
} }
/* /*
...@@ -2633,7 +2633,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) ...@@ -2633,7 +2633,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
return; return;
cleanup: cleanup:
rbio_orig_end_io(rbio, -EIO); rbio_orig_end_io(rbio, BLK_STS_IOERR);
return; return;
finish: finish:
......
...@@ -6212,7 +6212,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) ...@@ -6212,7 +6212,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
} }
} }
int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
int mirror_num, int async_submit) int mirror_num, int async_submit)
{ {
struct btrfs_device *dev; struct btrfs_device *dev;
...@@ -6233,7 +6233,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6233,7 +6233,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
&map_length, &bbio, mirror_num, 1); &map_length, &bbio, mirror_num, 1);
if (ret) { if (ret) {
btrfs_bio_counter_dec(fs_info); btrfs_bio_counter_dec(fs_info);
return ret; return errno_to_blk_status(ret);
} }
total_devs = bbio->num_stripes; total_devs = bbio->num_stripes;
...@@ -6256,7 +6256,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6256,7 +6256,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
} }
btrfs_bio_counter_dec(fs_info); btrfs_bio_counter_dec(fs_info);
return ret; return errno_to_blk_status(ret);
} }
if (map_length < length) { if (map_length < length) {
...@@ -6283,7 +6283,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6283,7 +6283,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
dev_nr, async_submit); dev_nr, async_submit);
} }
btrfs_bio_counter_dec(fs_info); btrfs_bio_counter_dec(fs_info);
return 0; return BLK_STS_OK;
} }
struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid, struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
......
...@@ -74,7 +74,7 @@ struct btrfs_device { ...@@ -74,7 +74,7 @@ struct btrfs_device {
int missing; int missing;
int can_discard; int can_discard;
int is_tgtdev_for_dev_replace; int is_tgtdev_for_dev_replace;
int last_flush_error; blk_status_t last_flush_error;
int flush_bio_sent; int flush_bio_sent;
#ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED
...@@ -416,7 +416,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -416,7 +416,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 type); struct btrfs_fs_info *fs_info, u64 type);
void btrfs_mapping_init(struct btrfs_mapping_tree *tree); void btrfs_mapping_init(struct btrfs_mapping_tree *tree);
void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree); void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree);
int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
int mirror_num, int async_submit); int mirror_num, int async_submit);
int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
fmode_t flags, void *holder); fmode_t flags, void *holder);
......
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