Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160956995
D23478.id67695.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D23478.id67695.diff
View Options
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
@@ -1026,6 +1026,9 @@
doca->doca_cred, tx);
}
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ zvol_create_minors(dp->dp_spa, doca->doca_name);
+#endif
spa_history_log_internal_ds(ds, "create", tx, "");
dsl_dataset_rele(ds, FTAG);
dsl_dir_rele(pdd, FTAG);
@@ -1121,6 +1124,9 @@
VERIFY0(dsl_dataset_hold_obj(pdd->dd_pool, obj, FTAG, &ds));
dsl_dataset_name(origin, namebuf);
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ zvol_create_minors(dp->dp_spa, doca->doca_clone);
+#endif
spa_history_log_internal_ds(ds, "clone", tx,
"origin=%s (%llu)", namebuf, origin->ds_object);
dsl_dataset_rele(ds, FTAG);
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -56,6 +56,9 @@
#include <sys/dsl_bookmark.h>
#include <sys/zfeature.h>
#include <sys/bqueue.h>
+#ifdef __FreeBSD__
+#include <sys/zvol.h>
+#endif
#ifdef __FreeBSD__
#undef dump_write
@@ -3421,6 +3424,11 @@
drc->drc_newsnapobj =
dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
}
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ zvol_create_minors(dp->dp_spa, drc->drc_tofs);
+#endif
+
/*
* Release the hold from dmu_recv_begin. This must be done before
* we return to open context, so that when we free the dataset's dnode,
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -1546,6 +1546,14 @@
dsl_dir_snap_cmtime_update(ds->ds_dir);
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ char fullname[ZFS_MAX_DATASET_NAME_LEN];
+
+ dsl_dataset_name(ds, fullname);
+ strlcat(fullname, "@", sizeof(fullname));
+ strlcat(fullname, snapname, sizeof(fullname));
+ zvol_create_minors(dp->dp_spa, fullname);
+#endif
spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, "");
}
@@ -1646,17 +1654,6 @@
fnvlist_free(suspended);
}
-#ifdef __FreeBSD__
-#ifdef _KERNEL
- if (error == 0) {
- for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
- pair = nvlist_next_nvpair(snaps, pair)) {
- char *snapname = nvpair_name(pair);
- zvol_create_minors(snapname);
- }
- }
-#endif
-#endif
return (error);
}
@@ -2528,16 +2525,16 @@
#ifdef __FreeBSD__
#ifdef _KERNEL
- oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
- newname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
- snprintf(oldname, MAXPATHLEN, "%s@%s", ddrsa->ddrsa_fsname,
- ddrsa->ddrsa_oldsnapname);
- snprintf(newname, MAXPATHLEN, "%s@%s", ddrsa->ddrsa_fsname,
- ddrsa->ddrsa_newsnapname);
+ oldname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ newname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ snprintf(oldname, ZFS_MAX_DATASET_NAME_LEN, "%s@%s",
+ ddrsa->ddrsa_fsname, ddrsa->ddrsa_oldsnapname);
+ snprintf(newname, ZFS_MAX_DATASET_NAME_LEN, "%s@%s",
+ ddrsa->ddrsa_fsname, ddrsa->ddrsa_newsnapname);
zfsvfs_update_fromname(oldname, newname);
- zvol_rename_minors(oldname, newname);
- kmem_free(newname, MAXPATHLEN);
- kmem_free(oldname, MAXPATHLEN);
+ zvol_rename_minors(dp->dp_spa, oldname, newname);
+ kmem_free(newname, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(oldname, ZFS_MAX_DATASET_NAME_LEN);
#endif
#endif
dsl_dataset_rele(ds, FTAG);
@@ -3087,11 +3084,8 @@
}
#if defined(__FreeBSD__) && defined(_KERNEL)
- /* Take the spa_namespace_lock early so zvol renames don't deadlock. */
- mutex_enter(&spa_namespace_lock);
-
- oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
- newname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+ oldname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ newname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
#endif
/* move snapshots to this dir */
@@ -3109,6 +3103,10 @@
ds->ds_objset = NULL;
}
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ dsl_dataset_name(ds, oldname);
+#endif
+
/* move snap name entry */
VERIFY0(dsl_dataset_get_snapname(ds));
VERIFY0(dsl_dataset_snap_remove(origin_head,
@@ -3131,7 +3129,7 @@
#if defined(__FreeBSD__) && defined(_KERNEL)
dsl_dataset_name(ds, newname);
zfsvfs_update_fromname(oldname, newname);
- zvol_rename_minors(oldname, newname);
+ zvol_rename_minors(dp->dp_spa, oldname, newname);
#endif
/* move any clone references */
@@ -3173,10 +3171,8 @@
}
#if defined(__FreeBSD__) && defined(_KERNEL)
- mutex_exit(&spa_namespace_lock);
-
- kmem_free(newname, MAXPATHLEN);
- kmem_free(oldname, MAXPATHLEN);
+ kmem_free(newname, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(oldname, ZFS_MAX_DATASET_NAME_LEN);
#endif
/*
* Change space accounting.
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
@@ -43,7 +43,11 @@
#include <sys/dsl_deleg.h>
#include <sys/dmu_impl.h>
#include <sys/zcp.h>
+#if defined(__FreeBSD__) && defined(_KERNEL)
+#include <sys/zvol.h>
+#endif
+
int
dsl_destroy_snapshot_check_impl(dsl_dataset_t *ds, boolean_t defer)
{
@@ -489,6 +493,14 @@
if (dsl_dataset_phys(ds)->ds_userrefs_obj != 0)
VERIFY0(zap_destroy(mos, dsl_dataset_phys(ds)->ds_userrefs_obj,
tx));
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ char dsname[ZFS_MAX_DATASET_NAME_LEN];
+
+ dsl_dataset_name(ds, dsname);
+ zvol_remove_minors(dp->dp_spa, dsname);
+#endif
+
dsl_dir_rele(ds->ds_dir, ds);
ds->ds_dir = NULL;
dmu_object_free_zapified(mos, obj, tx);
@@ -979,6 +991,9 @@
VERIFY0(dsl_dataset_hold(dp, ddha->ddha_name, FTAG, &ds));
dsl_destroy_head_sync_impl(ds, tx);
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ zvol_remove_minors(dp->dp_spa, ddha->ddha_name);
+#endif
dsl_dataset_rele(ds, FTAG);
}
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
@@ -2067,7 +2067,7 @@
#ifdef __FreeBSD__
#ifdef _KERNEL
zfsvfs_update_fromname(ddra->ddra_oldname, ddra->ddra_newname);
- zvol_rename_minors(ddra->ddra_oldname, ddra->ddra_newname);
+ zvol_rename_minors(dp->dp_spa, ddra->ddra_oldname, ddra->ddra_newname);
#endif
#endif
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -32,6 +32,7 @@
* Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2017 Datto Inc.
* Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
*/
/*
@@ -1280,6 +1281,24 @@
*/
trim_thread_create(spa);
+ /*
+ * This taskq is used to perform zvol-minor-related tasks
+ * asynchronously. This has several advantages, including easy
+ * resolution of various deadlocks (zfsonlinux bug #3681).
+ *
+ * The taskq must be single threaded to ensure tasks are always
+ * processed in the order in which they were dispatched.
+ *
+ * A taskq per pool allows one to keep the pools independent.
+ * This way if one pool is suspended, it will not impact another.
+ *
+ * The preferred location to dispatch a zvol minor task is a sync
+ * task. In this context, there is easy access to the spa_t and minimal
+ * error handling is required because the sync task must succeed.
+ */
+ spa->spa_zvol_taskq = taskq_create("z_zvol", 1, minclsyspri,
+ 1, INT_MAX, 0);
+
for (size_t i = 0; i < TXG_SIZE; i++) {
spa->spa_txg_zio[i] = zio_root(spa, NULL, NULL,
ZIO_FLAG_CANFAIL);
@@ -1323,6 +1342,11 @@
spa_evicting_os_wait(spa);
+ if (spa->spa_zvol_taskq) {
+ taskq_destroy(spa->spa_zvol_taskq);
+ spa->spa_zvol_taskq = NULL;
+ }
+
txg_list_destroy(&spa->spa_vdev_txg_list);
list_destroy(&spa->spa_config_dirty_list);
@@ -4614,7 +4638,7 @@
#ifdef __FreeBSD__
#ifdef _KERNEL
if (firstopen)
- zvol_create_minors(spa->spa_name);
+ zvol_create_minors(spa, spa->spa_name);
#endif
#endif
}
@@ -5970,7 +5994,7 @@
#ifdef __FreeBSD__
#ifdef _KERNEL
- zvol_create_minors(pool);
+ zvol_create_minors(spa, pool);
#endif
#endif
return (0);
@@ -6119,6 +6143,10 @@
spa_open_ref(spa, FTAG);
mutex_exit(&spa_namespace_lock);
spa_async_suspend(spa);
+ if (spa->spa_zvol_taskq) {
+ zvol_remove_minors(spa, spa_name(spa));
+ taskq_wait(spa->spa_zvol_taskq);
+ }
mutex_enter(&spa_namespace_lock);
spa_close(spa, FTAG);
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
@@ -27,6 +27,7 @@
* Copyright 2013 Saso Kiselkov. All rights reserved.
* Copyright (c) 2017 Datto Inc.
* Copyright (c) 2017, Intel Corporation.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
*/
#ifndef _SYS_SPA_IMPL_H
@@ -398,6 +399,8 @@
uint64_t spa_lowmem_last_txg; /* txg window start */
hrtime_t spa_ccw_fail_time; /* Conf cache write fail time */
+
+ taskq_t *spa_zvol_taskq; /* Taskq for minor management */
uint64_t spa_multihost; /* multihost aware (mmp) */
mmp_thread_t spa_mmp; /* multihost mmp thread */
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
*/
#ifndef _SYS_ZVOL_H
@@ -40,9 +41,6 @@
extern int zvol_check_volblocksize(uint64_t volblocksize);
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
-extern int zvol_create_minor(const char *);
-extern int zvol_remove_minor(const char *);
-extern void zvol_remove_minors(const char *);
extern int zvol_set_volsize(const char *, uint64_t);
#ifdef illumos
@@ -72,8 +70,10 @@
#endif /* illumos */
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-extern int zvol_create_minors(const char *name);
-extern void zvol_rename_minors(const char *oldname, const char *newname);
+extern void zvol_create_minors(spa_t *spa, const char *name);
+extern void zvol_remove_minors(spa_t *spa, const char *name);
+extern void zvol_rename_minors(spa_t *spa, const char *oldname,
+ const char *newname);
#endif
#endif /* _KERNEL */
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -1641,8 +1641,10 @@
int error;
zfs_log_history(zc);
error = spa_destroy(zc->zc_name);
+#ifndef __FreeBSD__
if (error == 0)
zvol_remove_minors(zc->zc_name);
+#endif
return (error);
}
@@ -1693,8 +1695,10 @@
zfs_log_history(zc);
error = spa_export(zc->zc_name, NULL, force, hardforce);
+#ifndef __FreeBSD__
if (error == 0)
zvol_remove_minors(zc->zc_name);
+#endif
return (error);
}
@@ -3397,13 +3401,23 @@
if (error == 0) {
error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
nvprops, outnvl);
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ /*
+ * Wait for ZVOL operations to settle down before destroying.
+ */
+ if (error != 0) {
+ spa_t *spa;
+
+ if (spa_open(fsname, &spa, FTAG) == 0) {
+ taskqueue_drain_all(
+ spa->spa_zvol_taskq->tq_queue);
+ spa_close(spa, FTAG);
+ }
+ }
+#endif
if (error != 0)
(void) dsl_destroy_head(fsname);
}
-#ifdef __FreeBSD__
- if (error == 0 && type == DMU_OST_ZVOL)
- zvol_create_minors(fsname);
-#endif
return (error);
}
@@ -3445,10 +3459,6 @@
if (error != 0)
(void) dsl_destroy_head(fsname);
}
-#ifdef __FreeBSD__
- if (error == 0)
- zvol_create_minors(fsname);
-#endif
return (error);
}
@@ -3740,9 +3750,6 @@
return (SET_ERROR(EXDEV));
zfs_unmount_snap(nvpair_name(pair));
-#if defined(__FreeBSD__)
- zvol_remove_minors(name);
-#endif
}
return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl));
@@ -3926,10 +3933,8 @@
err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
else
err = dsl_destroy_head(zc->zc_name);
+#ifndef __FreeBSD__
if (ost == DMU_OST_ZVOL && err == 0)
-#ifdef __FreeBSD__
- zvol_remove_minors(zc->zc_name);
-#else
(void) zvol_remove_minor(zc->zc_name);
#endif
return (err);
@@ -4824,11 +4829,6 @@
}
#endif
-#ifdef __FreeBSD__
- if (error == 0)
- zvol_create_minors(tofs);
-#endif
-
/*
* On error, restore the original props.
*/
@@ -6970,6 +6970,24 @@
out:
nvlist_free(innvl);
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ /*
+ * Wait for ZVOL changes to get applied.
+ * NB: taskqueue_drain_all() does less than taskq_wait(),
+ * but enough for what we want.
+ * And there is no equivalent illumos API.
+ */
+ if (error == 0) {
+ spa_t *spa;
+
+ if (spa_open(saved_poolname, &spa, FTAG) == 0) {
+ taskqueue_drain_all(
+ spa->spa_zvol_taskq->tq_queue);
+ spa_close(spa, FTAG);
+ }
+ }
+#endif
#ifdef illumos
rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -30,6 +30,7 @@
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
*/
/* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org> */
@@ -184,6 +185,20 @@
#endif
} zvol_state_t;
+typedef enum {
+ ZVOL_ASYNC_CREATE_MINORS,
+ ZVOL_ASYNC_REMOVE_MINORS,
+ ZVOL_ASYNC_RENAME_MINORS,
+ ZVOL_ASYNC_MAX
+} zvol_async_op_t;
+
+typedef struct {
+ zvol_async_op_t op;
+ char pool[ZFS_MAX_DATASET_NAME_LEN];
+ char name1[ZFS_MAX_DATASET_NAME_LEN];
+ char name2[ZFS_MAX_DATASET_NAME_LEN];
+} zvol_task_t;
+
#ifndef illumos
static LIST_HEAD(, zvol_state) all_zvols;
#endif
@@ -606,7 +621,7 @@
/*
* Create a minor node (plus a whole lot more) for the specified volume.
*/
-int
+static int
zvol_create_minor(const char *name)
{
zfs_soft_state_t *zs;
@@ -690,7 +705,6 @@
if (error != 0 || mode == ZFS_VOLMODE_DEFAULT)
mode = volmode;
- DROP_GIANT();
zv->zv_volmode = mode;
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
g_topology_lock();
@@ -765,7 +779,6 @@
zvol_geom_run(zv);
g_topology_unlock();
}
- PICKUP_GIANT();
ZFS_LOG(1, "ZVOL %s created.", name);
#endif
@@ -819,22 +832,6 @@
}
int
-zvol_remove_minor(const char *name)
-{
- zvol_state_t *zv;
- int rc;
-
- mutex_enter(&zfsdev_state_lock);
- if ((zv = zvol_minor_lookup(name)) == NULL) {
- mutex_exit(&zfsdev_state_lock);
- return (SET_ERROR(ENXIO));
- }
- rc = zvol_remove_zv(zv);
- mutex_exit(&zfsdev_state_lock);
- return (rc);
-}
-
-int
zvol_first_open(zvol_state_t *zv)
{
dmu_object_info_t doi;
@@ -975,7 +972,7 @@
}
void
-zvol_remove_minors(const char *name)
+zvol_remove_minors_impl(const char *name)
{
#ifdef illumos
zvol_state_t *zv;
@@ -1003,7 +1000,6 @@
namelen = strlen(name);
- DROP_GIANT();
mutex_enter(&zfsdev_state_lock);
LIST_FOREACH_SAFE(zv, &all_zvols, zv_links, tzv) {
@@ -1016,7 +1012,6 @@
}
mutex_exit(&zfsdev_state_lock);
- PICKUP_GIANT();
#endif /* illumos */
}
@@ -2919,7 +2914,7 @@
}
int
-zvol_create_minors(const char *name)
+zvol_create_minors_impl(const char *name)
{
uint64_t cookie;
objset_t *os;
@@ -2975,7 +2970,7 @@
while (dmu_dir_list_next(os, MAXPATHLEN - (p - osname), p, NULL,
&cookie) == 0) {
dmu_objset_rele(os, FTAG);
- (void)zvol_create_minors(osname);
+ (void)zvol_create_minors_impl(osname);
if ((error = dmu_objset_hold(name, FTAG, &os)) != 0) {
printf("ZFS WARNING: Unable to put hold on %s (error=%d).\n",
name, error);
@@ -3044,7 +3039,7 @@
}
void
-zvol_rename_minors(const char *oldname, const char *newname)
+zvol_rename_minors_impl(const char *oldname, const char *newname)
{
char name[MAXPATHLEN];
struct g_provider *pp;
@@ -3057,7 +3052,6 @@
oldnamelen = strlen(oldname);
newnamelen = strlen(newname);
- DROP_GIANT();
/* See comment in zvol_open(). */
if (!MUTEX_HELD(&zfsdev_state_lock)) {
mutex_enter(&zfsdev_state_lock);
@@ -3079,7 +3073,88 @@
if (locked)
mutex_exit(&zfsdev_state_lock);
- PICKUP_GIANT();
+}
+
+static zvol_task_t *
+zvol_task_alloc(zvol_async_op_t op, const char *name1, const char *name2)
+{
+ zvol_task_t *task;
+ char *delim;
+
+ task = kmem_zalloc(sizeof (zvol_task_t), KM_SLEEP);
+ task->op = op;
+ delim = strchr(name1, '/');
+ strlcpy(task->pool, name1, delim ? (delim - name1 + 1) : MAXNAMELEN);
+
+ strlcpy(task->name1, name1, MAXNAMELEN);
+ if (name2 != NULL)
+ strlcpy(task->name2, name2, MAXNAMELEN);
+
+ return (task);
+}
+
+static void
+zvol_task_free(zvol_task_t *task)
+{
+ kmem_free(task, sizeof (zvol_task_t));
+}
+
+/*
+ * The worker thread function performed asynchronously.
+ */
+static void
+zvol_task_cb(void *param)
+{
+ zvol_task_t *task = (zvol_task_t *)param;
+
+ switch (task->op) {
+ case ZVOL_ASYNC_CREATE_MINORS:
+ (void) zvol_create_minors_impl(task->name1);
+ break;
+ case ZVOL_ASYNC_REMOVE_MINORS:
+ zvol_remove_minors_impl(task->name1);
+ break;
+ case ZVOL_ASYNC_RENAME_MINORS:
+ zvol_rename_minors_impl(task->name1, task->name2);
+ break;
+ default:
+ VERIFY(0);
+ break;
+ }
+
+ zvol_task_free(task);
+}
+
+static void
+zvol_minors_helper(spa_t *spa, zvol_async_op_t op, const char *name1,
+ const char *name2)
+{
+ zvol_task_t *task;
+
+ if (dataset_name_hidden(name1))
+ return;
+ if (name2 != NULL && dataset_name_hidden(name2))
+ return;
+ task = zvol_task_alloc(op, name1, name2);
+ (void)taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP);
+}
+
+void
+zvol_create_minors(spa_t *spa, const char *name)
+{
+ zvol_minors_helper(spa, ZVOL_ASYNC_CREATE_MINORS, name, NULL);
+}
+
+void
+zvol_remove_minors(spa_t *spa, const char *name)
+{
+ zvol_minors_helper(spa, ZVOL_ASYNC_REMOVE_MINORS, name, NULL);
+}
+
+void
+zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname)
+{
+ zvol_minors_helper(spa, ZVOL_ASYNC_RENAME_MINORS, oldname, newname);
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jun 30, 10:07 AM (8 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34496011
Default Alt Text
D23478.id67695.diff (18 KB)
Attached To
Mode
D23478: rework how ZVOLs are updated in response to DSL operations
Attached
Detach File
Event Timeline
Log In to Comment