aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorFred Isaman <fred.isaman@gmail.com>2016-10-04 15:26:41 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-05-31 15:03:11 -0400
commit6e01260ceeca299b82d466660935534c5c909d54 (patch)
tree16852b84a1595fbb2bd4b64cbdc085d3b91cd16c /fs/nfs
parentpnfs: Add LAYOUTGET to OPEN of an existing file (diff)
downloadlinux-dev-6e01260ceeca299b82d466660935534c5c909d54.tar.xz
linux-dev-6e01260ceeca299b82d466660935534c5c909d54.zip
pnfs: Stop attempting LAYOUTGET on OPEN on failure
Signed-off-by: Fred Isaman <fred.isaman@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--fs/nfs/pnfs.c19
2 files changed, 21 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0e6db190a874..05454cbc473d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -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
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index a6fe8132e944..3dfe9fa264a5 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -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)