Skip to content

Commit

Permalink
Dangling reference from dmu_objset_upgrade
Browse files Browse the repository at this point in the history
After porting the fix for openzfs#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.

Signed-off-by: Andy Fiddaman <[email protected]>
  • Loading branch information
citrus-it committed Dec 18, 2020
1 parent 52c8537 commit 388a557
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 388a557

Please sign in to comment.