aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2012-04-27 17:53:53 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-19 17:55:33 -0400
commit041245c88a29273788e8eff1353bc6e1f56c61df (patch)
tree0810bad95fe40c6fbf1a1dc13cb3ba0305ba30d3 /fs/nfs/nfs4filelayout.c
parentb4a2967e52523dbf0281b52c042f9042c6082f99 (diff)
NFSv4.1 resend LAYOUTGET on data server invalid layout errors
The "invalid layout" class of errors is handled by destroying the layout and getting a new layout from the server. Currently, the layout must be destroyed before a new layout can be obtained. This means that all references (e.g.lsegs) to the "to be destroyed" layout header must be dropped before it can be destroyed. This in turn means waiting for all in flight RPC's using the old layout as well as draining the data server session slot table wait queue. Set the NFS_LAYOUT_INVALID flag to redirect I/O to the MDS while waiting for the old layout to be destroyed. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index eaaca897305c..474c6305afd9 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -182,6 +182,27 @@ static int filelayout_async_handle_error(struct rpc_task *task,
182 break; 182 break;
183 case -NFS4ERR_RETRY_UNCACHED_REP: 183 case -NFS4ERR_RETRY_UNCACHED_REP:
184 break; 184 break;
185 /* Invalidate Layout errors */
186 case -NFS4ERR_PNFS_NO_LAYOUT:
187 case -ESTALE: /* mapped NFS4ERR_STALE */
188 case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */
189 case -EISDIR: /* mapped NFS4ERR_ISDIR */
190 case -NFS4ERR_FHEXPIRED:
191 case -NFS4ERR_WRONG_TYPE:
192 dprintk("%s Invalid layout error %d\n", __func__,
193 task->tk_status);
194 /*
195 * Destroy layout so new i/o will get a new layout.
196 * Layout will not be destroyed until all current lseg
197 * references are put. Mark layout as invalid to resend failed
198 * i/o and all i/o waiting on the slot table to the MDS until
199 * layout is destroyed and a new valid layout is obtained.
200 */
201 set_bit(NFS_LAYOUT_INVALID,
202 &NFS_I(state->inode)->layout->plh_flags);
203 pnfs_destroy_layout(NFS_I(state->inode));
204 rpc_wake_up(&tbl->slot_tbl_waitq);
205 goto reset;
185 /* RPC connection errors */ 206 /* RPC connection errors */
186 case -ECONNREFUSED: 207 case -ECONNREFUSED:
187 case -EHOSTDOWN: 208 case -EHOSTDOWN:
@@ -199,6 +220,7 @@ static int filelayout_async_handle_error(struct rpc_task *task,
199 nfs4_ds_disconnect(clp); 220 nfs4_ds_disconnect(clp);
200 /* fall through */ 221 /* fall through */
201 default: 222 default:
223reset:
202 dprintk("%s Retry through MDS. Error %d\n", __func__, 224 dprintk("%s Retry through MDS. Error %d\n", __func__,
203 task->tk_status); 225 task->tk_status);
204 return -NFS4ERR_RESET_TO_MDS; 226 return -NFS4ERR_RESET_TO_MDS;
@@ -263,9 +285,8 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata)
263static void filelayout_read_prepare(struct rpc_task *task, void *data) 285static void filelayout_read_prepare(struct rpc_task *task, void *data)
264{ 286{
265 struct nfs_read_data *rdata = data; 287 struct nfs_read_data *rdata = data;
266 struct pnfs_layout_segment *lseg = rdata->header->lseg;
267 288
268 if (filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg))) { 289 if (filelayout_reset_to_mds(rdata->header->lseg)) {
269 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); 290 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
270 filelayout_reset_read(rdata); 291 filelayout_reset_read(rdata);
271 rpc_exit(task, 0); 292 rpc_exit(task, 0);
@@ -366,9 +387,8 @@ static int filelayout_commit_done_cb(struct rpc_task *task,
366static void filelayout_write_prepare(struct rpc_task *task, void *data) 387static void filelayout_write_prepare(struct rpc_task *task, void *data)
367{ 388{
368 struct nfs_write_data *wdata = data; 389 struct nfs_write_data *wdata = data;
369 struct pnfs_layout_segment *lseg = wdata->header->lseg;
370 390
371 if (filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg))) { 391 if (filelayout_reset_to_mds(wdata->header->lseg)) {
372 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); 392 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
373 filelayout_reset_write(wdata); 393 filelayout_reset_write(wdata);
374 rpc_exit(task, 0); 394 rpc_exit(task, 0);