Fix s_active leak in zfsvfs_hold() when z_unmounted is true

When getzfsvfs() succeeds (incrementing s_active via
zfs_vfs_ref()), but z_unmounted is subsequently found to
be B_TRUE, zfsvfs_hold() returns EBUSY without calling
zfs_vfs_rele(). This permanently leaks the VFS superblock
s_active reference, preventing generic_shutdown_super()
from ever firing, which blocks dmu_objset_disown() and
makes the pool permanently unexportable (EBUSY).

Add the missing zfs_vfs_rele() call, guarded by
zfs_vfs_held() to handle the zfsvfs_create() fallback
path where no VFS reference exists. This matches the
existing cleanup pattern in zfsvfs_rele().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: mischivus <1205832+mischivus@users.noreply.github.com>
Closes #18309
Closes #18310
This commit is contained in:
mischivus
2026-03-11 21:19:00 -06:00
committed by Tony Hutter
parent aba3ed30a3
commit b40cd91913
+1
View File
@@ -1439,6 +1439,7 @@ zfsvfs_hold(const char *name, const void *tag, zfsvfs_t **zfvp,
* objset from the zfsvfs.
*/
ZFS_TEARDOWN_EXIT(*zfvp, tag);
zfs_vfs_rele(*zfvp);
return (SET_ERROR(EBUSY));
}
}