@@ -323,8 +323,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
323323 cfile -> dentry = dget (dentry );
324324 cfile -> f_flags = file -> f_flags ;
325325 cfile -> invalidHandle = false;
326- cfile -> oplock_break_received = false;
327- cfile -> deferred_scheduled = false;
326+ cfile -> deferred_close_scheduled = false;
328327 cfile -> tlink = cifs_get_tlink (tlink );
329328 INIT_WORK (& cfile -> oplock_break , cifs_oplock_break );
330329 INIT_WORK (& cfile -> put , cifsFileInfo_put_work );
@@ -574,21 +573,18 @@ int cifs_open(struct inode *inode, struct file *file)
574573 file -> f_op = & cifs_file_direct_ops ;
575574 }
576575
577- spin_lock (& CIFS_I (inode )-> deferred_lock );
578576 /* Get the cached handle as SMB2 close is deferred */
579577 rc = cifs_get_readable_path (tcon , full_path , & cfile );
580578 if (rc == 0 ) {
581579 if (file -> f_flags == cfile -> f_flags ) {
582580 file -> private_data = cfile ;
581+ spin_lock (& CIFS_I (inode )-> deferred_lock );
583582 cifs_del_deferred_close (cfile );
584583 spin_unlock (& CIFS_I (inode )-> deferred_lock );
585584 goto out ;
586585 } else {
587- spin_unlock (& CIFS_I (inode )-> deferred_lock );
588586 _cifsFileInfo_put (cfile , true, false);
589587 }
590- } else {
591- spin_unlock (& CIFS_I (inode )-> deferred_lock );
592588 }
593589
594590 if (server -> oplocks )
@@ -878,12 +874,8 @@ void smb2_deferred_work_close(struct work_struct *work)
878874 struct cifsFileInfo , deferred .work );
879875
880876 spin_lock (& CIFS_I (d_inode (cfile -> dentry ))-> deferred_lock );
881- if (!cfile -> deferred_scheduled ) {
882- spin_unlock (& CIFS_I (d_inode (cfile -> dentry ))-> deferred_lock );
883- return ;
884- }
885877 cifs_del_deferred_close (cfile );
886- cfile -> deferred_scheduled = false;
878+ cfile -> deferred_close_scheduled = false;
887879 spin_unlock (& CIFS_I (d_inode (cfile -> dentry ))-> deferred_lock );
888880 _cifsFileInfo_put (cfile , true, false);
889881}
@@ -900,19 +892,26 @@ int cifs_close(struct inode *inode, struct file *file)
900892 file -> private_data = NULL ;
901893 dclose = kmalloc (sizeof (struct cifs_deferred_close ), GFP_KERNEL );
902894 if ((cinode -> oplock == CIFS_CACHE_RHW_FLG ) &&
895+ cinode -> lease_granted &&
903896 dclose ) {
904897 if (test_bit (CIFS_INO_MODIFIED_ATTR , & cinode -> flags ))
905898 inode -> i_ctime = inode -> i_mtime = current_time (inode );
906899 spin_lock (& cinode -> deferred_lock );
907900 cifs_add_deferred_close (cfile , dclose );
908- if (cfile -> deferred_scheduled ) {
909- mod_delayed_work (deferredclose_wq ,
910- & cfile -> deferred , cifs_sb -> ctx -> acregmax );
901+ if (cfile -> deferred_close_scheduled &&
902+ delayed_work_pending (& cfile -> deferred )) {
903+ /*
904+ * If there is no pending work, mod_delayed_work queues new work.
905+ * So, Increase the ref count to avoid use-after-free.
906+ */
907+ if (!mod_delayed_work (deferredclose_wq ,
908+ & cfile -> deferred , cifs_sb -> ctx -> acregmax ))
909+ cifsFileInfo_get (cfile );
911910 } else {
912911 /* Deferred close for files */
913912 queue_delayed_work (deferredclose_wq ,
914913 & cfile -> deferred , cifs_sb -> ctx -> acregmax );
915- cfile -> deferred_scheduled = true;
914+ cfile -> deferred_close_scheduled = true;
916915 spin_unlock (& cinode -> deferred_lock );
917916 return 0 ;
918917 }
@@ -2020,8 +2019,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
20202019 if (fsuid_only && !uid_eq (open_file -> uid , current_fsuid ()))
20212020 continue ;
20222021 if (OPEN_FMODE (open_file -> f_flags ) & FMODE_READ ) {
2023- if ((!open_file -> invalidHandle ) &&
2024- (!open_file -> oplock_break_received )) {
2022+ if ((!open_file -> invalidHandle )) {
20252023 /* found a good file */
20262024 /* lock it so it will not be closed on us */
20272025 cifsFileInfo_get (open_file );
@@ -4874,14 +4872,20 @@ void cifs_oplock_break(struct work_struct *work)
48744872 }
48754873 /*
48764874 * When oplock break is received and there are no active
4877- * file handles but cached, then set the flag oplock_break_received .
4875+ * file handles but cached, then schedule deferred close immediately .
48784876 * So, new open will not use cached handle.
48794877 */
48804878 spin_lock (& CIFS_I (inode )-> deferred_lock );
48814879 is_deferred = cifs_is_deferred_close (cfile , & dclose );
4882- if (is_deferred && cfile -> deferred_scheduled ) {
4883- cfile -> oplock_break_received = true;
4884- mod_delayed_work (deferredclose_wq , & cfile -> deferred , 0 );
4880+ if (is_deferred &&
4881+ cfile -> deferred_close_scheduled &&
4882+ delayed_work_pending (& cfile -> deferred )) {
4883+ /*
4884+ * If there is no pending work, mod_delayed_work queues new work.
4885+ * So, Increase the ref count to avoid use-after-free.
4886+ */
4887+ if (!mod_delayed_work (deferredclose_wq , & cfile -> deferred , 0 ))
4888+ cifsFileInfo_get (cfile );
48854889 }
48864890 spin_unlock (& CIFS_I (inode )-> deferred_lock );
48874891 _cifsFileInfo_put (cfile , false /* do not wait for ourself */ , false);
0 commit comments