Skip to content

Commit

Permalink
Make txg_wait_synced conditional in zfsvfs_teardown, for FreeBSD
Browse files Browse the repository at this point in the history
This applies the same change in #9115 to FreeBSD.  This was actually the
old behavior in FreeBSD 12; it only regressed when FreeBSD support was
added to OpenZFS.  As far as I can tell, the timeline went like this:

* Illumos's zfsvfs_teardown used an unconditional txg_wait_synced
* Illumos added the dirty data check [^4]
* FreeBSD merged in Illumos's conditional check [^3]
* OpenZFS forked from Illumos
* OpenZFS removed the dirty data check in #7795 [^5]
* @mattmacy forked the OpenZFS repo and began to add FreeBSD support
* OpenZFS PR #9115[^1] recreated the same dirty data check that Illumos
  used, in slightly different form.  At this point the OpenZFS repo did
  not yet have multi-OS support.
* Matt Macy merged in FreeBSD support in #8987[^2] , but it was based on
  slightly outdated OpenZFS code.

In my local testing, this vastly improves the reboot speed of a server
with a large pool that has 1000 datasets and is resilvering an HDD.

[^1]: #9115
[^2]: #8987
[^3]: freebsd/freebsd-src@10b9d77
[^4]: illumos/illumos-gate@5aaeed5
[^5]: #7795

Sponsored by: Axcient
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Alan Somers <asomers@gmail.com>
Closes #16268
  • Loading branch information
asomers authored Aug 9, 2024
1 parent cf6e8b2 commit ed0db1c
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions module/os/freebsd/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,9 +1636,18 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
zfs_unregister_callbacks(zfsvfs);

/*
* Evict cached data
* Evict cached data. We must write out any dirty data before
* disowning the dataset.
*/
if (!zfs_is_readonly(zfsvfs))
objset_t *os = zfsvfs->z_os;
boolean_t os_dirty = B_FALSE;
for (int t = 0; t < TXG_SIZE; t++) {
if (dmu_objset_is_dirty(os, t)) {
os_dirty = B_TRUE;
break;
}
}
if (!zfs_is_readonly(zfsvfs) && os_dirty)
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
dmu_objset_evict_dbufs(zfsvfs->z_os);
dd = zfsvfs->z_os->os_dsl_dataset->ds_dir;
Expand Down

0 comments on commit ed0db1c

Please sign in to comment.