diff options
| author | Benjamin Coddington <bcodding@hammerspace.com> | 2026-10-15 07:33:07 -0400 |
|---|---|---|
| committer | Anna Schumaker <anna.schumaker@hammerspace.com> | 2026-10-19 11:45:01 -0400 |
| commit | 7fa2ad367abe6d3155daefb57331e7fce1a17afd (patch) | |
| tree | e98c16564cea2f9e7a70543230bee5b4de35b96b /scripts/Makefile.thinlto | |
| parent | 8c13019a785d6adb1efd797ac03903758abfd7a8 (diff) | |
| download | linux-7fa2ad367abe6d3155daefb57331e7fce1a17afd.tar.gz linux-7fa2ad367abe6d3155daefb57331e7fce1a17afd.zip | |
NFSv4/flexfiles: fail I/O to the data server once a lock is lost
When a client loses a byte-range lock, because its lease expired and it
may not recover the lock (nfs.recover_lost_locks=0) or because reclaim
failed, it marks the lock state NFS_LOCK_LOST and fails further I/O by
that lock owner. Otherwise an application that believes it holds a
lock over a range is never told that the lock is gone, and can
overwrite data that another client has since written under its own
lock on that range.
The NFSv4 READ/WRITE and file layout I/O paths apply this in
rpc_call_prepare, where nfs4_set_rw_stateid() returns -EIO for a lost
lock. The flexfiles data server I/O path does not: the NFSv3 data
server path never checked, and the check on the NFSv4 path was removed
when the data server stateid began to be taken from the layout.
Fail read and write RPCs to the data server in rpc_call_prepare when the
lock is lost. The data server path has no use for the stateid that
nfs4_set_rw_stateid() selects, and selecting it looks up a delegation
or open stateid on every I/O.
Instead add nfs4_lock_context_lost(), which only tests NFS_LOCK_LOST,
and check it alongside the open state. Its lookup,
__nfs4_lookup_lock_state(), is split out of __nfs4_find_lock_state()
and takes no reference: a lock state is only unlinked from
state->lock_states under state->state_lock, so one found while holding
that lock cannot be freed before it is released. Use it in
nfs4_copy_lock_stateid() as well, which only reads the lock state under
that lock. That drops a reference get and put from stateid selection
for all NFSv4 I/O without changing the stateid selected.
Terminating the RPC in rpc_call_prepare is not enough on its own. The
done callback reads the -EIO as a data server connection error, forgets
the device ID, and resets the I/O to pNFS (or, for an NFSv4 data
server, possibly to the MDS). After a reset to pNFS a new LAYOUTGET is
granted and rpc_call_prepare fails the I/O again, without end. The
existing NFS_CONTEXT_BAD check does not loop, since the open state is
then invalid and pnfs_update_layout() fails the reset I/O, but it still
forgets the device ID.
So when an RPC that was never sent fails and the open context is bad,
the open state is invalid, or the lock is lost, complete it with -EIO
without error handling. An RPC that was sent and failed is handled as
before, so a real data server error is still reported to the MDS.
Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver")
Fixes: bb21ce0ad227 ("flexfiles: use per-mirror specified stateid for IO")
Cc: stable@vger.kernel.org
Tested-by: Arun Potharaju <arun.potharaju@hammerspace.com>
Assisted-by: LLM
Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
