summaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index bee203055b30..1e1626a2cfc3 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -501,8 +501,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
501 CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, 501 CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
502 &pCifsInode->flags); 502 &pCifsInode->flags);
503 503
504 queue_work(cifsoplockd_wq, 504 cifs_queue_oplock_break(netfile);
505 &netfile->oplock_break);
506 netfile->oplock_break_cancelled = false; 505 netfile->oplock_break_cancelled = false;
507 506
508 spin_unlock(&tcon->open_file_lock); 507 spin_unlock(&tcon->open_file_lock);
@@ -607,6 +606,28 @@ void cifs_put_writer(struct cifsInodeInfo *cinode)
607 spin_unlock(&cinode->writers_lock); 606 spin_unlock(&cinode->writers_lock);
608} 607}
609 608
609/**
610 * cifs_queue_oplock_break - queue the oplock break handler for cfile
611 *
612 * This function is called from the demultiplex thread when it
613 * receives an oplock break for @cfile.
614 *
615 * Assumes the tcon->open_file_lock is held.
616 * Assumes cfile->file_info_lock is NOT held.
617 */
618void cifs_queue_oplock_break(struct cifsFileInfo *cfile)
619{
620 /*
621 * Bump the handle refcount now while we hold the
622 * open_file_lock to enforce the validity of it for the oplock
623 * break handler. The matching put is done at the end of the
624 * handler.
625 */
626 cifsFileInfo_get(cfile);
627
628 queue_work(cifsoplockd_wq, &cfile->oplock_break);
629}
630
610void cifs_done_oplock_break(struct cifsInodeInfo *cinode) 631void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
611{ 632{
612 clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); 633 clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);