Skip to content

Commit

Permalink
zvol: Implement zvol threading as a Property
Browse files Browse the repository at this point in the history
Currently, zvol threading can be switched through the zvol_request_sync
module parameter system-wide. By making it a zvol property, zvol
threading can be switched per zvol.

Signed-off-by: Ameer Hamza <[email protected]>
  • Loading branch information
ixhamza committed Oct 16, 2023
1 parent 7c87584 commit 07d39f8
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ typedef enum {
ZFS_PROP_REDACTED,
ZFS_PROP_REDACT_SNAPS,
ZFS_PROP_SNAPSHOTS_CHANGED,
ZFS_PROP_VOLTHREADING,
ZFS_NUM_PROPS
} zfs_prop_t;

Expand Down
1 change: 1 addition & 0 deletions include/sys/zvol.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern int zvol_get_stats(objset_t *, nvlist_t *);
extern boolean_t zvol_is_zvol(const char *);
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 *, uint64_t);
extern int zvol_set_common(const char *, zprop_source_t, uint64_t, zfs_prop_t);
extern zvol_state_handle_t *zvol_suspend(const char *);
extern int zvol_resume(zvol_state_handle_t *);
Expand Down
1 change: 1 addition & 0 deletions include/sys/zvol_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ typedef struct zvol_state {
atomic_t zv_suspend_ref; /* refcount for suspend */
krwlock_t zv_suspend_lock; /* suspend lock */
struct zvol_state_os *zv_zso; /* private platform state */
uint32_t zv_threading; /* volthreading property */
} zvol_state_t;


Expand Down
3 changes: 2 additions & 1 deletion lib/libzfs/libzfs.abi
Original file line number Diff line number Diff line change
Expand Up @@ -1863,7 +1863,8 @@
<enumerator name='ZFS_PROP_REDACTED' value='93'/>
<enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/>
<enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
<enumerator name='ZFS_NUM_PROPS' value='96'/>
<enumerator name='ZFS_PROP_VOLTHREADING' value='96'/>
<enumerator name='ZFS_NUM_PROPS' value='97'/>
</enum-decl>
<typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/>
<enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'>
Expand Down
12 changes: 12 additions & 0 deletions man/man7/zfsprops.7
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,18 @@ are equivalent to the
and
.Sy noexec
mount options.
.It Sy volthreading Ns = Ns Sy on Ns | Ns Sy off
Controls internal zvol threading.
The value
.Sy off
Disables zvol threading, and zvol relies on application threads.
The default value is
.Sy on ,
which enables threading within a zvol.
Please note that this property will be overridden by
.Sy zvol_request_sync
module parameter.
This property is only applicable to Linux.
.It Sy filesystem_limit Ns = Ns Ar count Ns | Ns Sy none
Limits the number of filesystems and volumes that can exist under this point in
the dataset tree.
Expand Down
5 changes: 4 additions & 1 deletion module/os/linux/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
uint64_t size = io_size(bio, rq);
int rw = io_data_dir(bio, rq);

if (zvol_request_sync)
if (zvol_request_sync || zv->zv_threading == 0)
force_sync = 1;

zv_request_t zvr = {
Expand Down Expand Up @@ -1298,6 +1298,7 @@ zvol_os_create_minor(const char *name)
int error = 0;
int idx;
uint64_t hash = zvol_name_hash(name);
uint64_t volthreading;
bool replayed_zil = B_FALSE;

if (zvol_inhibit_dev)
Expand Down Expand Up @@ -1343,6 +1344,8 @@ zvol_os_create_minor(const char *name)
zv->zv_volblocksize = doi->doi_data_block_size;
zv->zv_volsize = volsize;
zv->zv_objset = os;
if (!dsl_prop_get_integer(name, "volthreading", &volthreading, NULL))
zv->zv_threading = volthreading;

set_capacity(zv->zv_zso->zvo_disk, zv->zv_volsize >> 9);

Expand Down
3 changes: 3 additions & 0 deletions module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@ zfs_prop_init(void)
ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK", B_FALSE,
sfeatures);
zprop_register_index(ZFS_PROP_VOLTHREADING, "volthreading",
1, PROP_DEFAULT, ZFS_TYPE_VOLUME, "on | off", "zvol threading",
boolean_table, sfeatures);
zprop_register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0,
PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
"USEDSNAP", B_FALSE, sfeatures);
Expand Down
3 changes: 3 additions & 0 deletions module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,9 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
case ZFS_PROP_VOLSIZE:
err = zvol_set_volsize(dsname, intval);
break;
case ZFS_PROP_VOLTHREADING:
err = zvol_set_volthreading(dsname, intval);
break;
case ZFS_PROP_SNAPDEV:
err = zvol_set_common(dsname, source, intval, ZFS_PROP_SNAPDEV);
break;
Expand Down
15 changes: 15 additions & 0 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,21 @@ zvol_set_volsize(const char *name, uint64_t volsize)
return (SET_ERROR(error));
}

/*
* Update volthreading.
*/
int
zvol_set_volthreading(const char *name, uint64_t value)
{
zvol_state_t *zv = zvol_find_by_name(name, RW_NONE);
if (zv) {
zv->zv_threading = value;
mutex_exit(&zv->zv_state_lock);
return (0);
}
return (ENOENT);
}

/*
* Sanity check volume block size.
*/
Expand Down

0 comments on commit 07d39f8

Please sign in to comment.