diff options
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 64a02eaf1dfe..2d702e4a74a3 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -3575,10 +3575,11 @@ xfs_bmap_do_search_extents( | |||
3575 | } | 3575 | } |
3576 | 3576 | ||
3577 | /* | 3577 | /* |
3578 | * Call xfs_bmap_do_search_extents() to search for the extent | 3578 | * Search the extent records for the entry containing block bno. |
3579 | * record containing block bno. If in multi-level in-core extent | 3579 | * If bno lies in a hole, point to the next entry. If bno lies |
3580 | * allocation mode, find and extract the target extent buffer, | 3580 | * past eof, *eofp will be set, and *prevp will contain the last |
3581 | * otherwise just use the direct extent list. | 3581 | * entry (null if none). Else, *lastxp will be set to the index |
3582 | * of the found entry; *gotp will contain the entry. | ||
3582 | */ | 3583 | */ |
3583 | xfs_bmbt_rec_t * /* pointer to found extent entry */ | 3584 | xfs_bmbt_rec_t * /* pointer to found extent entry */ |
3584 | xfs_bmap_search_multi_extents( | 3585 | xfs_bmap_search_multi_extents( |
@@ -3589,36 +3590,38 @@ xfs_bmap_search_multi_extents( | |||
3589 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ | 3590 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ |
3590 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ | 3591 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ |
3591 | { | 3592 | { |
3592 | xfs_bmbt_rec_t *base; /* base of extent records */ | ||
3593 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3593 | xfs_bmbt_rec_t *ep; /* extent record pointer */ |
3594 | xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ | ||
3595 | xfs_extnum_t lastx; /* last extent index */ | 3594 | xfs_extnum_t lastx; /* last extent index */ |
3596 | xfs_extnum_t nextents; /* number of file extents */ | ||
3597 | 3595 | ||
3598 | /* | 3596 | /* |
3599 | * For multi-level extent allocation mode, find the | 3597 | * Initialize the extent entry structure to catch access to |
3600 | * target extent list and pass only the contiguous | 3598 | * uninitialized br_startblock field. |
3601 | * list to xfs_bmap_do_search_extents. Convert lastx | ||
3602 | * from a file extent index to an index within the | ||
3603 | * target extent list. | ||
3604 | */ | 3599 | */ |
3605 | if (ifp->if_flags & XFS_IFEXTIREC) { | 3600 | gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; |
3606 | int erp_idx = 0; | 3601 | gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; |
3607 | erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); | 3602 | gotp->br_state = XFS_EXT_INVALID; |
3608 | base = erp->er_extbuf; | 3603 | #if XFS_BIG_BLKNOS |
3609 | nextents = erp->er_extcount; | 3604 | gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; |
3610 | lastx = ifp->if_lastex - erp->er_extoff; | 3605 | #else |
3611 | } else { | 3606 | gotp->br_startblock = 0xffffa5a5; |
3612 | base = &ifp->if_u1.if_extents[0]; | 3607 | #endif |
3613 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 3608 | prevp->br_startoff = NULLFILEOFF; |
3614 | lastx = ifp->if_lastex; | 3609 | |
3610 | ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); | ||
3611 | if (lastx > 0) { | ||
3612 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); | ||
3615 | } | 3613 | } |
3616 | ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, | 3614 | if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { |
3617 | eofp, lastxp, gotp, prevp); | 3615 | xfs_bmbt_get_all(ep, gotp); |
3618 | /* Convert lastx back to file-based index */ | 3616 | *eofp = 0; |
3619 | if (ifp->if_flags & XFS_IFEXTIREC) { | 3617 | } else { |
3620 | *lastxp += erp->er_extoff; | 3618 | if (lastx > 0) { |
3619 | *gotp = *prevp; | ||
3620 | } | ||
3621 | *eofp = 1; | ||
3622 | ep = NULL; | ||
3621 | } | 3623 | } |
3624 | *lastxp = lastx; | ||
3622 | return ep; | 3625 | return ep; |
3623 | } | 3626 | } |
3624 | 3627 | ||