Page MenuHomeFreeBSD

Handle a possible race between VOP_LOOKUP and Writing a file
ClosedPublic

Authored by rmacklem on Oct 26 2021, 11:40 PM.
Tags
None
Referenced Files
Unknown Object (File)
Feb 24 2024, 3:51 PM
Unknown Object (File)
Feb 10 2024, 5:01 PM
Unknown Object (File)
Feb 4 2024, 12:45 PM
Unknown Object (File)
Dec 24 2023, 6:12 AM
Unknown Object (File)
Dec 23 2023, 5:11 AM
Unknown Object (File)
Dec 15 2023, 2:59 AM
Unknown Object (File)
Nov 26 2023, 5:29 AM
Unknown Object (File)
Nov 25 2023, 3:55 AM
Subscribers

Details

Summary

Similar to D32635, I believe there could be a race between the NFS
client VOP_LOOKUP() and file Writing that could result in stale file
attributes being loaded into the NFS vnode by VOP_LOOKUP().

I have not been able to reproduce a failure due to this race, but
I believe that there are two possibilities:

  • The Lookup RPC happens while VOP_WRITE() is being executed and loads stale file attributes after VOP_WRITE() returns when it has already completed the Write/Commit RPC(s). --> For this case, setting the local modify timestamp at the end of VOP_WRITE() should ensure that stale file attributes are not loaded.
  • The Lookup RPC occurs after VOP_WRITE() has returned, while asynchronous Write/Commit RPCs are in progress and then is blocked by the vnode held by VOP_OPEN/VOP_CLOSE/VOP_FSYNC which will flush writes via ncl_flush() or ncl_vinvalbuf(), clearing the NMODIFIED flag (which indicates Writes-in-progress). The VOP_LOOKUP() then acquires the NFS vnode lock and fills in stale file attributes. --> Setting the local modify timestamp in ncl_flsuh() and ncl_vinvalbuf() when they clear NMODIFIED should ensure that stale file attributes are not loaded.

This patch does the above.

Test Plan

Tested for regressions and with several variants of the
test program in PR#259071 without demonstrating
problems.

Since Write/Commit RPCs update the attributes in
the NFS vnode, not doing this during VOP_LOOKUP()
should not be a problem.

Diff Detail

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