summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2014-10-10 01:01:04 +0000
committersmh <smh@FreeBSD.org>2014-10-10 01:01:04 +0000
commit4347b3c38b4237555ff0fc5763cb47854bdf8d31 (patch)
tree4698971160d9cf1c54e2bdb1bd15e2002ec52084 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
parent303356caa9a2204687c43e218ab0b0b090dfd1fe (diff)
downloadFreeBSD-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.c23
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
OpenPOWER on IntegriCloud