Skip to content

Commit

Permalink
cifs: Fix the target file was deleted when rename failed.
Browse files Browse the repository at this point in the history
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@huawei.com>
Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
  • Loading branch information
Zhang Xiaoxu authored and Steve French committed Jul 2, 2020
1 parent 5391b8e commit 9ffad92
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
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;
Expand Down Expand Up @@ -2120,8 +2121,13 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
*/

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
Expand Down

0 comments on commit 9ffad92

Please sign in to comment.