[XFS] There are a few problems with the new
xfs_bmap_search_multi_extents() wrapper function that I introduced in mod xfs-linux:xfs-kern:207393a. The function was added as a wrapper around xfs_bmap_do_search_extents() to avoid breaking the top-of-tree CXFS interface. The idea of the function was basically to extract the target extent buffer (if muli- level extent allocation mode), then call xfs_bmap_do_search_extents() with either a pointer to the first extent in the target buffer or a pointer to the first extent in the file, depending on which extent mode was being used. However, in addition to locating the target extent record for block bno, xfs_bmap_do_search_extents() also sets four parameters needed by the caller: *lastx, *eofp, *gotp, *prevp. Passing only the target extent buffer to xfs_bmap_do_search_extents() causes *eofp to be set incorrectly if the extent is at the end of the target list but there are actually more extents in the next er_extbuf. Likewise, if the extent is the first one in the buffer but NOT the first in the file, *prevp is incorrectly set to NULL. Adding the needed functionality to xfs_bmap_search_multi_extents() to re-set any incorrectly set fields is redundant and makes the call to xfs_bmap_do_search_extents() not make much sense when multi-level extent allocation mode is being used. This mod basically extracts the two functional components from xfs_bmap_do_search_extents(), with the intent of obsoleting/removing xfs_bmap_do_search_extents() after the CXFS mult-level in-core extent changes are checked in. The two components are: 1) The binary search to locate the target extent record, and 2) Setting the four parameters needed by the caller (*lastx, *eofp, *gotp, *prevp). Component 1: I created a new function in xfs_inode.c called xfs_iext_bno_to_ext(), which executes the binary search to find the target extent record. xfs_bmap_search_multi_extents() has been modified to call xfs_iext_bno_to_ext() rather than xfs_bmap_do_search_extents(). Component 2: The parameter setting functionality has been added to xfs_bmap_search_multi_extents(), eliminating the need for xfs_bmap_do_search_extents(). These changes make the removal of xfs_bmap_do_search_extents() trival once the CXFS changes are in place. They also allow us to maintain the current XFS interface, using the new search function introduced in mod xfs-linux:xfs-kern:207393a. SGI-PV: 928864 SGI-Modid: xfs-linux-melb:xfs-kern:207866a Signed-off-by: Mandy Kirkconnell <alkirkco@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
This commit is contained in:

committed by
Nathan Scott

parent
524fbf5dd1
commit
8867bc9bf0
@@ -4265,12 +4265,81 @@ xfs_iext_destroy(
|
||||
ifp->if_bytes = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the extent record for file system block bno.
|
||||
*/
|
||||
xfs_bmbt_rec_t * /* pointer to found extent record */
|
||||
xfs_iext_bno_to_ext(
|
||||
xfs_ifork_t *ifp, /* inode fork pointer */
|
||||
xfs_fileoff_t bno, /* block number to search for */
|
||||
xfs_extnum_t *idxp) /* index of target extent */
|
||||
{
|
||||
xfs_bmbt_rec_t *base; /* pointer to first extent */
|
||||
xfs_filblks_t blockcount = 0; /* number of blocks in extent */
|
||||
xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */
|
||||
xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
|
||||
int high; /* upper boundry in search */
|
||||
xfs_extnum_t idx = 0; /* index of target extent */
|
||||
int low; /* lower boundry in search */
|
||||
xfs_extnum_t nextents; /* number of file extents */
|
||||
xfs_fileoff_t startoff = 0; /* start offset of extent */
|
||||
|
||||
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
|
||||
if (nextents == 0) {
|
||||
*idxp = 0;
|
||||
return NULL;
|
||||
}
|
||||
low = 0;
|
||||
if (ifp->if_flags & XFS_IFEXTIREC) {
|
||||
/* Find target extent list */
|
||||
int erp_idx = 0;
|
||||
erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
|
||||
base = erp->er_extbuf;
|
||||
high = erp->er_extcount - 1;
|
||||
} else {
|
||||
base = ifp->if_u1.if_extents;
|
||||
high = nextents - 1;
|
||||
}
|
||||
/* Binary search extent records */
|
||||
while (low <= high) {
|
||||
idx = (low + high) >> 1;
|
||||
ep = base + idx;
|
||||
startoff = xfs_bmbt_get_startoff(ep);
|
||||
blockcount = xfs_bmbt_get_blockcount(ep);
|
||||
if (bno < startoff) {
|
||||
high = idx - 1;
|
||||
} else if (bno >= startoff + blockcount) {
|
||||
low = idx + 1;
|
||||
} else {
|
||||
/* Convert back to file-based extent index */
|
||||
if (ifp->if_flags & XFS_IFEXTIREC) {
|
||||
idx += erp->er_extoff;
|
||||
}
|
||||
*idxp = idx;
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
/* Convert back to file-based extent index */
|
||||
if (ifp->if_flags & XFS_IFEXTIREC) {
|
||||
idx += erp->er_extoff;
|
||||
}
|
||||
if (bno >= startoff + blockcount) {
|
||||
if (++idx == nextents) {
|
||||
ep = NULL;
|
||||
} else {
|
||||
ep = xfs_iext_get_ext(ifp, idx);
|
||||
}
|
||||
}
|
||||
*idxp = idx;
|
||||
return ep;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the indirection array entry containing the
|
||||
* extent record for filesystem block bno. Store the index of the
|
||||
* target irec in *erp_idxp.
|
||||
*/
|
||||
xfs_ext_irec_t *
|
||||
xfs_ext_irec_t * /* pointer to found extent record */
|
||||
xfs_iext_bno_to_irec(
|
||||
xfs_ifork_t *ifp, /* inode fork pointer */
|
||||
xfs_fileoff_t bno, /* block number to search for */
|
||||
@@ -4278,7 +4347,7 @@ xfs_iext_bno_to_irec(
|
||||
{
|
||||
xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
|
||||
xfs_ext_irec_t *erp_next; /* next indirection array entry */
|
||||
xfs_extnum_t erp_idx; /* indirection array index */
|
||||
int erp_idx; /* indirection array index */
|
||||
int nlists; /* number of extent irec's (lists) */
|
||||
int high; /* binary search upper limit */
|
||||
int low; /* binary search lower limit */
|
||||
|
Reference in New Issue
Block a user