Re: [PATCH v2 2/7] nfsd: answer NFS4ERR_DELAY instead of waiting for a layout recall
From: Chuck Lever
Date: Wed Oct 14 2026 - 17:03:25 EST
On 10/14/26, Daejun Park wrote:
> @@ -2384,6 +2384,14 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> spin_unlock(&async_copy->cp_copy.cp_clp->async_lock);
> status = nfs_ok;
> } else {
> + struct inode *src = file_inode(copy->nf_src->nf_file);
> + struct inode *dst = file_inode(copy->nf_dst->nf_file);
> +
> + /* A copy can be done as a clone, which breaks both files */
> + status = nfserrno(nfsd_break_layouts(src,
> + dst != src ? dst : NULL));
> + if (status)
> + goto out;
> status = nfsd4_do_copy(copy, copy->nf_src->nf_file,
> copy->nf_dst->nf_file, true);
This recalls layouts only for a synchronous COPY. The asynchronous
branch above it hands the same work to nfsd4_do_async_copy(), which
calls nfsd4_do_copy() with no recall at all. An async COPY whose
destination is held under an RW block layout by another client then
writes through the MDS page cache while that client writes the same
extents directly to the device. XFS breaks layouts for truncate,
fallocate and remap, but not for a buffered or spliced write, so
nothing below NFSD catches it either.
The recall therefore belongs before the sync/async split, so both
paths will execute it.
Nit: See if you can cut down the verbiage in the new comments.
kdoc comments are meant to document API contracts. Operational
details can be described close to the code itself (concisely,
please).
--
Chuck Lever (Come to NFS bake-a-thon! https://nfsv4bat.org)