@@ -731,14 +731,14 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
731731 oplock = fid -> pending_open -> oplock ;
732732 list_del (& fid -> pending_open -> olist );
733733
734- fid -> purge_cache = false;
735- server -> ops -> set_fid (cfile , fid , oplock );
736-
737734 list_add (& cfile -> tlist , & tcon -> openFileList );
738735 atomic_inc (& tcon -> num_local_opens );
739736
740737 /* if readable file instance put first in list*/
741738 spin_lock (& cinode -> open_file_lock );
739+ fid -> purge_cache = false;
740+ server -> ops -> set_fid (cfile , fid , oplock );
741+
742742 if (file -> f_mode & FMODE_READ )
743743 list_add (& cfile -> flist , & cinode -> openFileList );
744744 else
@@ -1410,7 +1410,8 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
14101410 oplock = 0 ;
14111411 }
14121412
1413- server -> ops -> set_fid (cfile , & cfile -> fid , oplock );
1413+ scoped_guard (spinlock , & cinode -> open_file_lock )
1414+ server -> ops -> set_fid (cfile , & cfile -> fid , oplock );
14141415 if (oparms .reconnect )
14151416 cifs_relock_file (cfile );
14161417
@@ -1437,11 +1438,11 @@ smb2_can_defer_close(struct inode *inode, struct cifs_deferred_close *dclose)
14371438{
14381439 struct cifs_sb_info * cifs_sb = CIFS_SB (inode -> i_sb );
14391440 struct cifsInodeInfo * cinode = CIFS_I (inode );
1441+ unsigned int oplock = READ_ONCE (cinode -> oplock );
14401442
1441- return (cifs_sb -> ctx -> closetimeo && cinode -> lease_granted && dclose &&
1442- (cinode -> oplock == CIFS_CACHE_RHW_FLG ||
1443- cinode -> oplock == CIFS_CACHE_RH_FLG ) &&
1444- !test_bit (CIFS_INO_CLOSE_ON_LOCK , & cinode -> flags ));
1443+ return cifs_sb -> ctx -> closetimeo && cinode -> lease_granted && dclose &&
1444+ (oplock == CIFS_CACHE_RHW_FLG || oplock == CIFS_CACHE_RH_FLG ) &&
1445+ !test_bit (CIFS_INO_CLOSE_ON_LOCK , & cinode -> flags );
14451446
14461447}
14471448
@@ -2371,7 +2372,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
23712372 cifs_zap_mapping (inode );
23722373 cifs_dbg (FYI , "Set no oplock for inode=%p due to mand locks\n" ,
23732374 inode );
2374- CIFS_I (inode )-> oplock = 0 ;
2375+ cifs_reset_oplock ( CIFS_I (inode )) ;
23752376 }
23762377
23772378 rc = server -> ops -> mand_lock (xid , cfile , flock -> fl_start , length ,
@@ -2930,7 +2931,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
29302931 cifs_zap_mapping (inode );
29312932 cifs_dbg (FYI , "Set Oplock/Lease to NONE for inode=%p after write\n" ,
29322933 inode );
2933- cinode -> oplock = 0 ;
2934+ cifs_reset_oplock ( cinode ) ;
29342935 }
29352936out :
29362937 cifs_put_writer (cinode );
@@ -2966,7 +2967,7 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
29662967 cifs_dbg (FYI ,
29672968 "Set no oplock for inode=%p after a write operation\n" ,
29682969 inode );
2969- cinode -> oplock = 0 ;
2970+ cifs_reset_oplock ( cinode ) ;
29702971 }
29712972 return written ;
29722973 }
@@ -3154,9 +3155,11 @@ void cifs_oplock_break(struct work_struct *work)
31543155 struct super_block * sb = inode -> i_sb ;
31553156 struct cifs_sb_info * cifs_sb = CIFS_SB (sb );
31563157 struct cifsInodeInfo * cinode = CIFS_I (inode );
3158+ bool cache_read , cache_write , cache_handle ;
31573159 struct cifs_tcon * tcon ;
31583160 struct TCP_Server_Info * server ;
31593161 struct tcon_link * tlink ;
3162+ unsigned int oplock ;
31603163 int rc = 0 ;
31613164 bool purge_cache = false, oplock_break_cancelled ;
31623165 __u64 persistent_fid , volatile_fid ;
@@ -3177,29 +3180,40 @@ void cifs_oplock_break(struct work_struct *work)
31773180 tcon = tlink_tcon (tlink );
31783181 server = tcon -> ses -> server ;
31793182
3180- server -> ops -> downgrade_oplock (server , cinode , cfile -> oplock_level ,
3181- cfile -> oplock_epoch , & purge_cache );
3183+ scoped_guard (spinlock , & cinode -> open_file_lock ) {
3184+ unsigned int sbflags = cifs_sb -> mnt_cifs_flags ;
3185+
3186+ server -> ops -> downgrade_oplock (server , cinode , cfile -> oplock_level ,
3187+ cfile -> oplock_epoch , & purge_cache );
3188+ oplock = READ_ONCE (cinode -> oplock );
3189+ cache_read = (oplock & CIFS_CACHE_READ_FLG ) ||
3190+ (sbflags & CIFS_MOUNT_RO_CACHE );
3191+ cache_write = (oplock & CIFS_CACHE_WRITE_FLG ) ||
3192+ (sbflags & CIFS_MOUNT_RW_CACHE );
3193+ cache_handle = oplock & CIFS_CACHE_HANDLE_FLG ;
3194+ }
31823195
3183- if (!CIFS_CACHE_WRITE (cinode ) && CIFS_CACHE_READ (cinode ) &&
3184- cifs_has_mand_locks (cinode )) {
3196+ if (!cache_write && cache_read && cifs_has_mand_locks (cinode )) {
31853197 cifs_dbg (FYI , "Reset oplock to None for inode=%p due to mand locks\n" ,
31863198 inode );
3187- cinode -> oplock = 0 ;
3199+ cifs_reset_oplock (cinode );
3200+ oplock = 0 ;
3201+ cache_read = cache_write = cache_handle = false;
31883202 }
31893203
31903204 if (S_ISREG (inode -> i_mode )) {
3191- if (CIFS_CACHE_READ ( cinode ) )
3205+ if (cache_read )
31923206 break_lease (inode , O_RDONLY );
31933207 else
31943208 break_lease (inode , O_WRONLY );
31953209 rc = filemap_fdatawrite (inode -> i_mapping );
3196- if (!CIFS_CACHE_READ ( cinode ) || purge_cache ) {
3210+ if (!cache_read || purge_cache ) {
31973211 rc = filemap_fdatawait (inode -> i_mapping );
31983212 mapping_set_error (inode -> i_mapping , rc );
31993213 cifs_zap_mapping (inode );
32003214 }
32013215 cifs_dbg (FYI , "Oplock flush inode %p rc %d\n" , inode , rc );
3202- if (CIFS_CACHE_WRITE ( cinode ) )
3216+ if (cache_write )
32033217 goto oplock_break_ack ;
32043218 }
32053219
@@ -3214,7 +3228,7 @@ void cifs_oplock_break(struct work_struct *work)
32143228 * So, new open will not use cached handle.
32153229 */
32163230
3217- if (!CIFS_CACHE_HANDLE ( cinode ) && !list_empty (& cinode -> deferred_closes ))
3231+ if (!cache_handle && !list_empty (& cinode -> deferred_closes ))
32183232 cifs_close_deferred_file (cinode );
32193233
32203234 persistent_fid = cfile -> fid .persistent_fid ;
@@ -3232,7 +3246,8 @@ void cifs_oplock_break(struct work_struct *work)
32323246 if (!oplock_break_cancelled && !list_empty (& cinode -> openFileList )) {
32333247 spin_unlock (& cinode -> open_file_lock );
32343248 rc = server -> ops -> oplock_response (tcon , persistent_fid ,
3235- volatile_fid , net_fid , cinode );
3249+ volatile_fid , net_fid ,
3250+ cinode , oplock );
32363251 cifs_dbg (FYI , "Oplock release rc = %d\n" , rc );
32373252 } else
32383253 spin_unlock (& cinode -> open_file_lock );
0 commit comments