[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 7 Jul 2020 17:15:50 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Hulk Robot <hulkci@...wei.com>,
Zhang Xiaoxu <zhangxiaoxu5@...wei.com>,
Steve French <stfrench@...rosoft.com>,
Aurelien Aptel <aaptel@...e.com>
Subject: [PATCH 4.14 23/27] cifs: Fix the target file was deleted when rename failed.
From: Zhang Xiaoxu <zhangxiaoxu5@...wei.com>
commit 9ffad9263b467efd8f8dc7ae1941a0a655a2bab2 upstream.
When xfstest generic/035, we found the target file was deleted
if the rename return -EACESS.
In cifs_rename2, we unlink the positive target dentry if rename
failed with EACESS or EEXIST, even if the target dentry is positived
before rename. Then the existing file was deleted.
We should just delete the target file which created during the
rename.
Reported-by: Hulk Robot <hulkci@...wei.com>
Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@...wei.com>
Cc: stable@...r.kernel.org
Signed-off-by: Steve French <stfrench@...rosoft.com>
Reviewed-by: Aurelien Aptel <aaptel@...e.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
fs/cifs/inode.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1778,6 +1778,7 @@ cifs_rename2(struct inode *source_dir, s
FILE_UNIX_BASIC_INFO *info_buf_target;
unsigned int xid;
int rc, tmprc;
+ bool new_target = d_really_is_negative(target_dentry);
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
@@ -1854,8 +1855,13 @@ cifs_rename2(struct inode *source_dir, s
*/
unlink_target:
- /* Try unlinking the target dentry if it's not negative */
- if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {
+ /*
+ * If the target dentry was created during the rename, try
+ * unlinking it if it's not negative
+ */
+ if (new_target &&
+ d_really_is_positive(target_dentry) &&
+ (rc == -EACCES || rc == -EEXIST)) {
if (d_is_dir(target_dentry))
tmprc = cifs_rmdir(target_dir, target_dentry);
else
Powered by blists - more mailing lists