[PATCH v1 1/3] NFSD: Make the write verifier reset helper available outside vfs.c
Chuck Lever <[email protected]>
| Newsgroups | org.kernel.vger.linux-nfs |
|---|---|
| Message-ID | <[email protected]> |
A subsequent patch moves the NFSv4-specific portions of nfsd4_clone_file_range() out of fs/nfsd/vfs.c and into its caller in fs/nfsd/nfs4proc.c. One of those portions resets the write verifier when the post-clone sync fails. netns.h already exposes nfsd_reset_write_verifier(), but that is the unconditional reset. commit_reset_write_verifier() wraps it with the policy that decides which errors warrant a reset: -EAGAIN and -ESTALE do not indicate a problem with durable storage, so they leave the verifier alone. A caller outside vfs.c has to apply the same policy, so make the wrapper visible rather than duplicate its switch. Rename it to nfsd_maybe_reset_write_verifier() on the way out. Signed-off-by: Chuck Lever <[email protected]> --- fs/nfsd/vfs.c | 29 ++++++++++++++++++++--------- fs/nfsd/vfs.h | 5 +++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6d865f4f9ba3..fad51a899062 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -352,9 +352,20 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, return err; } -static void -commit_reset_write_verifier(struct nfsd_net *nn, struct svc_rqst *rqstp, - int err) +/** + * nfsd_maybe_reset_write_verifier - Reset the write verifier after an I/O error + * @nn: nfsd namespace holding the write verifier + * @rqstp: RPC transaction context + * @err: errno reported by the failed operation + * + * A write verifier reset tells clients that unstable data the server has + * already acknowledged might have been lost. Client response is to resend + * in-flight dirty data. + * + * Context: Process context. + */ +void nfsd_maybe_reset_write_verifier(struct nfsd_net *nn, + struct svc_rqst *rqstp, int err) { switch (err) { case -EAGAIN: @@ -735,7 +746,7 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, &nfsd4_get_cstate(rqstp)->current_fh, dst_pos, count, status); - commit_reset_write_verifier(nn, rqstp, status); + nfsd_maybe_reset_write_verifier(nn, rqstp, status); ret = nfserrno(status); } } @@ -1472,21 +1483,21 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, break; } if (host_err < 0) { - commit_reset_write_verifier(nn, rqstp, host_err); + nfsd_maybe_reset_write_verifier(nn, rqstp, host_err); goto out_nfserr; } nfsd_stats_io_write_add(nn, exp, *cnt); fsnotify_modify(file); host_err = filemap_check_wb_err(file->f_mapping, since); if (host_err < 0) { - commit_reset_write_verifier(nn, rqstp, host_err); + nfsd_maybe_reset_write_verifier(nn, rqstp, host_err); goto out_nfserr; } if (iocb_flags && fhp->fh_use_wgather) { host_err = wait_for_concurrent_writes(file); if (host_err < 0) - commit_reset_write_verifier(nn, rqstp, host_err); + nfsd_maybe_reset_write_verifier(nn, rqstp, host_err); } out_nfserr: @@ -1662,14 +1673,14 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, err2 = filemap_check_wb_err(nf->nf_file->f_mapping, since); if (err2 < 0) - commit_reset_write_verifier(nn, rqstp, err2); + nfsd_maybe_reset_write_verifier(nn, rqstp, err2); err = nfserrno(err2); break; case -EINVAL: err = nfserr_notsupp; break; default: - commit_reset_write_verifier(nn, rqstp, err2); + nfsd_maybe_reset_write_verifier(nn, rqstp, err2); err = nfserrno(err2); } } else diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 3aa4522ca0a4..18171ccc6d16 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -86,7 +86,12 @@ static inline bool nfsd_attrs_valid(struct nfsd_attrs *attrs) attrs->na_pacl || attrs->na_dpacl); } +struct nfsd_net; + __be32 nfserrno (int errno); +void nfsd_maybe_reset_write_verifier(struct nfsd_net *nn, + struct svc_rqst *rqstp, + int err); __be32 nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, struct svc_export **expp); __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, -- 2.54.0