cifs: Fix the target file was deleted when rename failed.
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>
This commit is contained in:
parent
5391b8e1b7
commit
9ffad9263b
@ -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;
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user