Skip to content

Commit 6553498

Browse files
Trond Myklebustgregkh
authored andcommitted
nfsd: Don't reset the write verifier on a commit EAGAIN
[ Upstream commit 1b2021b ] If fsync() is returning EAGAIN, then we can assume that the filesystem being exported is something like NFS with the 'softerr' mount option enabled, and that it is just asking us to replay the fsync() operation at a later date. If we see an ESTALE, then ditto: the file is gone, so there is no danger of losing the error. For those cases, do not reset the write verifier. A write verifier change has a global effect, causing retransmission by all clients of all uncommitted unstable writes for all files, so it is worth mitigating where possible. Link: https://lore.kernel.org/linux-nfs/20230911184357.11739-1-trond.myklebust@hammerspace.com/ Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Stable-dep-of: 2090b05 ("nfsd: reset write verifier on deferred writeback errors") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent eeabb90 commit 6553498

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

fs/nfsd/vfs.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,24 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
338338
return err;
339339
}
340340

341+
static void
342+
commit_reset_write_verifier(struct nfsd_net *nn, struct svc_rqst *rqstp,
343+
int err)
344+
{
345+
switch (err) {
346+
case -EAGAIN:
347+
case -ESTALE:
348+
/*
349+
* Neither of these are the result of a problem with
350+
* durable storage, so avoid a write verifier reset.
351+
*/
352+
break;
353+
default:
354+
nfsd_reset_write_verifier(nn);
355+
trace_nfsd_writeverf_reset(nn, rqstp, err);
356+
}
357+
}
358+
341359
/*
342360
* Commit metadata changes to stable storage.
343361
*/
@@ -659,8 +677,7 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
659677
&nfsd4_get_cstate(rqstp)->current_fh,
660678
dst_pos,
661679
count, status);
662-
nfsd_reset_write_verifier(nn);
663-
trace_nfsd_writeverf_reset(nn, rqstp, status);
680+
commit_reset_write_verifier(nn, rqstp, status);
664681
ret = nfserrno(status);
665682
}
666683
}
@@ -1177,8 +1194,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
11771194
host_err = vfs_iter_write(file, &iter, &pos, flags);
11781195
file_end_write(file);
11791196
if (host_err < 0) {
1180-
nfsd_reset_write_verifier(nn);
1181-
trace_nfsd_writeverf_reset(nn, rqstp, host_err);
1197+
commit_reset_write_verifier(nn, rqstp, host_err);
11821198
goto out_nfserr;
11831199
}
11841200
*cnt = host_err;
@@ -1193,10 +1209,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
11931209

11941210
if (stable && use_wgather) {
11951211
host_err = wait_for_concurrent_writes(file);
1196-
if (host_err < 0) {
1197-
nfsd_reset_write_verifier(nn);
1198-
trace_nfsd_writeverf_reset(nn, rqstp, host_err);
1199-
}
1212+
if (host_err < 0)
1213+
commit_reset_write_verifier(nn, rqstp, host_err);
12001214
}
12011215

12021216
out_nfserr:
@@ -1343,8 +1357,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
13431357
err = nfserr_notsupp;
13441358
break;
13451359
default:
1346-
nfsd_reset_write_verifier(nn);
1347-
trace_nfsd_writeverf_reset(nn, rqstp, err2);
1360+
commit_reset_write_verifier(nn, rqstp, err2);
13481361
err = nfserrno(err2);
13491362
}
13501363
} else

0 commit comments

Comments
 (0)