Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[sfrench/cifs-2.6.git] / fs / xfs / xfs_bmap_util.c
index 83b1e8c6c18f939e8afcabdb4eb37fd33e459da8..6de8d90041ff0e676e85e559c1b2eef65dd74946 100644 (file)
@@ -702,16 +702,11 @@ xfs_bmap_punch_delalloc_range(
        struct xfs_iext_cursor  icur;
        int                     error = 0;
 
-       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
-       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
-               error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
-               if (error)
-                       return error;
-       }
+       ASSERT(ifp->if_flags & XFS_IFEXTENTS);
 
+       xfs_ilock(ip, XFS_ILOCK_EXCL);
        if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got))
-               return 0;
+               goto out_unlock;
 
        while (got.br_startoff + got.br_blockcount > start_fsb) {
                del = got;
@@ -735,6 +730,8 @@ xfs_bmap_punch_delalloc_range(
                        break;
        }
 
+out_unlock:
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
        return error;
 }
 
@@ -872,13 +869,11 @@ xfs_alloc_file_space(
        xfs_filblks_t           allocatesize_fsb;
        xfs_extlen_t            extsz, temp;
        xfs_fileoff_t           startoffset_fsb;
-       xfs_fsblock_t           firstfsb;
        int                     nimaps;
        int                     quota_flag;
        int                     rt;
        xfs_trans_t             *tp;
        xfs_bmbt_irec_t         imaps[1], *imapp;
-       struct xfs_defer_ops    dfops;
        uint                    qblocks, resblks, resrtextents;
        int                     error;
 
@@ -971,20 +966,15 @@ xfs_alloc_file_space(
 
                xfs_trans_ijoin(tp, ip, 0);
 
-               xfs_defer_init(&dfops, &firstfsb);
                error = xfs_bmapi_write(tp, ip, startoffset_fsb,
-                                       allocatesize_fsb, alloc_type, &firstfsb,
-                                       resblks, imapp, &nimaps, &dfops);
+                                       allocatesize_fsb, alloc_type, resblks,
+                                       imapp, &nimaps);
                if (error)
                        goto error0;
 
                /*
                 * Complete the transaction
                 */
-               error = xfs_defer_finish(&tp, &dfops);
-               if (error)
-                       goto error0;
-
                error = xfs_trans_commit(tp);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                if (error)
@@ -1003,8 +993,7 @@ xfs_alloc_file_space(
 
        return error;
 
-error0:        /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
-       xfs_defer_cancel(&dfops);
+error0:        /* unlock inode, unreserve quota blocks, cancel trans */
        xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag);
 
 error1:        /* Just cancel transaction */
@@ -1022,8 +1011,6 @@ xfs_unmap_extent(
 {
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_trans        *tp;
-       struct xfs_defer_ops    dfops;
-       xfs_fsblock_t           firstfsb;
        uint                    resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
        int                     error;
 
@@ -1041,24 +1028,15 @@ xfs_unmap_extent(
 
        xfs_trans_ijoin(tp, ip, 0);
 
-       xfs_defer_init(&dfops, &firstfsb);
-       error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb,
-                       &dfops, done);
-       if (error)
-               goto out_bmap_cancel;
-
-       xfs_defer_ijoin(&dfops, ip);
-       error = xfs_defer_finish(&tp, &dfops);
+       error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done);
        if (error)
-               goto out_bmap_cancel;
+               goto out_trans_cancel;
 
        error = xfs_trans_commit(tp);
 out_unlock:
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        return error;
 
-out_bmap_cancel:
-       xfs_defer_cancel(&dfops);
 out_trans_cancel:
        xfs_trans_cancel(tp);
        goto out_unlock;
@@ -1279,7 +1257,7 @@ xfs_prepare_shift(
         * we've flushed all the dirty data out to disk to avoid having
         * CoW extents at the wrong offsets.
         */
-       if (xfs_is_reflink_inode(ip)) {
+       if (xfs_inode_has_cow_data(ip)) {
                error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF,
                                true);
                if (error)
@@ -1310,8 +1288,6 @@ xfs_collapse_file_space(
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_trans        *tp;
        int                     error;
-       struct xfs_defer_ops    dfops;
-       xfs_fsblock_t           first_block;
        xfs_fileoff_t           next_fsb = XFS_B_TO_FSB(mp, offset + len);
        xfs_fileoff_t           shift_fsb = XFS_B_TO_FSB(mp, len);
        uint                    resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
@@ -1344,22 +1320,16 @@ xfs_collapse_file_space(
                        goto out_trans_cancel;
                xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 
-               xfs_defer_init(&dfops, &first_block);
                error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb,
-                               &done, &first_block, &dfops);
+                               &done);
                if (error)
-                       goto out_bmap_cancel;
+                       goto out_trans_cancel;
 
-               error = xfs_defer_finish(&tp, &dfops);
-               if (error)
-                       goto out_bmap_cancel;
                error = xfs_trans_commit(tp);
        }
 
        return error;
 
-out_bmap_cancel:
-       xfs_defer_cancel(&dfops);
 out_trans_cancel:
        xfs_trans_cancel(tp);
        return error;
@@ -1386,8 +1356,6 @@ xfs_insert_file_space(
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_trans        *tp;
        int                     error;
-       struct xfs_defer_ops    dfops;
-       xfs_fsblock_t           first_block;
        xfs_fileoff_t           stop_fsb = XFS_B_TO_FSB(mp, offset);
        xfs_fileoff_t           next_fsb = NULLFSBLOCK;
        xfs_fileoff_t           shift_fsb = XFS_B_TO_FSB(mp, len);
@@ -1423,22 +1391,17 @@ xfs_insert_file_space(
 
                xfs_ilock(ip, XFS_ILOCK_EXCL);
                xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-               xfs_defer_init(&dfops, &first_block);
                error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb,
-                               &done, stop_fsb, &first_block, &dfops);
+                               &done, stop_fsb);
                if (error)
-                       goto out_bmap_cancel;
+                       goto out_trans_cancel;
 
-               error = xfs_defer_finish(&tp, &dfops);
-               if (error)
-                       goto out_bmap_cancel;
                error = xfs_trans_commit(tp);
        }
 
        return error;
 
-out_bmap_cancel:
-       xfs_defer_cancel(&dfops);
+out_trans_cancel:
        xfs_trans_cancel(tp);
        return error;
 }
@@ -1566,14 +1529,13 @@ xfs_swap_extent_rmap(
        struct xfs_inode                *ip,
        struct xfs_inode                *tip)
 {
+       struct xfs_trans                *tp = *tpp;
        struct xfs_bmbt_irec            irec;
        struct xfs_bmbt_irec            uirec;
        struct xfs_bmbt_irec            tirec;
        xfs_fileoff_t                   offset_fsb;
        xfs_fileoff_t                   end_fsb;
        xfs_filblks_t                   count_fsb;
-       xfs_fsblock_t                   firstfsb;
-       struct xfs_defer_ops            dfops;
        int                             error;
        xfs_filblks_t                   ilen;
        xfs_filblks_t                   rlen;
@@ -1609,7 +1571,7 @@ xfs_swap_extent_rmap(
 
                /* Unmap the old blocks in the source file. */
                while (tirec.br_blockcount) {
-                       xfs_defer_init(&dfops, &firstfsb);
+                       ASSERT(tp->t_firstblock == NULLFSBLOCK);
                        trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec);
 
                        /* Read extent from the source file */
@@ -1618,7 +1580,7 @@ xfs_swap_extent_rmap(
                                        tirec.br_blockcount, &irec,
                                        &nimaps, 0);
                        if (error)
-                               goto out_defer;
+                               goto out;
                        ASSERT(nimaps == 1);
                        ASSERT(tirec.br_startoff == irec.br_startoff);
                        trace_xfs_swap_extent_rmap_remap_piece(ip, &irec);
@@ -1631,33 +1593,29 @@ xfs_swap_extent_rmap(
                        trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec);
 
                        /* Remove the mapping from the donor file. */
-                       error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops,
-                                       tip, &uirec);
+                       error = xfs_bmap_unmap_extent(tp, tip, &uirec);
                        if (error)
-                               goto out_defer;
+                               goto out;
 
                        /* Remove the mapping from the source file. */
-                       error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops,
-                                       ip, &irec);
+                       error = xfs_bmap_unmap_extent(tp, ip, &irec);
                        if (error)
-                               goto out_defer;
+                               goto out;
 
                        /* Map the donor file's blocks into the source file. */
-                       error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops,
-                                       ip, &uirec);
+                       error = xfs_bmap_map_extent(tp, ip, &uirec);
                        if (error)
