]> git.proxmox.com Git - mirror_zfs.git/commitdiff
zvol: Implement zvol threading as a Property
authorAmeer Hamza <ahamza@ixsystems.com>
Tue, 24 Oct 2023 21:53:27 +0000 (02:53 +0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 Oct 2023 16:50:32 +0000 (09:50 -0700)
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.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #15409

include/sys/fs/zfs.h
include/sys/zvol.h
include/sys/zvol_impl.h
lib/libzfs/libzfs.abi
man/man7/zfsprops.7
module/os/linux/zfs/zvol_os.c
module/zcommon/zfs_prop.c
module/zfs/zfs_ioctl.c
module/zfs/zvol.c

index 9d7eca9784b60aa791cc8b1175d7fca83d9cb778..a978a9db5075d85349b1d11a11437f305e896eb4 100644 (file)
@@ -192,6 +192,7 @@ typedef enum {
        ZFS_PROP_REDACT_SNAPS,
        ZFS_PROP_SNAPSHOTS_CHANGED,
        ZFS_PROP_PREFETCH,
+       ZFS_PROP_VOLTHREADING,
        ZFS_NUM_PROPS
 } zfs_prop_t;
 
index 5e92a3367b9fa14d9d70e2b0b99ab85bb7fc175c..c9eefbeb48d932e0c3f0f56fc93937213014d749 100644 (file)
@@ -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 *, boolean_t);
 extern int zvol_set_common(const char *, zfs_prop_t, zprop_source_t, uint64_t);
 extern zvol_state_handle_t *zvol_suspend(const char *);
 extern int zvol_resume(zvol_state_handle_t *);
index 8103208622d48437587300a16decb8d909102fe4..6c15c84b6bf41b7826881d3121b4f6b6fdcf30ab 100644 (file)
@@ -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 */
+       boolean_t               zv_threading;   /* volthreading property */
 } zvol_state_t;
 
 
index 083c27be7d31c111ed0c50a5af75fc443ffc4b90..f8b0d395161bd61471263dc4f3ac7946b1f73011 100644 (file)
       <enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/>
       <enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
       <enumerator name='ZFS_PROP_PREFETCH' value='96'/>
-      <enumerator name='ZFS_NUM_PROPS' value='97'/>
+      <enumerator name='ZFS_PROP_VOLTHREADING' value='97'/>
+      <enumerator name='ZFS_NUM_PROPS' value='98'/>
     </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'>
index 59f6404379afd5e81dcfc0b018219ec91ce2ebc6..9ff0236f4d74fd7d071b7b0615ba6d6c7d7a1375 100644 (file)
@@ -1197,6 +1197,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.
index 3dc0bb38836b6ec409e641488f48a9d00eeca20b..fd0fd2c36dcd686911ed85505a20393a018dd55b 100644 (file)
@@ -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 == B_FALSE)
                force_sync = 1;
 
        zv_request_t zvr = {
@@ -1304,6 +1304,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)
@@ -1350,6 +1351,12 @@ zvol_os_create_minor(const char *name)
        zv->zv_volsize = volsize;
        zv->zv_objset = os;
 
+       /* Default */
+       zv->zv_threading = B_TRUE;
+       if (dsl_prop_get_integer(name, "volthreading", &volthreading, NULL)
+           == 0)
+               zv->zv_threading = volthreading;
+
        set_capacity(zv->zv_zso->zvo_disk, zv->zv_volsize >> 9);
 
        blk_queue_max_hw_sectors(zv->zv_zso->zvo_queue,
index 29764674a31b9454ab02ed6dbc5042c3de69492a..764993b45e7c1996867e5d159e7bf7c0653094b0 100644 (file)
@@ -628,6 +628,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);
index d535d9031b98eeb466065834db2582e483f01db0..c4e99b34a1e2f90ee88c85393ba857b71fcab098 100644 (file)
@@ -2522,6 +2522,15 @@ 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);
+               /*
+                * 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_SNAPDEV:
        case ZFS_PROP_VOLMODE:
                err = zvol_set_common(dsname, prop, source, intval);
index eb20d982869a84443c3f27bcf7f79e4f84bc9e88..d5f0693992a37a644b1bb3ef9f7ea00f1ec83a84 100644 (file)
@@ -369,6 +369,20 @@ out:
        return (SET_ERROR(error));
 }
 
+/*
+ * Update volthreading.
+ */
+int
+zvol_set_volthreading(const char *name, boolean_t value)
+{
+       zvol_state_t *zv = zvol_find_by_name(name, RW_NONE);
+       if (zv == NULL)
+               return (ENOENT);
+       zv->zv_threading = value;
+       mutex_exit(&zv->zv_state_lock);
+       return (0);
+}
+
 /*
  * Sanity check volume block size.
  */