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 eaaca897305..474c6305afd 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, break; case -NFS4ERR_RETRY_UNCACHED_REP: break; + /* Invalidate Layout errors */ + case -NFS4ERR_PNFS_NO_LAYOUT: + case -ESTALE: /* mapped NFS4ERR_STALE */ + case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */ + case -EISDIR: /* mapped NFS4ERR_ISDIR */ + case -NFS4ERR_FHEXPIRED: + case -NFS4ERR_WRONG_TYPE: + dprintk("%s Invalid layout error %d\n", __func__, + task->tk_status); + /* + * Destroy layout so new i/o will get a new layout. + * Layout will not be destroyed until all current lseg + * references are put. Mark layout as invalid to resend failed + * i/o and all i/o waiting on the slot table to the MDS until + * layout is destroyed and a new valid layout is obtained. + */ + set_bit(NFS_LAYOUT_INVALID, + &NFS_I(state->inode)->layout->plh_flags); + pnfs_destroy_layout(NFS_I(state->inode)); + rpc_wake_up(&tbl->slot_tbl_waitq); + goto reset; /* RPC connection errors */ case -ECONNREFUSED: case -EHOSTDOWN: @@ -199,6 +220,7 @@ static int filelayout_async_handle_error(struct rpc_task *task, nfs4_ds_disconnect(clp); /* fall through */ default: +reset: dprintk("%s Retry through MDS. Error %d\n", __func__, task->tk_status); return -NFS4ERR_RESET_TO_MDS; @@ -263,9 +285,8 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata) static void filelayout_read_prepare(struct rpc_task *task, void *data) { struct nfs_read_data *rdata = data; - struct pnfs_layout_segment *lseg = rdata->header->lseg; - if (filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg))) { + if (filelayout_reset_to_mds(rdata->header->lseg)) { dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); filelayout_reset_read(rdata); rpc_exit(task, 0); @@ -366,9 +387,8 @@ static int filelayout_commit_done_cb(struct rpc_task *task, static void filelayout_write_prepare(struct rpc_task *task, void *data) { struct nfs_write_data *wdata = data; - struct pnfs_layout_segment *lseg = wdata->header->lseg; - if (filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg))) { + if (filelayout_reset_to_mds(wdata->header->lseg)) { dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); filelayout_reset_write(wdata); rpc_exit(task, 0); |