summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@manguebit.org>2025-09-18 12:30:32 -0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-09-25 11:16:53 +0200
commit9617c3ede9ffe488eb8ba18071f4d9f6e869d32b (patch)
tree6f6135c50ac73f9280d2dab721330fd4e4ec6743
parent5ba113d0b04986a6fcb873fb5ee1b0e9b60382fa (diff)
smb: client: fix file open check in __cifs_unlink()
[ Upstream commit 251090e2c2c1be60607d1c521af2c993f04d4f61 ] Fix the file open check to decide whether or not silly-rename the file in SMB2+. Fixes: c5ea3065586d ("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: Sasha Levin <sashal@kernel.org>
-rw-r--r--fs/smb/client/inode.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 1703f1285d36..0f0d2dae6283 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -2003,8 +2003,21 @@ retry_std_delete:
goto psx_del_no_retry;
}
- if (sillyrename || (server->vals->protocol_id > SMB10_PROT_ID &&
- d_is_positive(dentry) && d_count(dentry) > 2))
+ /* For SMB2+, if the file is open, we always perform a silly rename.
+ *
+ * We check for d_count() right after calling
+ * cifs_close_deferred_file_under_dentry() to make sure that the
+ * dentry's refcount gets dropped in case the file had any deferred
+ * close.
+ */
+ if (!sillyrename && server->vals->protocol_id > SMB10_PROT_ID) {
+ spin_lock(&dentry->d_lock);
+ if (d_count(dentry) > 1)
+ sillyrename = true;
+ spin_unlock(&dentry->d_lock);
+ }
+
+ if (sillyrename)
rc = -EBUSY;
else
rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);