-                               goto out_defer;
+                               goto out;
 
                        /* Map the source file's blocks into the donor file. */
-                       error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops,
-                                       tip, &irec);
+                       error = xfs_bmap_map_extent(tp, tip, &irec);
                        if (error)
-                               goto out_defer;
+                               goto out;
 
-                       xfs_defer_ijoin(&dfops, ip);
-                       error = xfs_defer_finish(tpp, &dfops);
+                       error = xfs_defer_finish(tpp);
+                       tp = *tpp;
                        if (error)
-                               goto out_defer;
+                               goto out;
 
                        tirec.br_startoff += rlen;
                        if (tirec.br_startblock != HOLESTARTBLOCK &&
@@ -1674,8 +1632,6 @@ xfs_swap_extent_rmap(
        tip->i_d.di_flags2 = tip_flags2;
        return 0;
 
-out_defer:
-       xfs_defer_cancel(&dfops);
 out:
        trace_xfs_swap_extent_rmap_error(ip, error, _RET_IP_);
        tip->i_d.di_flags2 = tip_flags2;
@@ -1691,7 +1647,6 @@ xfs_swap_extent_forks(
        int                     *src_log_flags,
        int                     *target_log_flags)
 {
-       struct xfs_ifork        tempifp, *ifp, *tifp;
        xfs_filblks_t           aforkblks = 0;
        xfs_filblks_t           taforkblks = 0;
        xfs_extnum_t            junk;
@@ -1733,11 +1688,7 @@ xfs_swap_extent_forks(
        /*
         * Swap the data forks of the inodes
         */
-       ifp = &ip->i_df;
-       tifp = &tip->i_df;
-       tempifp = *ifp;         /* struct copy */
-       *ifp = *tifp;           /* struct copy */
-       *tifp = tempifp;        /* struct copy */
+       swap(ip->i_df, tip->i_df);
 
        /*
         * Fix the on-disk inode values
@@ -1746,13 +1697,8 @@ xfs_swap_extent_forks(
        ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks;
        tip->i_d.di_nblocks = tmp + taforkblks - aforkblks;
 
-       tmp = (uint64_t) ip->i_d.di_nextents;
-       ip->i_d.di_nextents = tip->i_d.di_nextents;
-       tip->i_d.di_nextents = tmp;
-
-       tmp = (uint64_t) ip->i_d.di_format;
-       ip->i_d.di_format = tip->i_d.di_format;
-       tip->i_d.di_format = tmp;
+       swap(ip->i_d.di_nextents, tip->i_d.di_nextents);
+       swap(ip->i_d.di_format, tip->i_d.di_format);
 
        /*
         * The extents in the source inode could still contain speculative
@@ -1846,7 +1792,6 @@ xfs_swap_extents(
        int                     src_log_flags, target_log_flags;
        int                     error = 0;
        int                     lock_flags;
-       struct xfs_ifork        *cowfp;
        uint64_t                f;
        int                     resblks = 0;
 
@@ -1987,18 +1932,11 @@ xfs_swap_extents(
 
        /* Swap the cow forks. */
        if (xfs_sb_version_hasreflink(&mp->m_sb)) {
-               xfs_extnum_t    extnum;
-
                ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS);
                ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS);
 
-               extnum = ip->i_cnextents;
-               ip->i_cnextents = tip->i_cnextents;
-               tip->i_cnextents = extnum;
-
-               cowfp = ip->i_cowfp;
-               ip->i_cowfp = tip->i_cowfp;
-               tip->i_cowfp = cowfp;
+               swap(ip->i_cnextents, tip->i_cnextents);
+               swap(ip->i_cowfp, tip->i_cowfp);
 
                if (ip->i_cowfp && ip->i_cowfp->if_bytes)
                        xfs_inode_set_cowblocks_tag(ip);