[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:
Родитель
524fbf5dd1
Коммит
8867bc9bf0
|
@ -3575,10 +3575,11 @@ xfs_bmap_do_search_extents(
|
|||
}
|
||||
|
||||
/*
|
||||
* Call xfs_bmap_do_search_extents() to search for the extent
|
||||
* record containing block bno. If in multi-level in-core extent
|
||||
* allocation mode, find and extract the target extent buffer,
|
||||
* otherwise just use the direct extent list.
|
||||
* Search the extent records for the entry containing block bno.
|
||||
* If bno lies in a hole, point to the next entry. If bno lies
|
||||
* past eof, *eofp will be set, and *prevp will contain the last
|
||||
* entry (null if none). Else, *lastxp will be set to the index
|
||||
* of the found entry; *gotp will contain the entry.
|
||||
*/
|
||||
xfs_bmbt_rec_t * /* pointer to found extent entry */
|
||||
xfs_bmap_search_multi_extents(
|
||||
|
@ -3589,36 +3590,38 @@ xfs_bmap_search_multi_extents(
|
|||
xfs_bmbt_irec_t *gotp, /* out: extent entry found */
|
||||
xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
|
||||
{
|
||||
xfs_bmbt_rec_t *base; /* base of extent records */
|
||||
xfs_bmbt_rec_t *ep; /* extent record pointer */
|
||||
xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
|
||||
xfs_extnum_t lastx; /* last extent index */
|
||||
xfs_extnum_t nextents; /* number of file extents */
|
||||
|
||||
/*
|
||||
* For multi-level extent allocation mode, find the
|
||||
* target extent list and pass only the contiguous
|
||||
* list to xfs_bmap_do_search_extents. Convert lastx
|
||||
* from a file extent index to an index within the
|
||||
* target extent list.
|
||||
* Initialize the extent entry structure to catch access to
|
||||
* uninitialized br_startblock field.
|
||||
*/
|
||||
if (ifp->if_flags & XFS_IFEXTIREC) {
|
||||
int erp_idx = 0;
|
||||
erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
|
||||
base = erp->er_extbuf;
|
||||
nextents = erp->er_extcount;
|
||||
lastx = ifp->if_lastex - erp->er_extoff;
|
||||
gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
|
||||
gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
|
||||
gotp->br_state = XFS_EXT_INVALID;
|
||||
#if XFS_BIG_BLKNOS
|
||||
gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
|
||||
#else
|
||||
gotp->br_startblock = 0xffffa5a5;
|
||||
#endif
|
||||
prevp->br_startoff = NULLFILEOFF;
|
||||
|
||||
ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
|
||||
if (lastx > 0) {
|
||||
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
|
||||
}
|
||||
if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
|
||||
xfs_bmbt_get_all(ep, gotp);
|
||||
*eofp = 0;
|
||||
} else {
|
||||
base = &ifp->if_u1.if_extents[0];
|
||||
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
|
||||
lastx = ifp->if_lastex;
|
||||
}
|
||||
ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno,
|
||||
eofp, lastxp, gotp, prevp);
|
||||
/* Convert lastx back to file-based index */
|
||||
if (ifp->if_flags & XFS_IFEXTIREC) {
|
||||
*lastxp += erp->er_extoff;
|
||||
if (lastx > 0) {
|
||||
*gotp = *prevp;
|
||||
}
|
||||
*eofp = 1;
|
||||
ep = NULL;
|
||||
}
|
||||
*lastxp = lastx;
|
||||
return ep;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -478,6 +478,7 @@ void xfs_iext_indirect_to_direct(xfs_ifork_t *);
|
|||
void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
|
||||
void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
|
||||
void xfs_iext_destroy(xfs_ifork_t *);
|
||||
xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
|
||||
xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
|
||||
xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
|
||||
void xfs_iext_irec_init(xfs_ifork_t *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче