summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
authorCarlos Maiolino <cmaiolino@redhat.com>2014-12-24 08:51:42 +1100
committerDave Chinner <david@fromorbit.com>2014-12-24 08:51:42 +1100
commitd31a1825450062b85282b4afed1c840fd306d012 (patch)
treee0ef4c10543a9d78088b887c22d79a65d8eda4e0 /fs/xfs/xfs_iops.c
parentdbe1b5ca26396b6c61d711c8ac4de13ebb02e9f6 (diff)
xfs: Add support to RENAME_EXCHANGE flag
Adds a new function named xfs_cross_rename(), responsible for handling requests from sys_renameat2() using RENAME_EXCHANGE flag. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index abb838a565ee..ce80eeb8faa4 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -384,19 +384,23 @@ xfs_vn_rename(
unsigned int flags)
{
struct inode *new_inode = ndentry->d_inode;
+ int omode = 0;
struct xfs_name oname;
struct xfs_name nname;
- /* XFS does not support RENAME_EXCHANGE yet */
- if (flags & ~RENAME_NOREPLACE)
+ if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
return -EINVAL;
- xfs_dentry_to_name(&oname, odentry, 0);
+ /* if we are exchanging files, we need to set i_mode of both files */
+ if (flags & RENAME_EXCHANGE)
+ omode = ndentry->d_inode->i_mode;
+
+ xfs_dentry_to_name(&oname, odentry, omode);
xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode);
return xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
XFS_I(ndir), &nname,
- new_inode ? XFS_I(new_inode) : NULL);
+ new_inode ? XFS_I(new_inode) : NULL, flags);
}
/*