@@ -490,6 +490,7 @@ extern int nfs40_walk_client_list(struct nfs_client *clp,
extern int nfs41_walk_client_list(struct nfs_client *clp,
struct nfs_client **result,
struct rpc_cred *cred);
+extern bool nfs4_wake_up_first(struct nfs4_session *ses);
/*
* Determine the device name as a string
@@ -131,7 +131,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
struct nfs_server *mds_server = NFS_SERVER(inode);
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
struct nfs_client *mds_client = mds_server->nfs_client;
- struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
if (task->tk_status >= 0)
return 0;
@@ -191,7 +190,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
* layout is destroyed and a new valid layout is obtained.
*/
pnfs_destroy_layout(NFS_I(inode));
- rpc_wake_up(&tbl->slot_tbl_waitq);
goto reset;
/* RPC connection errors */
case -ECONNREFUSED:
@@ -206,7 +204,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
nfs4_mark_deviceid_unavailable(devid);
clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
_pnfs_return_layout(inode);
- rpc_wake_up(&tbl->slot_tbl_waitq);
nfs4_ds_disconnect(clp);
/* fall through */
default:
@@ -294,6 +291,7 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
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);
+ nfs4_wake_up_first(rdata->ds_clp->cl_session);
rpc_exit(task, 0);
return;
}
@@ -396,6 +394,7 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
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);
+ nfs4_wake_up_first(wdata->ds_clp->cl_session);
rpc_exit(task, 0);
return;
}
@@ -438,17 +438,25 @@ bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
return true;
}
-/*
- * Signal state manager thread if session fore channel is drained
- */
-static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
+bool nfs4_wake_up_first(struct nfs4_session *ses)
{
if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
rpc_wake_up_first(&ses->fc_slot_table.slot_tbl_waitq,
nfs4_set_task_privileged, NULL);
- return;
+ return true;
}
+ return false;
+}
+EXPORT_SYMBOL_GPL(nfs4_wake_up_first);
+/*
+ * Signal state manager thread if session fore channel is drained
+ */
+static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
+{
+
+ if (nfs4_wake_up_first(ses))
+ return;
if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
return;