Commit 251090e2 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French
Browse files

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: c5ea3065 ("smb: client: fix data loss due to broken rename(2)")
Signed-off-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.org>
Cc: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent d9dcbbcf
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -2003,8 +2003,21 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
		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);