MFV r330973: 9164 assert: newds == os->os_dsl_dataset
illumos/illumos-gate@5f5913bb83
5f5913bb83
https://www.illumos.org/issues/9164
This issue has been reported by Alan Somers as
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225877
dmu_objset_refresh_ownership() first disowns a dataset (and releases
it) and then owns it again. There is an assert that the new dataset
object is the same as the old dataset object. When running ZFS Test
Suite on FreeBSD we see this panic from zpool_upgrade_007_pos test:
panic: solaris assert: newds == os->os_dsl_dataset (0xfffff80045f4c000
== 0xfffff80021ab4800)
I see that the old dataset has dsl_dataset_evict_async() pending in
ds_dbu.dbu_tqent and its ds_dbuf is NULL.
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Don Brady <don.brady@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Author: Andriy Gapon <avg@FreeBSD.org>
PR: 225877
Reported by: asomers
MFC after: 1 week
This commit is contained in:
parent
a61b260648
commit
e226f0acba
@ -670,23 +670,21 @@ dmu_objset_rele(objset_t *os, void *tag)
|
||||
* same name so that it can be partially torn down and reconstructed.
|
||||
*/
|
||||
void
|
||||
dmu_objset_refresh_ownership(objset_t *os, void *tag)
|
||||
dmu_objset_refresh_ownership(dsl_dataset_t *ds, dsl_dataset_t **newds,
|
||||
void *tag)
|
||||
{
|
||||
dsl_pool_t *dp;
|
||||
dsl_dataset_t *ds, *newds;
|
||||
char name[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
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);
|
||||
dp = ds->ds_dir->dd_pool;
|
||||
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_dataset_disown(ds, tag);
|
||||
VERIFY0(dsl_dataset_own(dp, name, tag, newds));
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,8 @@ int dmu_objset_own(const char *name, dmu_objset_type_t type,
|
||||
boolean_t readonly, void *tag, objset_t **osp);
|
||||
int dmu_objset_own_obj(struct dsl_pool *dp, uint64_t obj,
|
||||
dmu_objset_type_t type, boolean_t readonly, void *tag, objset_t **osp);
|
||||
void dmu_objset_refresh_ownership(objset_t *os, void *tag);
|
||||
void dmu_objset_refresh_ownership(struct dsl_dataset *ds,
|
||||
struct dsl_dataset **newds, void *tag);
|
||||
void dmu_objset_rele(objset_t *os, void *tag);
|
||||
void dmu_objset_disown(objset_t *os, void *tag);
|
||||
int dmu_objset_from_ds(struct dsl_dataset *ds, objset_t **osp);
|
||||
|
@ -5115,14 +5115,14 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
||||
* objset needs to be closed & reopened (to grow the
|
||||
* objset_phys_t). Suspend/resume the fs will do that.
|
||||
*/
|
||||
dsl_dataset_t *ds;
|
||||
dsl_dataset_t *ds, *newds;
|
||||
|
||||
ds = dmu_objset_ds(zfsvfs->z_os);
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
if (error == 0) {
|
||||
dmu_objset_refresh_ownership(zfsvfs->z_os,
|
||||
dmu_objset_refresh_ownership(ds, &newds,
|
||||
zfsvfs);
|
||||
error = zfs_resume_fs(zfsvfs, ds);
|
||||
error = zfs_resume_fs(zfsvfs, newds);
|
||||
}
|
||||
}
|
||||
if (error == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user