diff options
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 28 |
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: |
223 | reset: | ||
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) | |||
263 | static void filelayout_read_prepare(struct rpc_task *task, void *data) | 285 | static 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, | |||
366 | static void filelayout_write_prepare(struct rpc_task *task, void *data) | 387 | static 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); |