]> git.baikalelectronics.ru Git - kernel.git/commitdiff
xfs: cleanup xfs_bmap_last_before
authorChristoph Hellwig <hch@lst.de>
Thu, 24 Nov 2016 00:39:38 +0000 (11:39 +1100)
committerDave Chinner <david@fromorbit.com>
Thu, 24 Nov 2016 00:39:38 +0000 (11:39 +1100)
Rewrite the function using xfs_iext_lookup_extent and xfs_iext_get_extent,
and massage the flow into something easily understandable.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/libxfs/xfs_bmap.c

index 42f4e7a84e2e8019343c6a7613612fad2ee1b040..13f62da67bbcca942833ef6a955cf9527c3983d3 100644 (file)
@@ -1523,44 +1523,44 @@ xfs_bmap_first_unused(
  */
 int                                            /* error */
 xfs_bmap_last_before(
-       xfs_trans_t     *tp,                    /* transaction pointer */
-       xfs_inode_t     *ip,                    /* incore inode */
-       xfs_fileoff_t   *last_block,            /* last block */
-       int             whichfork)              /* data or attr fork */
+       struct xfs_trans        *tp,            /* transaction pointer */
+       struct xfs_inode        *ip,            /* incore inode */
+       xfs_fileoff_t           *last_block,    /* last block */
+       int                     whichfork)      /* data or attr fork */
 {
-       xfs_fileoff_t   bno;                    /* input file offset */
-       int             eof;                    /* hit end of file */
-       xfs_bmbt_rec_host_t *ep;                /* pointer to last extent */
-       int             error;                  /* error return value */
-       xfs_bmbt_irec_t got;                    /* current extent value */
-       xfs_ifork_t     *ifp;                   /* inode fork pointer */
-       xfs_extnum_t    lastx;                  /* last extent used */
-       xfs_bmbt_irec_t prev;                   /* previous extent value */
+       struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, whichfork);
+       struct xfs_bmbt_irec    got;
+       xfs_extnum_t            idx;
+       int                     error;
 
-       if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
-           XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
-              return -EIO;
-       if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
+       switch (XFS_IFORK_FORMAT(ip, whichfork)) {
+       case XFS_DINODE_FMT_LOCAL:
                *last_block = 0;
                return 0;
+       case XFS_DINODE_FMT_BTREE:
+       case XFS_DINODE_FMT_EXTENTS:
+               break;
+       default:
+               return -EIO;
        }
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       if (!(ifp->if_flags & XFS_IFEXTENTS) &&
-           (error = xfs_iread_extents(tp, ip, whichfork)))
-               return error;
-       bno = *last_block - 1;
-       ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
-               &prev);
-       if (eof || xfs_bmbt_get_startoff(ep) > bno) {
-               if (prev.br_startoff == NULLFILEOFF)
-                       *last_block = 0;
-               else
-                       *last_block = prev.br_startoff + prev.br_blockcount;
+
+       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+               error = xfs_iread_extents(tp, ip, whichfork);
+               if (error)
+                       return error;
        }
-       /*
-        * Otherwise *last_block is already the right answer.
-        */
+
+       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;
        return 0;
 }