[XFS] embededd struct xfs_imap into xfs_inode
[safe/jmp/linux-2.6] / fs / xfs / xfs_dfrag.c
index 80562b6..75b0cd4 100644 (file)
@@ -41,8 +41,8 @@
 #include "xfs_itable.h"
 #include "xfs_dfrag.h"
 #include "xfs_error.h"
-#include "xfs_mac.h"
 #include "xfs_rw.h"
+#include "xfs_vnodeops.h"
 
 /*
  * Syssgi interface for swapext
@@ -52,76 +52,72 @@ xfs_swapext(
        xfs_swapext_t   __user *sxu)
 {
        xfs_swapext_t   *sxp;
-       xfs_inode_t     *ip=NULL, *tip=NULL;
-       xfs_mount_t     *mp;
-       struct file     *fp = NULL, *tfp = NULL;
-       bhv_vnode_t     *vp, *tvp;
+       xfs_inode_t     *ip, *tip;
+       struct file     *file, *target_file;
        int             error = 0;
 
        sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
        if (!sxp) {
                error = XFS_ERROR(ENOMEM);
-               goto error0;
+               goto out;
        }
 
        if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) {
                error = XFS_ERROR(EFAULT);
-               goto error0;
+               goto out_free_sxp;
        }
 
        /* Pull information for the target fd */
-       if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) ||
-           ((vp = vn_from_inode(fp->f_dentry->d_inode)) == NULL))  {
+       file = fget((int)sxp->sx_fdtarget);
+       if (!file) {
                error = XFS_ERROR(EINVAL);
-               goto error0;
+               goto out_free_sxp;
        }
 
-       ip = xfs_vtoi(vp);
-       if (ip == NULL) {
+       if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) {
                error = XFS_ERROR(EBADF);
-               goto error0;
+               goto out_put_file;
        }
 
-       if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) ||
-           ((tvp = vn_from_inode(tfp->f_dentry->d_inode)) == NULL)) {
+       target_file = fget((int)sxp->sx_fdtmp);
+       if (!target_file) {
                error = XFS_ERROR(EINVAL);
-               goto error0;
+               goto out_put_file;
        }
 
-       tip = xfs_vtoi(tvp);
-       if (tip == NULL) {
+       if (!(target_file->f_mode & FMODE_WRITE) ||
+           (target_file->f_flags & O_APPEND)) {
                error = XFS_ERROR(EBADF);
-               goto error0;
+               goto out_put_target_file;
        }
 
+       ip = XFS_I(file->f_path.dentry->d_inode);
+       tip = XFS_I(target_file->f_path.dentry->d_inode);
+
        if (ip->i_mount != tip->i_mount) {
-               error =  XFS_ERROR(EINVAL);
-               goto error0;
+               error = XFS_ERROR(EINVAL);
+               goto out_put_target_file;
        }
 
        if (ip->i_ino == tip->i_ino) {
-               error =  XFS_ERROR(EINVAL);
-               goto error0;
+               error = XFS_ERROR(EINVAL);
+               goto out_put_target_file;
        }
 
-       mp = ip->i_mount;
-
-       if (XFS_FORCED_SHUTDOWN(mp)) {
-               error =  XFS_ERROR(EIO);
-               goto error0;
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+               error = XFS_ERROR(EIO);
+               goto out_put_target_file;
        }
 
-       error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
-
- error0:
-       if (fp != NULL)
-               fput(fp);
-       if (tfp != NULL)
-               fput(tfp);
-
-       if (sxp != NULL)
-               kmem_free(sxp, sizeof(xfs_swapext_t));
+       error = xfs_swap_extents(ip, tip, sxp);
 
+ out_put_target_file:
+       fput(target_file);
+ out_put_file:
+       fput(file);
+ out_free_sxp:
+       kmem_free(sxp);
+ out:
        return error;
 }
 
@@ -132,10 +128,8 @@ xfs_swap_extents(
        xfs_swapext_t   *sxp)
 {
        xfs_mount_t     *mp;
-       xfs_inode_t     *ips[2];
        xfs_trans_t     *tp;
        xfs_bstat_t     *sbp = &sxp->sx_stat;
-       bhv_vnode_t     *vp, *tvp;
        xfs_ifork_t     *tempifp, *ifp, *tifp;
        int             ilf_fields, tilf_fields;
        static uint     lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
@@ -154,30 +148,17 @@ xfs_swap_extents(
        }
 
        sbp = &sxp->sx_stat;
-       vp = XFS_ITOV(ip);
-       tvp = XFS_ITOV(tip);
-
-       /* Lock in i_ino order */
-       if (ip->i_ino < tip->i_ino) {
-               ips[0] = ip;
-               ips[1] = tip;
-       } else {
-               ips[0] = tip;
-               ips[1] = ip;
-       }
 
-       xfs_lock_inodes(ips, 2, 0, lock_flags);
+       /*
+        * we have to do two separate lock calls here to keep lockdep
+        * happy. If we try to get all the locks in one call, lock will
+        * report false positives when we drop the ILOCK and regain them
+        * below.
+        */
+       xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
+       xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
        locked = 1;
 
-       /* Check permissions */
-       error = xfs_iaccess(ip, S_IWUSR, NULL);
-       if (error)
-               goto error0;
-
-       error = xfs_iaccess(tip, S_IWUSR, NULL);
-       if (error)
-               goto error0;
-
        /* Verify that both files have the same format */
        if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
                error = XFS_ERROR(EINVAL);
@@ -185,8 +166,7 @@ xfs_swap_extents(
        }
 
        /* Verify both files are either real-time or non-realtime */
-       if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
-           (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+       if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
                error = XFS_ERROR(EINVAL);
                goto error0;
        }
@@ -198,13 +178,16 @@ xfs_swap_extents(
                goto error0;
        }
 
-       if (VN_CACHED(tvp) != 0) {
-               xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
-               bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
+       if (VN_CACHED(VFS_I(tip)) != 0) {
+               xfs_inval_cached_trace(tip, 0, -1, 0, -1);
+               error = xfs_flushinval_pages(tip, 0, -1,
+                               FI_REMAPF_LOCKED);
+               if (error)
+                       goto error0;
        }
 
        /* Verify O_DIRECT for ftmp */
-       if (VN_CACHED(tvp) != 0) {
+       if (VN_CACHED(VFS_I(tip)) != 0) {
                error = XFS_ERROR(EINVAL);
                goto error0;
        }
@@ -248,7 +231,7 @@ xfs_swap_extents(
         * vop_read (or write in the case of autogrow) they block on the iolock
         * until we have switched the extents.
         */
-       if (VN_MAPPED(vp)) {
+       if (VN_MAPPED(VFS_I(ip))) {
                error = XFS_ERROR(EBUSY);
                goto error0;
        }
@@ -264,7 +247,7 @@ xfs_swap_extents(
         * fields change.
         */
 
-       bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
+       xfs_tosspages(ip, 0, -1, FI_REMAPF);
 
        tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
        if ((error = xfs_trans_reserve(tp, 0,
@@ -276,7 +259,7 @@ xfs_swap_extents(
                locked = 0;
                goto error0;
        }
-       xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL);
+       xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
 
        /*
         * Count the number of extended attribute blocks
@@ -361,15 +344,11 @@ xfs_swap_extents(
                break;
        }
 
-       /*
-        * Increment vnode ref counts since xfs_trans_commit &
-        * xfs_trans_cancel will both unlock the inodes and
-        * decrement the associated ref counts.
-        */
-       VN_HOLD(vp);
-       VN_HOLD(tvp);
 
+       IHOLD(ip);
        xfs_trans_ijoin(tp, ip, lock_flags);
+
+       IHOLD(tip);
        xfs_trans_ijoin(tp, tip, lock_flags);
 
        xfs_trans_log_inode(tp, ip,  ilf_fields);
@@ -383,7 +362,7 @@ xfs_swap_extents(
                xfs_trans_set_sync(tp);
        }
 
-       error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL);
+       error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
        locked = 0;
 
  error0:
@@ -392,6 +371,6 @@ xfs_swap_extents(
                xfs_iunlock(tip, lock_flags);
        }
        if (tempifp != NULL)
-               kmem_free(tempifp, sizeof(xfs_ifork_t));
+               kmem_free(tempifp);
        return error;
 }