|
|
| version 1.345, 2006/03/14 21:49:17 | version 1.346, 2006/03/28 23:50:15 |
|---|---|
| Line 3467 done: | Line 3467 done: |
| return error; | return error; |
| } | } |
| xfs_bmbt_rec_t * /* pointer to found extent entry */ | |
| xfs_bmap_do_search_extents( | |
| xfs_bmbt_rec_t *base, /* base of extent list */ | |
| xfs_extnum_t lastx, /* last extent index used */ | |
| xfs_extnum_t nextents, /* number of file extents */ | |
| xfs_fileoff_t bno, /* block number searched for */ | |
| int *eofp, /* out: end of file found */ | |
| xfs_extnum_t *lastxp, /* out: last extent index */ | |
| xfs_bmbt_irec_t *gotp, /* out: extent entry found */ | |
| xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ | |
| { | |
| xfs_bmbt_rec_t *ep; /* extent list entry pointer */ | |
| xfs_bmbt_irec_t got; /* extent list entry, decoded */ | |
| int high; /* high index of binary search */ | |
| int low; /* low index of binary search */ | |
| /* | |
| * Initialize the extent entry structure to catch access to | |
| * uninitialized br_startblock field. | |
| */ | |
| got.br_startoff = 0xffa5a5a5a5a5a5a5LL; | |
| got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; | |
| got.br_state = XFS_EXT_INVALID; | |
| #if XFS_BIG_BLKNOS | |
| got.br_startblock = 0xffffa5a5a5a5a5a5LL; | |
| #else | |
| got.br_startblock = 0xffffa5a5; | |
| #endif | |
| if (lastx != NULLEXTNUM && lastx < nextents) | |
| ep = base + lastx; | |
| else | |
| ep = NULL; | |
| prevp->br_startoff = NULLFILEOFF; | |
| if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) && | |
| bno < got.br_startoff + | |
| (got.br_blockcount = xfs_bmbt_get_blockcount(ep))) | |
| *eofp = 0; | |
| else if (ep && lastx < nextents - 1 && | |
| bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) && | |
| bno < got.br_startoff + | |
| (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) { | |
| lastx++; | |
| ep++; | |
| *eofp = 0; | |
| } else if (nextents == 0) | |
| *eofp = 1; | |
| else if (bno == 0 && | |
| (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) { | |
| ep = base; | |
| lastx = 0; | |
| got.br_blockcount = xfs_bmbt_get_blockcount(ep); | |
| *eofp = 0; | |
| } else { | |
| low = 0; | |
| high = nextents - 1; | |
| /* binary search the extents array */ | |
| while (low <= high) { | |
| XFS_STATS_INC(xs_cmp_exlist); | |
| lastx = (low + high) >> 1; | |
| ep = base + lastx; | |
| got.br_startoff = xfs_bmbt_get_startoff(ep); | |
| got.br_blockcount = xfs_bmbt_get_blockcount(ep); | |
| if (bno < got.br_startoff) | |
| high = lastx - 1; | |
| else if (bno >= got.br_startoff + got.br_blockcount) | |
| low = lastx + 1; | |
| else { | |
| got.br_startblock = xfs_bmbt_get_startblock(ep); | |
| got.br_state = xfs_bmbt_get_state(ep); | |
| *eofp = 0; | |
| *lastxp = lastx; | |
| *gotp = got; | |
| return ep; | |
| } | |
| } | |
| if (bno >= got.br_startoff + got.br_blockcount) { | |
| lastx++; | |
| if (lastx == nextents) { | |
| *eofp = 1; | |
| got.br_startblock = xfs_bmbt_get_startblock(ep); | |
| got.br_state = xfs_bmbt_get_state(ep); | |
| *prevp = got; | |
| ep = NULL; | |
| } else { | |
| *eofp = 0; | |
| xfs_bmbt_get_all(ep, prevp); | |
| ep++; | |
| got.br_startoff = xfs_bmbt_get_startoff(ep); | |
| got.br_blockcount = xfs_bmbt_get_blockcount(ep); | |
| } | |
| } else { | |
| *eofp = 0; | |
| if (ep > base) | |
| xfs_bmbt_get_all(ep - 1, prevp); | |
| } | |
| } | |
| if (ep) { | |
| got.br_startblock = xfs_bmbt_get_startblock(ep); | |
| got.br_state = xfs_bmbt_get_state(ep); | |
| } | |
| *lastxp = lastx; | |
| *gotp = got; | |
| return ep; | |
| } | |
| /* | /* |
| * Search the extent records for the entry containing block bno. | * Search the extent records for the entry containing block bno. |
| * If bno lies in a hole, point to the next entry. If bno lies | * If bno lies in a hole, point to the next entry. If bno lies |