mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
NFSv4.1 Fix a pNFS session draining deadlock
On a CB_RECALL the callback service thread flushes the inode using filemap_flush prior to scheduling the state manager thread to return the delegation. When pNFS is used and I/O has not yet gone to the data server servicing the inode, a LAYOUTGET can preceed the I/O. Unlike the async filemap_flush call, the LAYOUTGET must proceed to completion. If the state manager starts to recover data while the inode flush is sending the LAYOUTGET, a deadlock occurs as the callback service thread holds the single callback session slot until the flushing is done which blocks the state manager thread, and the state manager thread has set the session draining bit which puts the inode flush LAYOUTGET RPC to sleep on the forechannel slot table waitq. Separate the draining of the back channel from the draining of the fore channel by moving the NFS4_SESSION_DRAINING bit from session scope into the fore and back slot tables. Drain the back channel first allowing the LAYOUTGET call to proceed (and fail) so the callback service thread frees the callback slot. Then proceed with draining the forechannel. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
2aed8b476f
commit
774d5f14ee
6 changed files with 20 additions and 18 deletions
|
@ -73,7 +73,7 @@ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
|
|||
tbl->highest_used_slotid = new_max;
|
||||
else {
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
nfs4_session_drain_complete(tbl->session, tbl);
|
||||
nfs4_slot_tbl_drain_complete(tbl);
|
||||
}
|
||||
}
|
||||
dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
|
||||
|
@ -226,7 +226,7 @@ static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
|
|||
struct nfs4_slot *slot = pslot;
|
||||
struct nfs4_slot_table *tbl = slot->table;
|
||||
|
||||
if (nfs4_session_draining(tbl->session) && !args->sa_privileged)
|
||||
if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
|
||||
return false;
|
||||
slot->generation = tbl->generation;
|
||||
args->sa_slot = slot;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue