xfs: kill xfs_zero_remaining_bytes
authorChristoph Hellwig <hch@lst.de>
Tue, 21 Jun 2016 00:02:23 +0000 (10:02 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 21 Jun 2016 00:02:23 +0000 (10:02 +1000)
Instead punch the whole first, and the use the our zeroing helper
to punch out the edge blocks.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_bmap_util.c

index e36664f..569f03d 100644 (file)
@@ -1089,101 +1089,6 @@ error1: /* Just cancel transaction */
        return error;
 }
 
-/*
- * Zero file bytes between startoff and endoff inclusive.
- * The iolock is held exclusive and no blocks are buffered.
- *
- * This function is used by xfs_free_file_space() to zero
- * partial blocks when the range to free is not block aligned.
- * When unreserving space with boundaries that are not block
- * aligned we round up the start and round down the end
- * boundaries and then use this function to zero the parts of
- * the blocks that got dropped during the rounding.
- */
-STATIC int
-xfs_zero_remaining_bytes(
-       xfs_inode_t             *ip,
-       xfs_off_t               startoff,
-       xfs_off_t               endoff)
-{
-       xfs_bmbt_irec_t         imap;
-       xfs_fileoff_t           offset_fsb;
-       xfs_off_t               lastoffset;
-       xfs_off_t               offset;
-       xfs_buf_t               *bp;
-       xfs_mount_t             *mp = ip->i_mount;
-       int                     nimap;
-       int                     error = 0;
-
-       /*
-        * Avoid doing I/O beyond eof - it's not necessary
-        * since nothing can read beyond eof.  The space will
-        * be zeroed when the file is extended anyway.
-        */
-       if (startoff >= XFS_ISIZE(ip))
-               return 0;
-
-       if (endoff > XFS_ISIZE(ip))
-               endoff = XFS_ISIZE(ip);
-
-       for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
-               uint lock_mode;
-
-               offset_fsb = XFS_B_TO_FSBT(mp, offset);
-               nimap = 1;
-
-               lock_mode = xfs_ilock_data_map_shared(ip);
-               error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0);
-               xfs_iunlock(ip, lock_mode);
-
-               if (error || nimap < 1)
-                       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;
-
-               /* 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,
-                               xfs_fsb_to_db(ip, imap.br_startblock),
-                               BTOBB(mp->m_sb.sb_blocksize),
-                               0, &bp, NULL);
-               if (error)
-                       return error;
-
-               memset(bp->b_addr +
-                               (offset - XFS_FSB_TO_B(mp, imap.br_startoff)),
-                      0, lastoffset - offset + 1);
-
-               error = xfs_bwrite(bp);
-               xfs_buf_relse(bp);
-               if (error)
-                       return error;
-       }
-       return error;
-}
-
 static int
 xfs_unmap_extent(
        struct xfs_inode        *ip,
@@ -1309,7 +1214,7 @@ xfs_free_file_space(
        struct xfs_mount        *mp = ip->i_mount;
        xfs_fileoff_t           startoffset_fsb;
        xfs_fileoff_t           endoffset_fsb;
-       int                     done, error;
+       int                     done = 0, error;
 
        trace_xfs_free_file_space(ip);
 
@@ -1341,31 +1246,21 @@ xfs_free_file_space(
                        return error;
        }
 
-       if ((done = (endoffset_fsb <= startoffset_fsb)))
-               /*
-                * One contiguous piece to clear
-                */
-               error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1);
-       else {
-               /*
-                * Some full blocks, possibly two pieces to clear
-                */
-               if (offset < XFS_FSB_TO_B(mp, startoffset_fsb))
-                       error = xfs_zero_remaining_bytes(ip, offset,
-                               XFS_FSB_TO_B(mp, startoffset_fsb) - 1);
-               if (!error &&
-                   XFS_FSB_TO_B(mp, endoffset_fsb) < offset + len)
-                       error = xfs_zero_remaining_bytes(ip,
-                               XFS_FSB_TO_B(mp, endoffset_fsb),
-                               offset + len - 1);
-       }
-
-       while (!error && !done) {
-               error = xfs_unmap_extent(ip, startoffset_fsb,
-                               endoffset_fsb - startoffset_fsb, &done);
+       if (endoffset_fsb > startoffset_fsb) {
+               while (!done) {
+                       error = xfs_unmap_extent(ip, startoffset_fsb,
+                                       endoffset_fsb - startoffset_fsb, &done);
+                       if (error)
+                               return error;
+               }
        }
 
-       return error;
+       /*
+        * Now that we've unmap all full blocks we'll have to zero out any
+        * partial block at the beginning and/or end.  xfs_zero_range is
+        * smart enough to skip any holes, including those we just created.
+        */
+       return xfs_zero_range(ip, offset, len, NULL);
 }
 
 /*