]> git.baikalelectronics.ru Git - kernel.git/commitdiff
nfsd: Retry once in nfsd_open on an -EOPENSTALE return
authorJeff Layton <jeff.layton@primarydata.com>
Sun, 19 Dec 2021 01:37:56 +0000 (20:37 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Sat, 8 Jan 2022 19:42:02 +0000 (14:42 -0500)
If we get back -EOPENSTALE from an NFSv4 open, then we either got some
unhandled error or the inode we got back was not the same as the one
associated with the dentry.

We really have no recourse in that situation other than to retry the
open, and if it fails to just return nfserr_stale back to the client.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfsproc.c
fs/nfsd/vfs.c

index da0414ecf4d2705512ae30223ffa6977e1c16e2b..48c7344151df3b54aaaa25feb427e597ddc8e687 100644 (file)
@@ -875,6 +875,7 @@ nfserrno (int errno)
                { nfserr_serverfault, -ESERVERFAULT },
                { nfserr_serverfault, -ENFILE },
                { nfserr_io, -EREMOTEIO },
+               { nfserr_stale, -EOPENSTALE },
                { nfserr_io, -EUCLEAN },
                { nfserr_perm, -ENOKEY },
                { nfserr_no_grace, -ENOGRACE},
index c99857689e2c2ab5dec2d4fff53c15d1d05ecfd7..0faa3839ea6cd1fbc22b167f3185685609306676 100644 (file)
@@ -777,6 +777,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
                int may_flags, struct file **filp)
 {
        __be32 err;
+       bool retried = false;
 
        validate_process_creds();
        /*
@@ -792,9 +793,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
         */
        if (type == S_IFREG)
                may_flags |= NFSD_MAY_OWNER_OVERRIDE;
+retry:
        err = fh_verify(rqstp, fhp, type, may_flags);
-       if (!err)
+       if (!err) {
                err = __nfsd_open(rqstp, fhp, type, may_flags, filp);
+               if (err == nfserr_stale && !retried) {
+                       retried = true;
+                       fh_put(fhp);
+                       goto retry;
+               }
+       }
        validate_process_creds();
        return err;
 }