cifs: simplify refcounting for oplock breaks
Currently, we take a sb->s_active reference and a cifsFileInfo reference when an oplock break workqueue job is queued. This is unnecessary and more complicated than it needs to be. Also as Al points out, deactivate_super has non-trivial locking implications so it's best to avoid that if we can. Instead, just cancel any pending oplock breaks for this filehandle synchronously in cifsFileInfo_put after taking it off the lists. That should ensure that this job doesn't outlive the structures it depends on. Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:

committed by
Steve French

parent
5980fc966b
commit
ad635942c8
@@ -585,15 +585,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
|
||||
|
||||
cifs_set_oplock_level(pCifsInode,
|
||||
pSMB->OplockLevel ? OPLOCK_READ : 0);
|
||||
/*
|
||||
* cifs_oplock_break_put() can't be called
|
||||
* from here. Get reference after queueing
|
||||
* succeeded. cifs_oplock_break() will
|
||||
* synchronize using cifs_file_list_lock.
|
||||
*/
|
||||
if (queue_work(system_nrt_wq,
|
||||
&netfile->oplock_break))
|
||||
cifs_oplock_break_get(netfile);
|
||||
queue_work(system_nrt_wq,
|
||||
&netfile->oplock_break);
|
||||
netfile->oplock_break_cancelled = false;
|
||||
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
|
Reference in New Issue
Block a user