From 9ccdb8becdc6a50c389958877aa76ff12a8955d2 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. Reviewed-by: Tony Hutter Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: Ameer Hamza Closes #15409 --- 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 c4e99b34a1..b2b06881bd 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -2535,6 +2535,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 d5f0693992..c7e10fbc63 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. */