Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 23125
b: refs/heads/master
c: 8867bc9
h: refs/heads/master
i:
  23123: d18c7fb
v: v3
  • Loading branch information
Mandy Kirkconnell authored and Nathan Scott committed Mar 17, 2006
1 parent 867666b commit 11b996a
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 524fbf5dd1b25acffe6f8a4ed5f3cce1023cfdb8
refs/heads/master: 8867bc9bf0aed7181aa72c7c938c6ce830b75166
57 changes: 30 additions & 27 deletions trunk/fs/xfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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;
} else {
base = &ifp->if_u1.if_extents[0];
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
lastx = ifp->if_lastex;
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);
}
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 < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
xfs_bmbt_get_all(ep, gotp);
*eofp = 0;
} else {
if (lastx > 0) {
*gotp = *prevp;
}
*eofp = 1;
ep = NULL;
}
*lastxp = lastx;
return ep;
}

Expand Down
73 changes: 71 additions & 2 deletions trunk/fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -4265,20 +4265,89 @@ 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 */
int *erp_idxp) /* irec index of target ext list */
{
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 */
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit 11b996a

Please sign in to comment.