Skip to content

Commit

Permalink
zvol: fix delayed update to block device ro entry
Browse files Browse the repository at this point in the history
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 <ahamza@ixsystems.com>
  • Loading branch information
ixhamza committed Dec 11, 2023
1 parent 1438208 commit 510560c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/sys/zvol.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
9 changes: 9 additions & 0 deletions module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down

0 comments on commit 510560c

Please sign in to comment.