diff options
author | Boris Protopopov <[email protected]> | 2014-03-22 05:07:14 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-03-10 09:49:22 -0800 |
commit | a0bd735adb1b1eb81fef10b4db102ee051c4d4ff (patch) | |
tree | 121fcde3000a116f0c33143b28a530a87fd6073a /module/zfs/dsl_dataset.c | |
parent | eb0856779f7b57162c9179f238104f6d6e150745 (diff) |
Add support for asynchronous zvol minor operations
zfsonlinux issue #2217 - zvol minor operations: check snapdev
property before traversing snapshots of a dataset
zfsonlinux issue #3681 - lock order inversion between zvol_open()
and dsl_pool_sync()...zvol_rename_minors()
Create a per-pool zvol taskq for asynchronous zvol tasks.
There are a few key design decisions to be aware of.
* Each taskq must be single threaded to ensure tasks are always
processed in the order in which they were dispatched.
* There is a taskq per-pool in order 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.
Support for asynchronous zvol minor operations address issue #3681.
Signed-off-by: Boris Protopopov <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2217
Closes #3678
Closes #3681
Diffstat (limited to 'module/zfs/dsl_dataset.c')
-rw-r--r-- | module/zfs/dsl_dataset.c | 36 |
1 files changed, 6 insertions, 30 deletions
diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index a5a9694fc..230027daf 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -24,6 +24,7 @@ * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2014 RackTop Systems. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. */ #include <sys/dmu_objset.h> @@ -1424,6 +1425,7 @@ dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx) dsl_props_set_sync_impl(ds->ds_prev, ZPROP_SRC_LOCAL, ddsa->ddsa_props, tx); } + zvol_create_minors(dp->dp_spa, nvpair_name(pair), B_TRUE); dsl_dataset_rele(ds, FTAG); } } @@ -1498,16 +1500,6 @@ dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors) fnvlist_free(suspended); } -#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 - return (error); } @@ -1930,6 +1922,8 @@ dsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp, VERIFY0(zap_add(dp->dp_meta_objset, dsl_dataset_phys(hds)->ds_snapnames_zapobj, ds->ds_snapname, 8, 1, &ds->ds_object, tx)); + zvol_rename_minors(dp->dp_spa, ddrsa->ddrsa_oldsnapname, + ddrsa->ddrsa_newsnapname, B_TRUE); dsl_dataset_rele(ds, FTAG); return (0); @@ -1958,11 +1952,6 @@ int dsl_dataset_rename_snapshot(const char *fsname, const char *oldsnapname, const char *newsnapname, boolean_t recursive) { -#ifdef _KERNEL - char *oldname, *newname; -#endif - int error; - dsl_dataset_rename_snapshot_arg_t ddrsa; ddrsa.ddrsa_fsname = fsname; @@ -1970,22 +1959,9 @@ dsl_dataset_rename_snapshot(const char *fsname, ddrsa.ddrsa_newsnapname = newsnapname; ddrsa.ddrsa_recursive = recursive; - error = dsl_sync_task(fsname, dsl_dataset_rename_snapshot_check, + return (dsl_sync_task(fsname, dsl_dataset_rename_snapshot_check, dsl_dataset_rename_snapshot_sync, &ddrsa, - 1, ZFS_SPACE_CHECK_RESERVED); - - if (error) - return (SET_ERROR(error)); - -#ifdef _KERNEL - oldname = kmem_asprintf("%s@%s", fsname, oldsnapname); - newname = kmem_asprintf("%s@%s", fsname, newsnapname); - zvol_rename_minors(oldname, newname); - strfree(newname); - strfree(oldname); -#endif - - return (0); + 1, ZFS_SPACE_CHECK_RESERVED)); } /* |