Page MenuHomeFreeBSD

unionfs: avoid vdrop()ing a locked but doomed vnode
ClosedPublic

Authored by jah on Tue, Oct 14, 10:19 PM.
Tags
None
Referenced Files
F135555405: D53107.diff
Mon, Nov 10, 6:58 PM
Unknown Object (File)
Wed, Nov 5, 6:13 AM
Unknown Object (File)
Sun, Nov 2, 7:45 AM
Unknown Object (File)
Thu, Oct 30, 11:37 PM
Unknown Object (File)
Wed, Oct 29, 6:54 AM
Unknown Object (File)
Wed, Oct 29, 6:53 AM
Unknown Object (File)
Wed, Oct 29, 6:53 AM
Unknown Object (File)
Wed, Oct 29, 6:43 AM
Subscribers

Details

Summary

unionfs_lock() unconditionally calls vdrop() on the target vnode
after locking it, but it's possible this vnode may be doomed.
In that case, vdrop() may free the vnode, which in certain cases
requires taking the vnode lock. Commit a7aac8c20497d added an
assert to this effect, which unionfs_lock() now trips over.

Fix this by lightly reworking the flow of unionfs_lock() so that
the target vnode is vdrop()ed after being unlocked in the case
where the unionfs lock operation needs to be restarted (which
will happen if the unionfs vnode has been doomed, which is a
prerequisite for the target vnode in the underlying filesystem
to have been doomed).

While here, get rid of a superfluous vhold/vdrop sequence in
unionfs_unlock() that was probably inherited from nullfs and whose
nullfs equivalent was recently removed.

MFC after: 1 week

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

jah requested review of this revision.Tue, Oct 14, 10:19 PM

Further cleanup of unionfs_unlock()

This revision is now accepted and ready to land.Wed, Oct 15, 3:22 AM
olce accepted this revision.EditedWed, Oct 15, 2:42 PM

For the changes in unionfs_lock(), there is indeed a window after the interlock drop and before lock acquire and drop where the "root" reference unionfs holds (through unionfs_node; the one that allows to call vholdnz() above) could be dropped (it's the same window described in the big comment about checking whether the proper target vnode (lower or upper) was locked).

The changes in unionfs_unlock() are also good (and would be even without D52608).