Dangling reference from dmu_objset_upgrade
After porting the fix for https://github.com/openzfs/zfs/issues/5295 over to illumos, we started hitting an assertion failure when running the testsuite: assertion failed: rc->rc_count == number, file: .../refcount.c and the unexpected hold has this stack: dsl_dataset_long_hold+0x59 dmu_objset_upgrade+0x73 dmu_objset_id_quota_upgrade+0x15 dmu_objset_own+0x14f The simplest reproducer for this in illumos is zpool create -f -O version=1 testpool c3t0d0; zpool destroy testpool which is run as part of the zpool_create_tempname test, but I can't get this to trigger on FreeBSD. This appears to be because of the call to txg_wait_synced() in dmu_objset_upgrade_stop() (which was missing in illumos), slows down dmu_objset_disown() enough to avoid the condition. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Andy Fiddaman <andy@omnios.org> Closes #11368
This commit is contained in:
parent
6152014d1a
commit
39372fa25b
@ -1428,10 +1428,15 @@ dmu_objset_upgrade_task_cb(void *data)
|
||||
mutex_enter(&os->os_upgrade_lock);
|
||||
os->os_upgrade_status = EINTR;
|
||||
if (!os->os_upgrade_exit) {
|
||||
int status;
|
||||
|
||||
mutex_exit(&os->os_upgrade_lock);
|
||||
|
||||
os->os_upgrade_status = os->os_upgrade_cb(os);
|
||||
status = os->os_upgrade_cb(os);
|
||||
|
||||
mutex_enter(&os->os_upgrade_lock);
|
||||
|
||||
os->os_upgrade_status = status;
|
||||
}
|
||||
os->os_upgrade_exit = B_TRUE;
|
||||
os->os_upgrade_id = 0;
|
||||
@ -1459,6 +1464,8 @@ dmu_objset_upgrade(objset_t *os, dmu_objset_upgrade_cb_t cb)
|
||||
dsl_dataset_long_rele(dmu_objset_ds(os), upgrade_tag);
|
||||
os->os_upgrade_status = ENOMEM;
|
||||
}
|
||||
} else {
|
||||
dsl_dataset_long_rele(dmu_objset_ds(os), upgrade_tag);
|
||||
}
|
||||
mutex_exit(&os->os_upgrade_lock);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user