]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Prevent panic during concurrent snapshot rollback and zvol read
authorAmeer Hamza <ahamza@ixsystems.com>
Wed, 10 May 2023 00:56:35 +0000 (05:56 +0500)
committerGitHub <noreply@github.com>
Wed, 10 May 2023 00:56:35 +0000 (17:56 -0700)
Protect zvol_cdev_read with zv_suspend_lock to prevent concurrent
release of the dnode, avoiding panic when a snapshot is rolled back
in parallel during ongoing zvol read operation.

Reviewed-by: Chunwei Chen <tuxoko@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #14839

module/os/freebsd/zfs/zvol_os.c

index 26578491fd67392678aadae6010b0fcae228ced6..2520507b98aad79fa254cb72dc096853d9936d03 100644 (file)
@@ -832,6 +832,7 @@ zvol_cdev_read(struct cdev *dev, struct uio *uio_s, int ioflag)
            (zfs_uio_offset(&uio) < 0 || zfs_uio_offset(&uio) > volsize))
                return (SET_ERROR(EIO));
 
+       rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
        ssize_t start_resid = zfs_uio_resid(&uio);
        lr = zfs_rangelock_enter(&zv->zv_rangelock, zfs_uio_offset(&uio),
            zfs_uio_resid(&uio), RL_READER);
@@ -853,6 +854,7 @@ zvol_cdev_read(struct cdev *dev, struct uio *uio_s, int ioflag)
        zfs_rangelock_exit(lr);
        int64_t nread = start_resid - zfs_uio_resid(&uio);
        dataset_kstats_update_read_kstats(&zv->zv_kstat, nread);
+       rw_exit(&zv->zv_suspend_lock);
 
        return (error);
 }