Page MenuHomeFreeBSD

DEBUG_VFS_LOCKS: stop excluding devfs and doomed vnode from asserts
ClosedPublic

Authored by kib on Oct 31 2021, 9:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Dec 9, 5:48 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:24 PM
Unknown Object (File)
Thu, Nov 21, 2:03 PM
Subscribers

Details

Summary

We do not require devvp vnode locked for metadata io. It is typically not needed indeed, since correctness of the file system using corresponding block device ensures that there is no incorrect or racy manipulations.

But right now DEBUG_VFS_LOCKS option excludes both character device vnodes and completely destroyed (VBAD) vnodes from asserts. This is not too bad since WITNESS still ensures that we do not leak locks. On the other hand, asserts do not mean what they should, to the reader, and reliance on them being enforced might result in wrong code.

Fix this, but first either remove assertions not holding, or adding real locking where needed.

Note that ASSERT_VOP_LOCKED() still silently accepts NULLVP, I think it is worth fixing as well, in the next round.

Messages from individual commits:

Make locking assertions for VOP_FSYNC() more correct

For devfs vnodes, it is fine to not lock vnodes for VOP_FSYNC().
Otherwise vnode must be locked exclusively, except for MNT_SHARED_WRITES().
freevnode(): lock the freeing vnode around destroy_vpollinfo()
ffs_snapshot: do not assert that um_devvp is locked

It is not, and the lock is not needed there
mntfs: lock mntfs pseudo devfs vnode properly

Require devvp locked for mntfs_freevp(), to have it locked around
vgone().  Make that true for ffs, which is the only consumer of
the interface.
ffs: Remove assertions about locked um_devvp in several places

Namely, ffs_blkfree_cg(), and ffs_flushfiles().
getblk(): do not require devvp vnodes to be locked
geom_vfs: lock devvp in g_vfs_close()

It is needed for g_vfs_close() invalidating the buffers.  We rely on the
vnode lock for correctness.

Per-commit view is available at https://kib.kiev.ua/git/gitweb.cgi?p=deviant3.git;a=shortlog;h=refs/heads/ufs

Diff Detail

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

Event Timeline

kib requested review of this revision.Oct 31 2021, 9:51 PM

Upload current patchset.

kib added reviewers: markj, mckusick, chs, jah, mjg.
sys/kern/vfs_subr.c
1901 ↗(On Diff #97999)

Why exactly is it necessary? In particular I wonder why it's ok to set v_pollinfo = NULL without the vnode lock.

5566 ↗(On Diff #97999)

Should vop_fdatasync have the same wrappers? I guess for devfs it doesn't make a difference since vop_stdfdatasync() calls VOP_FSYNC.

kib marked 2 inline comments as done.Nov 9 2021, 4:54 PM
kib added inline comments.
sys/kern/vfs_subr.c
1901 ↗(On Diff #97999)

We are in freevnode(). The vnode is freed several lines below, so there must be no any references to it. With one exception: vnode might be still registered for kevents notifications, and destroy_vpollinfo() above manipulates klists to remove the registered events.

I considered either moving the destroy into vgonel(), and I decided that it is unsafe. Also I believe that it is wrong to loose the klist asserts there.

5566 ↗(On Diff #97999)

Yes I think you are right, done.

kib marked 2 inline comments as done.

Handle VOP_FDATASYNC() locking assertions same as VOP_FSYNC().

Fix typo.

Reported by: pho

This revision is now accepted and ready to land.Nov 12 2021, 10:02 PM