Merge git://www.linux-watchdog.org/linux-watchdog
[cascardo/linux.git] / fs / xfs / xfs_bmap_util.c
index a52bbd3..0f34886 100644 (file)
@@ -75,28 +75,20 @@ xfs_bmap_finish(
        xfs_efi_log_item_t      *efi;           /* extent free intention */
        int                     error;          /* error return value */
        xfs_bmap_free_item_t    *free;          /* free extent item */
-       struct xfs_trans_res    tres;           /* new log reservation */
        xfs_mount_t             *mp;            /* filesystem mount structure */
        xfs_bmap_free_item_t    *next;          /* next item on free list */
-       xfs_trans_t             *ntp;           /* new transaction pointer */
 
        ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
        if (flist->xbf_count == 0) {
                *committed = 0;
                return 0;
        }
-       ntp = *tp;
-       efi = xfs_trans_get_efi(ntp, flist->xbf_count);
+       efi = xfs_trans_get_efi(*tp, flist->xbf_count);
        for (free = flist->xbf_first; free; free = free->xbfi_next)
-               xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock,
+               xfs_trans_log_efi_extent(*tp, efi, free->xbfi_startblock,
                        free->xbfi_blockcount);
 
-       tres.tr_logres = ntp->t_log_res;
-       tres.tr_logcount = ntp->t_log_count;
-       tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-       ntp = xfs_trans_dup(*tp);
-       error = xfs_trans_commit(*tp, 0);
-       *tp = ntp;
+       error = xfs_trans_roll(tp, NULL);
        *committed = 1;
        /*
         * We have a new transaction, so we should return committed=1,
@@ -105,19 +97,10 @@ xfs_bmap_finish(
        if (error)
                return error;
 
-       /*
-        * transaction commit worked ok so we can drop the extra ticket
-        * reference that we gained in xfs_trans_dup()
-        */
-       xfs_log_ticket_put(ntp->t_ticket);
-
-       error = xfs_trans_reserve(ntp, &tres, 0, 0);
-       if (error)
-               return error;
-       efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count);
+       efd = xfs_trans_get_efd(*tp, efi, flist->xbf_count);
        for (free = flist->xbf_first; free != NULL; free = next) {
                next = free->xbfi_next;
-               if ((error = xfs_free_extent(ntp, free->xbfi_startblock,
+               if ((error = xfs_free_extent(*tp, free->xbfi_startblock,
                                free->xbfi_blockcount))) {
                        /*
                         * The bmap free list will be cleaned up at a
@@ -127,7 +110,7 @@ xfs_bmap_finish(
                         * happens, since this transaction may not be
                         * dirty yet.
                         */
-                       mp = ntp->t_mountp;
+                       mp = (*tp)->t_mountp;
                        if (!XFS_FORCED_SHUTDOWN(mp))
                                xfs_force_shutdown(mp,
                                                   (error == -EFSCORRUPTED) ?
@@ -135,7 +118,7 @@ xfs_bmap_finish(
                                                   SHUTDOWN_META_IO_ERROR);
                        return error;
                }
-               xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
+               xfs_trans_log_efd_extent(*tp, efd, free->xbfi_startblock,
                        free->xbfi_blockcount);
                xfs_bmap_del_free(flist, NULL, free);
        }
@@ -878,7 +861,7 @@ xfs_free_eofblocks(
 
                if (need_iolock) {
                        if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
-                               xfs_trans_cancel(tp, 0);
+                               xfs_trans_cancel(tp);
                                return -EAGAIN;
                        }
                }
@@ -886,7 +869,7 @@ xfs_free_eofblocks(
                error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
                if (error) {
                        ASSERT(XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp, 0);
+                       xfs_trans_cancel(tp);
                        if (need_iolock)
                                xfs_iunlock(ip, XFS_IOLOCK_EXCL);
                        return error;
@@ -908,12 +891,9 @@ xfs_free_eofblocks(
                         * If we get an error at this point we simply don't
                         * bother truncating the file.
                         */
-                       xfs_trans_cancel(tp,
-                                        (XFS_TRANS_RELEASE_LOG_RES |
-                                         XFS_TRANS_ABORT));
+                       xfs_trans_cancel(tp);
                } else {
-                       error = xfs_trans_commit(tp,
-                                               XFS_TRANS_RELEASE_LOG_RES);
+                       error = xfs_trans_commit(tp);
                        if (!error)
                                xfs_inode_clear_eofblocks_tag(ip);
                }
@@ -1026,7 +1006,7 @@ xfs_alloc_file_space(
                         * Free the transaction structure.
                         */
                        ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp, 0);
+                       xfs_trans_cancel(tp);
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1053,7 +1033,7 @@ xfs_alloc_file_space(
                        goto error0;
                }
 
-               error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+               error = xfs_trans_commit(tp);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                if (error) {
                        break;
@@ -1077,7 +1057,7 @@ error0:   /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
        xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag);
 
 error1:        /* Just cancel transaction */
-       xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
+       xfs_trans_cancel(tp);
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        return error;
 }
@@ -1133,14 +1113,29 @@ xfs_zero_remaining_bytes(
                        break;
                ASSERT(imap.br_blockcount >= 1);
                ASSERT(imap.br_startoff == offset_fsb);
+               ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
+
+               if (imap.br_startblock == HOLESTARTBLOCK ||
+                   imap.br_state == XFS_EXT_UNWRITTEN) {
+                       /* skip the entire extent */
+                       lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff +
+                                                     imap.br_blockcount) - 1;
+                       continue;
+               }
+
                lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1;
                if (lastoffset > endoff)
                        lastoffset = endoff;
-               if (imap.br_startblock == HOLESTARTBLOCK)
-                       continue;
-               ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
-               if (imap.br_state == XFS_EXT_UNWRITTEN)
+
+               /* DAX can just zero the backing device directly */
+               if (IS_DAX(VFS_I(ip))) {
+                       error = dax_zero_page_range(VFS_I(ip), offset,
+                                                   lastoffset - offset + 1,
+                                                   xfs_get_blocks_direct);
+                       if (error)
+                               return error;
                        continue;
+               }
 
                error = xfs_buf_read_uncached(XFS_IS_REALTIME_INODE(ip) ?
                                mp->m_rtdev_targp : mp->m_ddev_targp,
@@ -1289,7 +1284,7 @@ xfs_free_file_space(
                         * Free the transaction structure.
                         */
                        ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp, 0);
+                       xfs_trans_cancel(tp);
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1320,7 +1315,7 @@ xfs_free_file_space(
                        goto error0;
                }
 
-               error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+               error = xfs_trans_commit(tp);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
        }
 
@@ -1330,7 +1325,7 @@ xfs_free_file_space(
  error0:
        xfs_bmap_cancel(&free_list);
  error1:
-       xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
+       xfs_trans_cancel(tp);
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        goto out;
 }
@@ -1462,7 +1457,7 @@ xfs_shift_file_space(
                error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
                                XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
                if (error) {
-                       xfs_trans_cancel(tp, 0);
+                       xfs_trans_cancel(tp);
                        break;
                }
 
@@ -1492,13 +1487,13 @@ xfs_shift_file_space(
                if (error)
                        goto out;
 
-               error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+               error = xfs_trans_commit(tp);
        }
 
        return error;
 
 out:
-       xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
+       xfs_trans_cancel(tp);
        return error;
 }
 
@@ -1718,7 +1713,7 @@ xfs_swap_extents(
        tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
        error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
        if (error) {
-               xfs_trans_cancel(tp, 0);
+               xfs_trans_cancel(tp);
                goto out_unlock;
        }
 
@@ -1901,7 +1896,7 @@ xfs_swap_extents(
        if (mp->m_flags & XFS_MOUNT_WSYNC)
                xfs_trans_set_sync(tp);
 
-       error = xfs_trans_commit(tp, 0);
+       error = xfs_trans_commit(tp);
 
        trace_xfs_swap_extent_after(ip, 0);
        trace_xfs_swap_extent_after(tip, 1);
@@ -1915,6 +1910,6 @@ out_unlock:
        goto out;
 
 out_trans_cancel:
-       xfs_trans_cancel(tp, 0);
+       xfs_trans_cancel(tp);
        goto out;
 }