Skip to content

Commit aefd664

Browse files
committed
smb: client: fix file open check in __cifs_unlink()
JIRA: https://issues.redhat.com/browse/RHEL-114295 commit 251090e Author: Paulo Alcantara <pc@manguebit.org> Date: Thu Sep 18 12:30:32 2025 -0300 smb: client: fix file open check in __cifs_unlink() Fix the file open check to decide whether or not silly-rename the file in SMB2+. Fixes: c5ea306 ("smb: client: fix data loss due to broken rename(2)") Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: Frank Sorenson <sorenson@redhat.com> Reviewed-by: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Paulo Alcantara <paalcant@redhat.com>
1 parent b6bdffa commit aefd664

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

fs/smb/client/inode.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,8 +1983,21 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
19831983
goto psx_del_no_retry;
19841984
}
19851985

1986-
if (sillyrename || (server->vals->protocol_id > SMB10_PROT_ID &&
1987-
d_is_positive(dentry) && d_count(dentry) > 2))
1986+
/* For SMB2+, if the file is open, we always perform a silly rename.
1987+
*
1988+
* We check for d_count() right after calling
1989+
* cifs_close_deferred_file_under_dentry() to make sure that the
1990+
* dentry's refcount gets dropped in case the file had any deferred
1991+
* close.
1992+
*/
1993+
if (!sillyrename && server->vals->protocol_id > SMB10_PROT_ID) {
1994+
spin_lock(&dentry->d_lock);
1995+
if (d_count(dentry) > 1)
1996+
sillyrename = true;
1997+
spin_unlock(&dentry->d_lock);
1998+
}
1999+
2000+
if (sillyrename)
19882001
rc = -EBUSY;
19892002
else
19902003
rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);

0 commit comments

Comments
 (0)