aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2013-02-28 20:30:10 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-02-28 20:41:35 -0500
commit3000512137602b84d1ad5fd89d62984993a19bb6 (patch)
treead75f7487669d2977fa1fcb0b45de533c35f29e2 /fs/nfs
parentedddbb1eda61753c886a3c5e159293a7b3a9e30a (diff)
NFSv4.1: LAYOUTGET EDELAY loops timeout to the MDS
The client will currently try LAYOUTGETs forever if a server is returning NFS4ERR_LAYOUTTRYLATER or NFS4ERR_RECALLCONFLICT - even if the client no longer needs the layout (ie process killed, unmounted). This patch uses the DS timeout value (module parameter 'dataserver_timeo' via rpc layer) to set an upper limit of how long the client tries LATOUTGETs in this situation. Once the timeout is reached, IO is redirected to the MDS. This also changes how the client checks if a layout is on the clp list to avoid a double list_add. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c9
-rw-r--r--fs/nfs/pnfs.c7
2 files changed, 11 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 37eb38566fbc..b2671cb0f901 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -93,6 +93,8 @@ static int nfs4_map_errors(int err)
93 return err; 93 return err;
94 switch (err) { 94 switch (err) {
95 case -NFS4ERR_RESOURCE: 95 case -NFS4ERR_RESOURCE:
96 case -NFS4ERR_LAYOUTTRYLATER:
97 case -NFS4ERR_RECALLCONFLICT:
96 return -EREMOTEIO; 98 return -EREMOTEIO;
97 case -NFS4ERR_WRONGSEC: 99 case -NFS4ERR_WRONGSEC:
98 return -EPERM; 100 return -EPERM;
@@ -6046,6 +6048,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
6046 struct nfs_server *server = NFS_SERVER(inode); 6048 struct nfs_server *server = NFS_SERVER(inode);
6047 struct pnfs_layout_hdr *lo; 6049 struct pnfs_layout_hdr *lo;
6048 struct nfs4_state *state = NULL; 6050 struct nfs4_state *state = NULL;
6051 unsigned long timeo, giveup;
6049 6052
6050 dprintk("--> %s\n", __func__); 6053 dprintk("--> %s\n", __func__);
6051 6054
@@ -6057,7 +6060,10 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
6057 goto out; 6060 goto out;
6058 case -NFS4ERR_LAYOUTTRYLATER: 6061 case -NFS4ERR_LAYOUTTRYLATER:
6059 case -NFS4ERR_RECALLCONFLICT: 6062 case -NFS4ERR_RECALLCONFLICT:
6060 task->tk_status = -NFS4ERR_DELAY; 6063 timeo = rpc_get_timeout(task->tk_client);
6064 giveup = lgp->args.timestamp + timeo;
6065 if (time_after(giveup, jiffies))
6066 task->tk_status = -NFS4ERR_DELAY;
6061 break; 6067 break;
6062 case -NFS4ERR_EXPIRED: 6068 case -NFS4ERR_EXPIRED:
6063 case -NFS4ERR_BAD_STATEID: 6069 case -NFS4ERR_BAD_STATEID:
@@ -6178,6 +6184,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6178 return ERR_PTR(-ENOMEM); 6184 return ERR_PTR(-ENOMEM);
6179 } 6185 }
6180 lgp->args.layout.pglen = max_pages * PAGE_SIZE; 6186 lgp->args.layout.pglen = max_pages * PAGE_SIZE;
6187 lgp->args.timestamp = jiffies;
6181 6188
6182 lgp->res.layoutp = &lgp->args.layout; 6189 lgp->res.layoutp = &lgp->args.layout;
6183 lgp->res.seq_res.sr_slot = NULL; 6190 lgp->res.seq_res.sr_slot = NULL;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 97767c8683f9..48ac5aad6258 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1181,7 +1181,7 @@ pnfs_update_layout(struct inode *ino,
1181 struct nfs_client *clp = server->nfs_client; 1181 struct nfs_client *clp = server->nfs_client;
1182 struct pnfs_layout_hdr *lo; 1182 struct pnfs_layout_hdr *lo;
1183 struct pnfs_layout_segment *lseg = NULL; 1183 struct pnfs_layout_segment *lseg = NULL;
1184 bool first = false; 1184 bool first;
1185 1185
1186 if (!pnfs_enabled_sb(NFS_SERVER(ino))) 1186 if (!pnfs_enabled_sb(NFS_SERVER(ino)))
1187 goto out; 1187 goto out;
@@ -1215,10 +1215,9 @@ pnfs_update_layout(struct inode *ino,
1215 goto out_unlock; 1215 goto out_unlock;
1216 atomic_inc(&lo->plh_outstanding); 1216 atomic_inc(&lo->plh_outstanding);
1217 1217
1218 if (list_empty(&lo->plh_segs)) 1218 first = list_empty(&lo->plh_layouts) ? true : false;
1219 first = true;
1220
1221 spin_unlock(&ino->i_lock); 1219 spin_unlock(&ino->i_lock);
1220
1222 if (first) { 1221 if (first) {
1223 /* The lo must be on the clp list if there is any 1222 /* The lo must be on the clp list if there is any
1224 * chance of a CB_LAYOUTRECALL(FILE) coming in. 1223 * chance of a CB_LAYOUTRECALL(FILE) coming in.