|
@@ -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;
|
|
|
}
|
|
|
|