aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu_objset.c
diff options
context:
space:
mode:
authorKeith M Wesolowski <[email protected]>2013-07-27 10:50:07 -0700
committerBrian Behlendorf <[email protected]>2013-11-04 11:27:41 -0800
commit831baf06efb3023ddee7ed41800d3b44521bf2ee (patch)
tree01347f77efc0f3a717c3f143d960bf9e5db3d065 /module/zfs/dmu_objset.c
parent19580676295b4e271da63dce145bb17c3731d069 (diff)
Illumos #3875
3875 panic in zfs_root() after failed rollback Reviewed by: Jerry Jelinek <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Approved by: Gordon Ross <[email protected]> References: https://www.illumos.org/issues/3875 illumos/illumos-gate@91948b51b8e978ddc88a36b2bc3ae83c20cdc9aa Ported-by: Richard Yao <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #1775
Diffstat (limited to 'module/zfs/dmu_objset.c')
-rw-r--r--module/zfs/dmu_objset.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index f886254af..6a3b5f05e 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -517,6 +517,38 @@ dmu_objset_rele(objset_t *os, void *tag)
dsl_pool_rele(dp, tag);
}
+/*
+ * When we are called, os MUST refer to an objset associated with a dataset
+ * that is owned by 'tag'; that is, is held and long held by 'tag' and ds_owner
+ * == tag. We will then release and reacquire ownership of the dataset while
+ * holding the pool config_rwlock to avoid intervening namespace or ownership
+ * changes may occur.
+ *
+ * This exists solely to accommodate zfs_ioc_userspace_upgrade()'s desire to
+ * release the hold on its dataset and acquire a new one on the dataset of the
+ * same name so that it can be partially torn down and reconstructed.
+ */
+void
+dmu_objset_refresh_ownership(objset_t *os, void *tag)
+{
+ dsl_pool_t *dp;
+ dsl_dataset_t *ds, *newds;
+ char name[MAXNAMELEN];
+
+ ds = os->os_dsl_dataset;
+ VERIFY3P(ds, !=, NULL);
+ VERIFY3P(ds->ds_owner, ==, tag);
+ VERIFY(dsl_dataset_long_held(ds));
+
+ dsl_dataset_name(ds, name);
+ dp = dmu_objset_pool(os);
+ dsl_pool_config_enter(dp, FTAG);
+ dmu_objset_disown(os, tag);
+ VERIFY0(dsl_dataset_own(dp, name, tag, &newds));
+ VERIFY3P(newds, ==, os->os_dsl_dataset);
+ dsl_pool_config_exit(dp, FTAG);
+}
+
void
dmu_objset_disown(objset_t *os, void *tag)
{