Page MenuHomeFreeBSD

vn_delayed_setsize()
AcceptedPublic

Authored by kib on Sat, Feb 28, 4:35 PM.
Tags
None
Referenced Files
F146498732: D55595.diff
Tue, Mar 3, 4:16 AM
F146498229: D55595.diff
Tue, Mar 3, 4:10 AM
F146486623: D55595.diff
Tue, Mar 3, 2:13 AM
F146417723: D55595.id172992.diff
Mon, Mar 2, 1:02 PM
F146406023: D55595.id172965.diff
Mon, Mar 2, 10:56 AM
Unknown Object (File)
Sun, Mar 1, 10:11 PM
Unknown Object (File)
Sun, Mar 1, 12:10 PM
Unknown Object (File)
Sun, Mar 1, 11:57 AM
Subscribers

Details

Summary
vfs: add VOP_DELAYED_SETSIZE() and related infrastructure

The change generalizes code that was initially developed for nfs client
to handle filesystems that needs to call vnode_pager_setsize() while
only owning the vnode lock shared.  Since vnode pager might need to trim
or extend the vnode vm_object' page queue, the vnode lock for the call
must be owned exclusive.  This is typical for filesystems with remote
authorative source of file attributes, like nfs/p9/fuse.

Handle the conflict by delaying the vnode_pager_setsize() to the next
vnode locking to avoid relock.  But if the next locking request is in
shared mode, lock it exclusively instead, perform the delayed
vnode_pager_setsize() call by doing VOP_DEFAULT_SETSIZE(), and then
downgrade to shared.

Filesystems that opt into the feature must provide the implementation of
VOP_DELAYED_SETSIZE() that actually calls vnode_pager_setsize(), and use
vn_delay_setsize() helper to mark the vnode as requiring the delay call.


nfsclient: convert to use vn_delayed_setsize()

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

kib requested review of this revision.Sat, Feb 28, 4:35 PM
20260228 20:28:50 all (1/11): ftruncate3.sh
VNASSERT failed: a->a_gen.a_desc == &vop_lock1_desc not true at vnode_if.c:2095 (VOP_LOCK1_APV)
0xfffffe016a9e6940: type VREG state VSTATE_CONSTRUCTED op 0xffffffff81aaead8
    usecount 3, writecount 2, refcount 1 seqc users 0
    hold count flags ()
    flags (VV_VMSIZEVNLOCK|VI(0x40)|VMP_LAZYLIST)
    v_object 0xfffff803dac10c30 ref 2 pages 0 cleanbuf 0 dirtybuf 0
    lock type nfs: UNLOCKED
#0 0xffffffff80b990c8 at lockmgr_lock_flags+0x1b8
#1 0xffffffff80cc0f20 at vop_sigdefer+0x30
#2 0xffffffff81213a93 at VOP_LOCK1_APV+0x133
#3 0xffffffff80cfc96b at VOP_LOCK1+0x4b
#4 0xffffffff80cfa260 at _vn_lock+0x140
#5 0xffffffff80cf7902 at vn_truncate+0x82
#6 0xffffffff80c4febe at kern_ftruncate+0xee
#7 0xffffffff8113eaa9 at amd64_syscall+0x169
#8 0xffffffff8110d6db at fast_syscall_common+0xf8
	fileid 3 fsid 0x3a3a00ff01
panic: Wrong a_desc in vop_lock1(0xfffffe016a9e6940, 0xfffffe010008fa50)

log0657.txt

Properly initialize ap.gen.desc

Accumulated bug fixes after the Peter' testing.

I consider removing the nfs n_mtx and using the vnode interlock instead, as the future change.

Integrate delayed setsize locking into vn_lock() more tight, now that the code moved out from VOP.

It all looks good to me, although I won't claim to
understand all the required semantics in
vn_lock_delayed_setsize().

This revision is now accepted and ready to land.Mon, Mar 2, 10:30 PM