@@ -1931,7 +1931,7 @@ cifs_drop_nlink(struct inode *inode)
19311931 * but will return the EACCES to the caller. Note that the VFS does not call
19321932 * unlink on negative dentries currently.
19331933 */
1934- int cifs_unlink (struct inode * dir , struct dentry * dentry )
1934+ static int __cifs_unlink (struct inode * dir , struct dentry * dentry , bool sillyrename )
19351935{
19361936 int rc = 0 ;
19371937 unsigned int xid ;
@@ -2003,7 +2003,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
20032003 goto psx_del_no_retry ;
20042004 }
20052005
2006- rc = server -> ops -> unlink (xid , tcon , full_path , cifs_sb , dentry );
2006+ if (sillyrename || (server -> vals -> protocol_id > SMB10_PROT_ID &&
2007+ d_is_positive (dentry ) && d_count (dentry ) > 2 ))
2008+ rc = - EBUSY ;
2009+ else
2010+ rc = server -> ops -> unlink (xid , tcon , full_path , cifs_sb , dentry );
20072011
20082012psx_del_no_retry :
20092013 if (!rc ) {
@@ -2071,6 +2075,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
20712075 return rc ;
20722076}
20732077
2078+ int cifs_unlink (struct inode * dir , struct dentry * dentry )
2079+ {
2080+ return __cifs_unlink (dir , dentry , false);
2081+ }
2082+
20742083static int
20752084cifs_mkdir_qinfo (struct inode * parent , struct dentry * dentry , umode_t mode ,
20762085 const char * full_path , struct cifs_sb_info * cifs_sb ,
@@ -2358,14 +2367,16 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
23582367 rc = server -> ops -> rmdir (xid , tcon , full_path , cifs_sb );
23592368 cifs_put_tlink (tlink );
23602369
2370+ cifsInode = CIFS_I (d_inode (direntry ));
2371+
23612372 if (!rc ) {
2373+ set_bit (CIFS_INO_DELETE_PENDING , & cifsInode -> flags );
23622374 spin_lock (& d_inode (direntry )-> i_lock );
23632375 i_size_write (d_inode (direntry ), 0 );
23642376 clear_nlink (d_inode (direntry ));
23652377 spin_unlock (& d_inode (direntry )-> i_lock );
23662378 }
23672379
2368- cifsInode = CIFS_I (d_inode (direntry ));
23692380 /* force revalidate to go get info when needed */
23702381 cifsInode -> time = 0 ;
23712382
@@ -2458,8 +2469,11 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
24582469 }
24592470#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
24602471do_rename_exit :
2461- if (rc == 0 )
2472+ if (rc == 0 ) {
24622473 d_move (from_dentry , to_dentry );
2474+ /* Force a new lookup */
2475+ d_drop (from_dentry );
2476+ }
24632477 cifs_put_tlink (tlink );
24642478 return rc ;
24652479}
@@ -2470,6 +2484,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
24702484 struct dentry * target_dentry , unsigned int flags )
24712485{
24722486 const char * from_name , * to_name ;
2487+ struct TCP_Server_Info * server ;
24732488 void * page1 , * page2 ;
24742489 struct cifs_sb_info * cifs_sb ;
24752490 struct tcon_link * tlink ;
@@ -2505,6 +2520,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
25052520 if (IS_ERR (tlink ))
25062521 return PTR_ERR (tlink );
25072522 tcon = tlink_tcon (tlink );
2523+ server = tcon -> ses -> server ;
25082524
25092525 page1 = alloc_dentry_path ();
25102526 page2 = alloc_dentry_path ();
@@ -2591,19 +2607,53 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
25912607
25922608unlink_target :
25932609#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2594-
2595- /* Try unlinking the target dentry if it's not negative */
2596- if (d_really_is_positive (target_dentry ) && (rc == - EACCES || rc == - EEXIST )) {
2597- if (d_is_dir (target_dentry ))
2598- tmprc = cifs_rmdir (target_dir , target_dentry );
2599- else
2600- tmprc = cifs_unlink (target_dir , target_dentry );
2601- if (tmprc )
2602- goto cifs_rename_exit ;
2603- rc = cifs_do_rename (xid , source_dentry , from_name ,
2604- target_dentry , to_name );
2605- if (!rc )
2606- rehash = false;
2610+ if (d_really_is_positive (target_dentry )) {
2611+ if (!rc ) {
2612+ struct inode * inode = d_inode (target_dentry );
2613+ /*
2614+ * Samba and ksmbd servers allow renaming a target
2615+ * directory that is open, so make sure to update
2616+ * ->i_nlink and then mark it as delete pending.
2617+ */
2618+ if (S_ISDIR (inode -> i_mode )) {
2619+ drop_cached_dir_by_name (xid , tcon , to_name , cifs_sb );
2620+ spin_lock (& inode -> i_lock );
2621+ i_size_write (inode , 0 );
2622+ clear_nlink (inode );
2623+ spin_unlock (& inode -> i_lock );
2624+ set_bit (CIFS_INO_DELETE_PENDING , & CIFS_I (inode )-> flags );
2625+ CIFS_I (inode )-> time = 0 ; /* force reval */
2626+ inode_set_ctime_current (inode );
2627+ inode_set_mtime_to_ts (inode , inode_set_ctime_current (inode ));
2628+ }
2629+ } else if (rc == - EACCES || rc == - EEXIST ) {
2630+ /*
2631+ * Rename failed, possibly due to a busy target.
2632+ * Retry it by unliking the target first.
2633+ */
2634+ if (d_is_dir (target_dentry )) {
2635+ tmprc = cifs_rmdir (target_dir , target_dentry );
2636+ } else {
2637+ tmprc = __cifs_unlink (target_dir , target_dentry ,
2638+ server -> vals -> protocol_id > SMB10_PROT_ID );
2639+ }
2640+ if (tmprc ) {
2641+ /*
2642+ * Some servers will return STATUS_ACCESS_DENIED
2643+ * or STATUS_DIRECTORY_NOT_EMPTY when failing to
2644+ * rename a non-empty directory. Make sure to
2645+ * propagate the appropriate error back to
2646+ * userspace.
2647+ */
2648+ if (tmprc == - EEXIST || tmprc == - ENOTEMPTY )
2649+ rc = tmprc ;
2650+ goto cifs_rename_exit ;
2651+ }
2652+ rc = cifs_do_rename (xid , source_dentry , from_name ,
2653+ target_dentry , to_name );
2654+ if (!rc )
2655+ rehash = false;
2656+ }
26072657 }
26082658
26092659 /* force revalidate to go get info when needed */
@@ -2629,6 +2679,8 @@ cifs_dentry_needs_reval(struct dentry *dentry)
26292679 struct cifs_tcon * tcon = cifs_sb_master_tcon (cifs_sb );
26302680 struct cached_fid * cfid = NULL ;
26312681
2682+ if (test_bit (CIFS_INO_DELETE_PENDING , & cifs_i -> flags ))
2683+ return false;
26322684 if (cifs_i -> time == 0 )
26332685 return true;
26342686
0 commit comments