From 510560c66f1a1b8156433db5dda2d331a6524f5a Mon Sep 17 00:00:00 2001 From: Ameer Hamza Date: Wed, 18 Oct 2023 00:19:58 +0500 Subject: [PATCH] zvol: fix delayed update to block device ro entry The change in the zvol readonly property does not update the block device readonly entry until the first IO to the ZVOL. This patch addresses the issue by updating the block device readonly property from the set property IOCTL call. Signed-off-by: Ameer Hamza --- include/sys/zvol.h | 1 + module/zfs/zfs_ioctl.c | 9 +++++++++ module/zfs/zvol.c | 20 ++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/include/sys/zvol.h b/include/sys/zvol.h index c9eefbeb48..c79fe1d9ad 100644 --- a/include/sys/zvol.h +++ b/include/sys/zvol.h @@ -52,6 +52,7 @@ extern void zvol_create_cb(objset_t *, void *, cred_t *, dmu_tx_t *); extern int zvol_set_volsize(const char *, uint64_t); extern int zvol_set_volthreading(const char *, boolean_t); extern int zvol_set_common(const char *, zfs_prop_t, zprop_source_t, uint64_t); +extern int zvol_set_ro(const char *, boolean_t); extern zvol_state_handle_t *zvol_suspend(const char *); extern int zvol_resume(zvol_state_handle_t *); extern void *zvol_tag(zvol_state_handle_t *); diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 72d5fc8192..01e16e102f 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -2536,6 +2536,15 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, case ZFS_PROP_VOLMODE: err = zvol_set_common(dsname, prop, source, intval); break; + case ZFS_PROP_READONLY: + err = zvol_set_ro(dsname, intval); + /* + * Set err to -1 to force the zfs_set_prop_nvlist code down the + * default path to set the value in the nvlist. + */ + if (err == 0) + err = -1; + break; case ZFS_PROP_VERSION: { zfsvfs_t *zfsvfs; diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index c576e34696..e661c55d18 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -383,6 +383,26 @@ zvol_set_volthreading(const char *name, boolean_t value) return (0); } +/* + * Update zvol ro property. + */ +int +zvol_set_ro(const char *name, boolean_t value) +{ + zvol_state_t *zv = zvol_find_by_name(name, RW_NONE); + if (zv == NULL) + return (-1); + if (value) { + zvol_os_set_disk_ro(zv, 1); + zv->zv_flags |= ZVOL_RDONLY; + } else { + zvol_os_set_disk_ro(zv, 0); + zv->zv_flags &= ~ZVOL_RDONLY; + } + mutex_exit(&zv->zv_state_lock); + return (0); +} + /* * Sanity check volume block size. */