diff options
author | Keith M Wesolowski <[email protected]> | 2013-07-27 10:50:07 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-11-04 11:27:41 -0800 |
commit | 831baf06efb3023ddee7ed41800d3b44521bf2ee (patch) | |
tree | 01347f77efc0f3a717c3f143d960bf9e5db3d065 /module/zfs/dmu_objset.c | |
parent | 19580676295b4e271da63dce145bb17c3731d069 (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.c | 32 |
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) { |