diff options
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r-- | fs/cifs/misc.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 191e6220bc76..0241b25ac33f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | extern mempool_t *cifs_sm_req_poolp; | 33 | extern mempool_t *cifs_sm_req_poolp; |
34 | extern mempool_t *cifs_req_poolp; | 34 | extern mempool_t *cifs_req_poolp; |
35 | extern struct task_struct *oplockThread; | ||
36 | 35 | ||
37 | /* The xid serves as a useful identifier for each incoming vfs request, | 36 | /* The xid serves as a useful identifier for each incoming vfs request, |
38 | in a similar way to the mid which is useful to track each sent smb, | 37 | in a similar way to the mid which is useful to track each sent smb, |
@@ -500,6 +499,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
500 | struct cifsTconInfo *tcon; | 499 | struct cifsTconInfo *tcon; |
501 | struct cifsInodeInfo *pCifsInode; | 500 | struct cifsInodeInfo *pCifsInode; |
502 | struct cifsFileInfo *netfile; | 501 | struct cifsFileInfo *netfile; |
502 | int rc; | ||
503 | 503 | ||
504 | cFYI(1, ("Checking for oplock break or dnotify response")); | 504 | cFYI(1, ("Checking for oplock break or dnotify response")); |
505 | if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && | 505 | if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && |
@@ -569,19 +569,30 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
569 | if (pSMB->Fid != netfile->netfid) | 569 | if (pSMB->Fid != netfile->netfid) |
570 | continue; | 570 | continue; |
571 | 571 | ||
572 | read_unlock(&GlobalSMBSeslock); | 572 | /* |
573 | read_unlock(&cifs_tcp_ses_lock); | 573 | * don't do anything if file is about to be |
574 | * closed anyway. | ||
575 | */ | ||
576 | if (netfile->closePend) { | ||
577 | read_unlock(&GlobalSMBSeslock); | ||
578 | read_unlock(&cifs_tcp_ses_lock); | ||
579 | return true; | ||
580 | } | ||
581 | |||
574 | cFYI(1, ("file id match, oplock break")); | 582 | cFYI(1, ("file id match, oplock break")); |
575 | pCifsInode = CIFS_I(netfile->pInode); | 583 | pCifsInode = CIFS_I(netfile->pInode); |
576 | pCifsInode->clientCanCacheAll = false; | 584 | pCifsInode->clientCanCacheAll = false; |
577 | if (pSMB->OplockLevel == 0) | 585 | if (pSMB->OplockLevel == 0) |
578 | pCifsInode->clientCanCacheRead = false; | 586 | pCifsInode->clientCanCacheRead = false; |
579 | AllocOplockQEntry(netfile->pInode, | 587 | rc = slow_work_enqueue(&netfile->oplock_break); |
580 | netfile->netfid, tcon); | 588 | if (rc) { |
581 | cFYI(1, ("about to wake up oplock thread")); | 589 | cERROR(1, ("failed to enqueue oplock " |
582 | if (oplockThread) | 590 | "break: %d\n", rc)); |
583 | wake_up_process(oplockThread); | 591 | } else { |
584 | 592 | netfile->oplock_break_cancelled = false; | |
593 | } | ||
594 | read_unlock(&GlobalSMBSeslock); | ||
595 | read_unlock(&cifs_tcp_ses_lock); | ||
585 | return true; | 596 | return true; |
586 | } | 597 | } |
587 | read_unlock(&GlobalSMBSeslock); | 598 | read_unlock(&GlobalSMBSeslock); |