zvol: cleanup error handling and passthrough

This is trying to get all the uses and non-uses of SET_ERROR correct
(being: only call it if we're the originator of an error _within ZFS_),
and correctly negating errors going to/from the kernel. And/or both.

Sponsored-by: Klara, Inc.
Sponsored-by: Railway Corporation
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17605
This commit is contained in:
Rob Norris
2025-08-09 10:04:01 +10:00
committed by GitHub
parent 90a1e13df2
commit 2fd145b578
2 changed files with 42 additions and 40 deletions
+18 -13
View File
@@ -84,8 +84,9 @@ static unsigned int zvol_blk_mq_blocks_per_thread = 8;
static inline void
zvol_end_io(struct bio *bio, struct request *rq, int error)
{
ASSERT3U(error, >=, 0);
if (bio) {
bio->bi_status = errno_to_bi_status(-error);
bio->bi_status = errno_to_bi_status(error);
bio_endio(bio);
} else {
blk_mq_end_request(rq, errno_to_bi_status(error));
@@ -288,7 +289,7 @@ zvol_write(zv_request_t *zvr)
blk_generic_end_io_acct(q, disk, WRITE, bio, start_time);
}
zvol_end_io(bio, rq, -error);
zvol_end_io(bio, rq, error);
}
static void
@@ -377,7 +378,7 @@ unlock:
start_time);
}
zvol_end_io(bio, rq, -error);
zvol_end_io(bio, rq, error);
}
static void
@@ -455,7 +456,7 @@ zvol_read(zv_request_t *zvr)
blk_generic_end_io_acct(q, disk, READ, bio, start_time);
}
zvol_end_io(bio, rq, -error);
zvol_end_io(bio, rq, error);
}
static void
@@ -486,7 +487,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
int rw = io_data_dir(bio, rq);
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) {
zvol_end_io(bio, rq, -SET_ERROR(ENXIO));
zvol_end_io(bio, rq, SET_ERROR(ENXIO));
goto out;
}
@@ -505,7 +506,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
(long long unsigned)offset,
(long unsigned)size);
zvol_end_io(bio, rq, -SET_ERROR(EIO));
zvol_end_io(bio, rq, SET_ERROR(EIO));
goto out;
}
@@ -527,7 +528,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
if (rw == WRITE) {
if (unlikely(zv->zv_flags & ZVOL_RDONLY)) {
zvol_end_io(bio, rq, -SET_ERROR(EROFS));
zvol_end_io(bio, rq, SET_ERROR(EROFS));
goto out;
}
@@ -892,16 +893,18 @@ zvol_ioctl(struct block_device *bdev, fmode_t mode,
case BLKZNAME:
mutex_enter(&zv->zv_state_lock);
error = copy_to_user((void *)arg, zv->zv_name, MAXNAMELEN);
error = -copy_to_user((void *)arg, zv->zv_name, MAXNAMELEN);
mutex_exit(&zv->zv_state_lock);
if (error)
error = SET_ERROR(error);
break;
default:
error = -ENOTTY;
error = SET_ERROR(ENOTTY);
break;
}
return (SET_ERROR(error));
return (-error);
}
#ifdef CONFIG_COMPAT
@@ -1480,7 +1483,9 @@ __zvol_os_add_disk(struct gendisk *disk)
{
int error = 0;
#ifdef HAVE_ADD_DISK_RET
error = add_disk(disk);
error = -add_disk(disk);
if (error)
error = SET_ERROR(error);
#else
add_disk(disk);
#endif
@@ -1765,10 +1770,10 @@ zvol_init(void)
return (error);
}
error = register_blkdev(zvol_major, ZVOL_DRIVER);
error = -register_blkdev(zvol_major, ZVOL_DRIVER);
if (error) {
printk(KERN_INFO "ZFS: register_blkdev() failed %d\n", error);
return (error);
return (SET_ERROR(error));
}
if (zvol_blk_mq_queue_depth == 0) {