diff options
author | smh <smh@FreeBSD.org> | 2014-10-10 01:01:04 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2014-10-10 01:01:04 +0000 |
commit | 4347b3c38b4237555ff0fc5763cb47854bdf8d31 (patch) | |
tree | 4698971160d9cf1c54e2bdb1bd15e2002ec52084 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c | |
parent | 303356caa9a2204687c43e218ab0b0b090dfd1fe (diff) | |
download | FreeBSD-src-4347b3c38b4237555ff0fc5763cb47854bdf8d31.zip FreeBSD-src-4347b3c38b4237555ff0fc5763cb47854bdf8d31.tar.gz |
MFC r272474:
Fix various issues with zvols
Sponsored by: Multiplay
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index a97a10a..d013206 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -2257,6 +2257,9 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx) dsl_dir_t *odd = NULL; uint64_t oldnext_obj; int64_t delta; +#if defined(__FreeBSD__) && defined(_KERNEL) + char *oldname, *newname; +#endif VERIFY0(promote_hold(ddpa, dp, FTAG)); hds = ddpa->ddpa_clone; @@ -2322,6 +2325,14 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx) dd->dd_phys->dd_clones, origin_head->ds_object, tx)); } +#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); +#endif + /* move snapshots to this dir */ for (snap = list_head(&ddpa->shared_snaps); snap; snap = list_next(&ddpa->shared_snaps, snap)) { @@ -2356,6 +2367,12 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx) VERIFY0(dsl_dir_hold_obj(dp, dd->dd_object, NULL, ds, &ds->ds_dir)); +#if defined(__FreeBSD__) && defined(_KERNEL) + dsl_dataset_name(ds, newname); + zfsvfs_update_fromname(oldname, newname); + zvol_rename_minors(oldname, newname); +#endif + /* move any clone references */ if (ds->ds_phys->ds_next_clones_obj && spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) { @@ -2393,6 +2410,12 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx) ASSERT(!dsl_prop_hascb(ds)); } +#if defined(__FreeBSD__) && defined(_KERNEL) + mutex_exit(&spa_namespace_lock); + + kmem_free(newname, MAXPATHLEN); + kmem_free(oldname, MAXPATHLEN); +#endif /* * Change space accounting. * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either |