]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: add a new xfs_iext_lookup_extent_before helper
authorChristoph Hellwig <hch@lst.de>
Fri, 17 Nov 2017 04:11:33 +0000 (22:11 -0600)
committerEric Sandeen <sandeen@redhat.com>
Fri, 17 Nov 2017 04:11:33 +0000 (22:11 -0600)
Source kernel commit: dc56015faff1bc9e7493c2b28302c423a02237c2

This helper looks up the last extent the covers space before the passed
in block number.  This is useful for truncate and similar operations that
operate backwards over the extent list.  For xfs_bunmapi it also is
a slight optimization as we can return early if there are not extents
at or below the end of the to be truncated range.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_bmap.c
libxfs/xfs_inode_fork.c
libxfs/xfs_inode_fork.h

index 11ec8c5621e4c8231318a938d61ad5659a51fc92..905095371e13b81a6e05765abf2a7092ac2608ec 100644 (file)
@@ -1377,17 +1377,8 @@ xfs_bmap_last_before(
                        return error;
        }
 
-       if (xfs_iext_lookup_extent(ip, ifp, *last_block - 1, &idx, &got)) {
-               if (got.br_startoff <= *last_block - 1)
-                       return 0;
-       }
-
-       if (xfs_iext_get_extent(ifp, idx - 1, &got)) {
-               *last_block = got.br_startoff + got.br_blockcount;
-               return 0;
-       }
-
-       *last_block = 0;
+       if (!xfs_iext_lookup_extent_before(ip, ifp, last_block, &idx, &got))
+               *last_block = 0;
        return 0;
 }
 
@@ -5162,17 +5153,13 @@ __xfs_bunmapi(
        }
        XFS_STATS_INC(mp, xs_blk_unmap);
        isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
-       end = start + len - 1;
+       end = start + len;
 
-       /*
-        * Check to see if the given block number is past the end of the
-        * file, back up to the last block if so...
-        */
-       if (!xfs_iext_lookup_extent(ip, ifp, end, &lastx, &got)) {
-               ASSERT(lastx > 0);
-               xfs_iext_get_extent(ifp, --lastx, &got);
-               end = got.br_startoff + got.br_blockcount - 1;
+       if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &lastx, &got)) {
+               *rlen = 0;
+               return 0;
        }
+       end--;
 
        logflags = 0;
        if (ifp->if_flags & XFS_IFBROOT) {
index 3aab9fe39be844f3144b48eee951a87cb3e17f29..4502de31fb532752858949211354b1fa40a1a186 100644 (file)
@@ -1966,6 +1966,27 @@ xfs_iext_lookup_extent(
        return true;
 }
 
+/*
+ * Returns the last extent before end, and if this extent doesn't cover
+ * end, update end to the end of the extent.
+ */
+bool
+xfs_iext_lookup_extent_before(
+       struct xfs_inode        *ip,
+       struct xfs_ifork        *ifp,
+       xfs_fileoff_t           *end,
+       xfs_extnum_t            *idxp,
+       struct xfs_bmbt_irec    *gotp)
+{
+       if (xfs_iext_lookup_extent(ip, ifp, *end - 1, idxp, gotp) &&
+           gotp->br_startoff <= *end - 1)
+               return true;
+       if (!xfs_iext_get_extent(ifp, --*idxp, gotp))
+               return false;
+       *end = gotp->br_startoff + gotp->br_blockcount;
+       return true;
+}
+
 /*
  * Return true if there is an extent at index idx, and return the expanded
  * extent structure at idx in that case.  Else return false.
index e0c42ea9b8d0c189e54089909c4a986c37229034..113fd42ec36dc04310076ad52aecd1c6024662a3 100644 (file)
@@ -183,6 +183,10 @@ void               xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int);
 bool           xfs_iext_lookup_extent(struct xfs_inode *ip,
                        struct xfs_ifork *ifp, xfs_fileoff_t bno,
                        xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp);
+bool           xfs_iext_lookup_extent_before(struct xfs_inode *ip,
+                       struct xfs_ifork *ifp, xfs_fileoff_t *end,
+                       xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp);
+
 bool           xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx,
                        struct xfs_bmbt_irec *gotp);
 void           xfs_iext_update_extent(struct xfs_inode *ip, int state,