summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_ioctl.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-08-12 14:49:48 +0400
committerBen Myers <bpm@sgi.com>2013-08-13 01:56:06 +0400
commita133d952b44cef278d2da664d742d51ef95f4dd3 (patch)
tree7a6f2d8bfc9be9d29246f2ed94582186331cbd45 /fs/xfs/xfs_ioctl.c
parente546cb79ef7ebe53060369dae665fa449a544353 (diff)
downloadlinux-a133d952b44cef278d2da664d742d51ef95f4dd3.tar.xz
xfs: consolidate extent swap code
So we don't need xfs_dfrag.h in userspace anymore, move the extent swap ioctl structure definition to xfs_fs.h where most of the other ioctl structure definitions are. Now that we don't need separate files for extent swapping, separate the basic file descriptor checking code to xfs_ioctl.c, and the code that does the extent swap operation to xfs_bmap_util.c. This cleanly separates the user interface code from the physical mechanism used to do the extent swap. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_ioctl.c')
-rw-r--r--fs/xfs/xfs_ioctl.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 557c7b8b2425..efb216de5f69 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -35,7 +35,6 @@
#include "xfs_bmap.h"
#include "xfs_bmap_util.h"
#include "xfs_buf_item.h"
-#include "xfs_dfrag.h"
#include "xfs_fsops.h"
#include "xfs_discard.h"
#include "xfs_quota.h"
@@ -1363,6 +1362,75 @@ xfs_ioc_getbmapx(
return 0;
}
+int
+xfs_ioc_swapext(
+ xfs_swapext_t *sxp)
+{
+ xfs_inode_t *ip, *tip;
+ struct fd f, tmp;
+ int error = 0;
+
+ /* Pull information for the target fd */
+ f = fdget((int)sxp->sx_fdtarget);
+ if (!f.file) {
+ error = XFS_ERROR(EINVAL);
+ goto out;
+ }
+
+ if (!(f.file->f_mode & FMODE_WRITE) ||
+ !(f.file->f_mode & FMODE_READ) ||
+ (f.file->f_flags & O_APPEND)) {
+ error = XFS_ERROR(EBADF);
+ goto out_put_file;
+ }
+
+ tmp = fdget((int)sxp->sx_fdtmp);
+ if (!tmp.file) {
+ error = XFS_ERROR(EINVAL);
+ goto out_put_file;
+ }
+
+ if (!(tmp.file->f_mode & FMODE_WRITE) ||
+ !(tmp.file->f_mode & FMODE_READ) ||
+ (tmp.file->f_flags & O_APPEND)) {
+ error = XFS_ERROR(EBADF);
+ goto out_put_tmp_file;
+ }
+
+ if (IS_SWAPFILE(file_inode(f.file)) ||
+ IS_SWAPFILE(file_inode(tmp.file))) {
+ error = XFS_ERROR(EINVAL);
+ goto out_put_tmp_file;
+ }
+
+ ip = XFS_I(file_inode(f.file));
+ tip = XFS_I(file_inode(tmp.file));
+
+ if (ip->i_mount != tip->i_mount) {
+ error = XFS_ERROR(EINVAL);
+ goto out_put_tmp_file;
+ }
+
+ if (ip->i_ino == tip->i_ino) {
+ error = XFS_ERROR(EINVAL);
+ goto out_put_tmp_file;
+ }
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ error = XFS_ERROR(EIO);
+ goto out_put_tmp_file;
+ }
+
+ error = xfs_swap_extents(ip, tip, sxp);
+
+ out_put_tmp_file:
+ fdput(tmp);
+ out_put_file:
+ fdput(f);
+ out:
+ return error;
+}
+
/*
* Note: some of the ioctl's return positive numbers as a
* byte count indicating success, such as readlink_by_handle.
@@ -1507,7 +1575,7 @@ xfs_file_ioctl(
error = mnt_want_write_file(filp);
if (error)
return error;
- error = xfs_swapext(&sxp);
+ error = xfs_ioc_swapext(&sxp);
mnt_drop_write_file(filp);
return -error;
}