pnfs: Stop attempting LAYOUTGET on OPEN on failure
authorFred Isaman <fred.isaman@gmail.com>
Tue, 4 Oct 2016 19:26:41 +0000 (15:26 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 31 May 2018 19:03:11 +0000 (15:03 -0400)
Signed-off-by: Fred Isaman <fred.isaman@gmail.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
include/linux/nfs_fs_sb.h

index 0e6db190a8745a14ca1ddbbb6870f8af36dbdc58..05454cbc473df7950ae8b650263165a67156879c 100644 (file)
@@ -9465,7 +9465,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
                | NFS_CAP_ATOMIC_OPEN
                | NFS_CAP_POSIX_LOCK
                | NFS_CAP_STATEID_NFSV41
-               | NFS_CAP_ATOMIC_OPEN_V1,
+               | NFS_CAP_ATOMIC_OPEN_V1
+               | NFS_CAP_LGOPEN,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
@@ -9490,6 +9491,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_POSIX_LOCK
                | NFS_CAP_STATEID_NFSV41
                | NFS_CAP_ATOMIC_OPEN_V1
+               | NFS_CAP_LGOPEN
                | NFS_CAP_ALLOCATE
                | NFS_CAP_COPY
                | NFS_CAP_DEALLOCATE
index a6fe8132e94414dbef751d7ce11bbc5160ab6834..3dfe9fa264a539d99bcb8a07af7541d40c0eb9c5 100644 (file)
@@ -2088,6 +2088,8 @@ void pnfs_lgopen_prepare(struct nfs4_opendata *data,
              server->pnfs_curr_ld->flags & PNFS_LAYOUTGET_ON_OPEN))
                return;
        /* Could check on max_ops, but currently hardcoded high enough */
+       if (!nfs_server_capable(data->dir->d_inode, NFS_CAP_LGOPEN))
+               return;
        if (data->state)
                _lgopen_prepare_attached(data, ctx);
        else
@@ -2101,8 +2103,23 @@ void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
        struct pnfs_layout_segment *lseg;
        u32 iomode;
 
-       if (!lgp || lgp->res.layoutp->len == 0)
+       if (!lgp)
                return;
+       dprintk("%s: entered with status %i\n", __func__, lgp->res.status);
+       if (lgp->res.status) {
+               switch (lgp->res.status) {
+               case -NFS4ERR_DELAY:
+               case -NFS4ERR_GRACE:
+               case -NFS4ERR_LAYOUTTRYLATER:
+                       break;
+               default:
+                       /* FIXME - Any error not listed above permanently
+                        * halts lgopen attempts.
+                        */
+                       NFS_SERVER(ino)->caps &= ~NFS_CAP_LGOPEN;
+               }
+               return;
+       }
        if (!lgp->args.inode) {
                lo = _pnfs_grab_empty_layout(ino, ctx);
                if (!lo)
index 4e735be53e704a56a33f8576b75023dafd60f158..2c18d618604ecfc7f8342236131e227c2003c89a 100644 (file)
@@ -235,6 +235,7 @@ struct nfs_server {
 #define NFS_CAP_ACLS           (1U << 3)
 #define NFS_CAP_ATOMIC_OPEN    (1U << 4)
 /* #define NFS_CAP_CHANGE_ATTR (1U << 5) */
+#define NFS_CAP_LGOPEN         (1U << 5)
 #define NFS_CAP_FILEID         (1U << 6)
 #define NFS_CAP_MODE           (1U << 7)
 #define NFS_CAP_NLINK          (1U << 8)