On Fri, Nov 03, 2017 at 05:45:30PM +0300, Christoph Hellwig wrote: > Add a new xfs_iext_cursor structure to hide the direct extent map > index manipulations. In addition to the existing lookup/get/insert/ > remove and update routines new primitives to get the first and last > extent cursor, as well as moving up and down by one extent are > provided. Also new are convenience to increment/decrement the > cursor and retreive the new extent, as well as to peek into the > previous/next extent without updating the cursor and last but not > least a macro to iterate over all extents in a fork. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > --- > fs/xfs/libxfs/xfs_bmap.c | 441 ++++++++++++++++++++--------------------- > fs/xfs/libxfs/xfs_bmap.h | 12 +- > fs/xfs/libxfs/xfs_inode_fork.c | 75 +++---- > fs/xfs/libxfs/xfs_inode_fork.h | 87 +++++++- > fs/xfs/libxfs/xfs_types.h | 3 + > fs/xfs/scrub/bmap.c | 6 +- > fs/xfs/scrub/dir.c | 14 +- > fs/xfs/xfs_bmap_util.c | 12 +- > fs/xfs/xfs_dir2_readdir.c | 8 +- > fs/xfs/xfs_dquot.c | 4 +- > fs/xfs/xfs_iomap.c | 14 +- > fs/xfs/xfs_reflink.c | 56 +++--- > fs/xfs/xfs_trace.h | 12 +- > 13 files changed, 407 insertions(+), 337 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index f4d0639dc4ae..b08c4863c2af 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -672,8 +672,9 @@ xfs_bmap_extents_to_btree( > xfs_bmbt_key_t *kp; /* root block key pointer */ > xfs_mount_t *mp; /* mount structure */ > xfs_bmbt_ptr_t *pp; /* root block address pointer */ > + struct xfs_iext_cursor icur; > struct xfs_bmbt_irec rec; > - xfs_extnum_t i = 0, cnt = 0; > + xfs_extnum_t cnt = 0; > > mp = ip->i_mount; > ASSERT(whichfork != XFS_COW_FORK); > @@ -752,7 +753,7 @@ xfs_bmap_extents_to_btree( > XFS_BTNUM_BMAP, 0, 0, ip->i_ino, > XFS_BTREE_LONG_PTRS); > > - while (xfs_iext_get_extent(ifp, i++, &rec)) { > + for_each_iext(ifp, &icur, &rec) { I stand by my previous mutterings that 'xfs' ought to be in the name somewhere, so if you don't mind I'll change this to 'for_each_xfs_iext' on the way in. Otherwise looks ok, Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > if (isnullstartblock(rec.br_startblock)) > continue; > arp = XFS_BMBT_REC_ADDR(mp, ablock, 1 + cnt); > @@ -828,6 +829,7 @@ xfs_bmap_local_to_extents( > xfs_alloc_arg_t args; /* allocation arguments */ > xfs_buf_t *bp; /* buffer for extent block */ > struct xfs_bmbt_irec rec; > + struct xfs_iext_cursor icur; > > /* > * We don't want to deal with the case of keeping inode data inline yet. > @@ -894,7 +896,8 @@ xfs_bmap_local_to_extents( > rec.br_startblock = args.fsbno; > rec.br_blockcount = 1; > rec.br_state = XFS_EXT_NORM; > - xfs_iext_insert(ip, 0, 1, &rec, 0); > + xfs_iext_first(ifp, &icur); > + xfs_iext_insert(ip, &icur, 1, &rec, 0); > > XFS_IFORK_NEXT_SET(ip, whichfork, 1); > ip->i_d.di_nblocks = 1; > @@ -1174,6 +1177,7 @@ xfs_iread_extents( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > xfs_extnum_t nextents = XFS_IFORK_NEXTENTS(ip, whichfork); > struct xfs_btree_block *block = ifp->if_broot; > + struct xfs_iext_cursor icur; > xfs_fsblock_t bno; > struct xfs_buf *bp; > xfs_extnum_t i, j; > @@ -1223,6 +1227,7 @@ xfs_iread_extents( > * Here with bp and block set to the leftmost leaf node in the tree. > */ > i = 0; > + xfs_iext_first(ifp, &icur); > > /* > * Loop over all leaf nodes. Copy information to the extent records. > @@ -1264,7 +1269,8 @@ xfs_iread_extents( > } > trp->l0 = be64_to_cpu(frp->l0); > trp->l1 = be64_to_cpu(frp->l1); > - trace_xfs_read_extent(ip, i, state, _THIS_IP_); > + trace_xfs_read_extent(ip, &icur, state, _THIS_IP_); > + xfs_iext_next(ifp, &icur); > } > xfs_trans_brelse(tp, bp); > bno = nextbno; > @@ -1312,7 +1318,7 @@ xfs_bmap_first_unused( > { > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec got; > - xfs_extnum_t idx = 0; > + struct xfs_iext_cursor icur; > xfs_fileoff_t lastaddr = 0; > xfs_fileoff_t lowest, max; > int error; > @@ -1333,7 +1339,7 @@ xfs_bmap_first_unused( > } > > lowest = max = *first_unused; > - while (xfs_iext_get_extent(ifp, idx++, &got)) { > + for_each_iext(ifp, &icur, &got) { > /* > * See if the hole before this extent will work. > */ > @@ -1363,7 +1369,7 @@ xfs_bmap_last_before( > { > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > int error; > > switch (XFS_IFORK_FORMAT(ip, whichfork)) { > @@ -1383,7 +1389,7 @@ xfs_bmap_last_before( > return error; > } > > - if (!xfs_iext_lookup_extent_before(ip, ifp, last_block, &idx, &got)) > + if (!xfs_iext_lookup_extent_before(ip, ifp, last_block, &icur, &got)) > *last_block = 0; > return 0; > } > @@ -1397,8 +1403,8 @@ xfs_bmap_last_extent( > int *is_empty) > { > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > + struct xfs_iext_cursor icur; > int error; > - int nextents; > > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > @@ -1406,14 +1412,11 @@ xfs_bmap_last_extent( > return error; > } > > - nextents = xfs_iext_count(ifp); > - if (nextents == 0) { > + xfs_iext_last(ifp, &icur); > + if (!xfs_iext_get_extent(ifp, &icur, rec)) > *is_empty = 1; > - return 0; > - } > - > - xfs_iext_get_extent(ifp, nextents - 1, rec); > - *is_empty = 0; > + else > + *is_empty = 0; > return 0; > } > > @@ -1501,6 +1504,7 @@ xfs_bmap_one_block( > xfs_ifork_t *ifp; /* inode fork pointer */ > int rval; /* return value */ > xfs_bmbt_irec_t s; /* internal version of extent */ > + struct xfs_iext_cursor icur; > > #ifndef DEBUG > if (whichfork == XFS_DATA_FORK) > @@ -1512,7 +1516,8 @@ xfs_bmap_one_block( > return 0; > ifp = XFS_IFORK_PTR(ip, whichfork); > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > - xfs_iext_get_extent(ifp, 0, &s); > + xfs_iext_first(ifp, &icur); > + xfs_iext_get_extent(ifp, &icur, &s); > rval = s.br_startoff == 0 && s.br_blockcount == 1; > if (rval && whichfork == XFS_DATA_FORK) > ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize); > @@ -1554,8 +1559,6 @@ xfs_bmap_add_extent_delay_real( > nextents = (whichfork == XFS_COW_FORK ? &bma->ip->i_cnextents : > &bma->ip->i_d.di_nextents); > > - ASSERT(bma->idx >= 0); > - ASSERT(bma->idx <= xfs_iext_count(ifp)); > ASSERT(!isnullstartblock(new->br_startblock)); > ASSERT(!bma->cur || > (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); > @@ -1569,7 +1572,7 @@ xfs_bmap_add_extent_delay_real( > /* > * Set up a bunch of variables to make the tests simpler. > */ > - xfs_iext_get_extent(ifp, bma->idx, &PREV); > + xfs_iext_get_extent(ifp, &bma->icur, &PREV); > new_endoff = new->br_startoff + new->br_blockcount; > ASSERT(isnullstartblock(PREV.br_startblock)); > ASSERT(PREV.br_startoff <= new->br_startoff); > @@ -1591,10 +1594,8 @@ xfs_bmap_add_extent_delay_real( > * Check and set flags if this segment has a left neighbor. > * Don't set contiguous if the combined extent would be too large. > */ > - if (bma->idx > 0) { > + if (xfs_iext_peek_prev_extent(ifp, &bma->icur, &LEFT)) { > state |= BMAP_LEFT_VALID; > - xfs_iext_get_extent(ifp, bma->idx - 1, &LEFT); > - > if (isnullstartblock(LEFT.br_startblock)) > state |= BMAP_LEFT_DELAY; > } > @@ -1611,10 +1612,8 @@ xfs_bmap_add_extent_delay_real( > * Don't set contiguous if the combined extent would be too large. > * Also check for all-three-contiguous being too large. > */ > - if (bma->idx < xfs_iext_count(ifp) - 1) { > + if (xfs_iext_peek_next_extent(ifp, &bma->icur, &RIGHT)) { > state |= BMAP_RIGHT_VALID; > - xfs_iext_get_extent(ifp, bma->idx + 1, &RIGHT); > - > if (isnullstartblock(RIGHT.br_startblock)) > state |= BMAP_RIGHT_DELAY; > } > @@ -1646,9 +1645,9 @@ xfs_bmap_add_extent_delay_real( > */ > LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount; > > - xfs_iext_remove(bma->ip, bma->idx, 2, state); > - bma->idx--; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &LEFT); > + xfs_iext_remove(bma->ip, &bma->icur, 2, state); > + xfs_iext_prev(ifp, &bma->icur); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); > (*nextents)--; > > if (bma->cur == NULL) > @@ -1681,9 +1680,9 @@ xfs_bmap_add_extent_delay_real( > old = LEFT; > LEFT.br_blockcount += PREV.br_blockcount; > > - xfs_iext_remove(bma->ip, bma->idx, 1, state); > - bma->idx--; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &LEFT); > + xfs_iext_remove(bma->ip, &bma->icur, 1, state); > + xfs_iext_prev(ifp, &bma->icur); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); > > if (bma->cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -1707,10 +1706,10 @@ xfs_bmap_add_extent_delay_real( > PREV.br_startblock = new->br_startblock; > PREV.br_blockcount += RIGHT.br_blockcount; > > - bma->idx++; > - xfs_iext_remove(bma->ip, bma->idx, 1, state); > - bma->idx--; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV); > + xfs_iext_next(ifp, &bma->icur); > + xfs_iext_remove(bma->ip, &bma->icur, 1, state); > + xfs_iext_prev(ifp, &bma->icur); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > > if (bma->cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -1734,7 +1733,7 @@ xfs_bmap_add_extent_delay_real( > */ > PREV.br_startblock = new->br_startblock; > PREV.br_state = new->br_state; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > > (*nextents)++; > if (bma->cur == NULL) > @@ -1768,9 +1767,9 @@ xfs_bmap_add_extent_delay_real( > PREV.br_startoff += new->br_blockcount; > PREV.br_startblock = nullstartblock(da_new); > > - xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV); > - bma->idx--; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &LEFT); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > + xfs_iext_prev(ifp, &bma->icur); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); > > if (bma->cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -1784,7 +1783,6 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > - > break; > > case BMAP_LEFT_FILLING: > @@ -1792,7 +1790,7 @@ xfs_bmap_add_extent_delay_real( > * Filling in the first part of a previous delayed allocation. > * The left neighbor is not contiguous. > */ > - xfs_iext_update_extent(bma->ip, state, bma->idx, new); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, new); > (*nextents)++; > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > @@ -1825,7 +1823,9 @@ xfs_bmap_add_extent_delay_real( > PREV.br_startoff = new_endoff; > PREV.br_blockcount = temp; > PREV.br_startblock = nullstartblock(da_new); > - xfs_iext_insert(bma->ip, bma->idx + 1, 1, &PREV, state); > + xfs_iext_next(ifp, &bma->icur); > + xfs_iext_insert(bma->ip, &bma->icur, 1, &PREV, state); > + xfs_iext_prev(ifp, &bma->icur); > break; > > case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: > @@ -1858,9 +1858,9 @@ xfs_bmap_add_extent_delay_real( > PREV.br_blockcount = temp; > PREV.br_startblock = nullstartblock(da_new); > > - xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV); > - bma->idx++; > - xfs_iext_update_extent(bma->ip, state, bma->idx, &RIGHT); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > + xfs_iext_next(ifp, &bma->icur); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &RIGHT); > break; > > case BMAP_RIGHT_FILLING: > @@ -1868,7 +1868,7 @@ xfs_bmap_add_extent_delay_real( > * Filling in the last part of a previous delayed allocation. > * The right neighbor is not contiguous. > */ > - xfs_iext_update_extent(bma->ip, state, bma->idx, new); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, new); > (*nextents)++; > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > @@ -1900,9 +1900,8 @@ xfs_bmap_add_extent_delay_real( > > PREV.br_startblock = nullstartblock(da_new); > PREV.br_blockcount = temp; > - xfs_iext_insert(bma->ip, bma->idx, 1, &PREV, state); > - > - bma->idx++; > + xfs_iext_insert(bma->ip, &bma->icur, 1, &PREV, state); > + xfs_iext_next(ifp, &bma->icur); > break; > > case 0: > @@ -1945,10 +1944,11 @@ xfs_bmap_add_extent_delay_real( > PREV.br_startblock = > nullstartblock(xfs_bmap_worst_indlen(bma->ip, > PREV.br_blockcount)); > - xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV); > + xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > > /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ > - xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state); > + xfs_iext_next(ifp, &bma->icur); > + xfs_iext_insert(bma->ip, &bma->icur, 2, &LEFT, state); > (*nextents)++; > > if (bma->cur == NULL) > @@ -1976,7 +1976,6 @@ xfs_bmap_add_extent_delay_real( > > da_new = startblockval(PREV.br_startblock) + > startblockval(RIGHT.br_startblock); > - bma->idx++; > break; > > case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: > @@ -2040,7 +2039,7 @@ xfs_bmap_add_extent_unwritten_real( > struct xfs_trans *tp, > xfs_inode_t *ip, /* incore inode pointer */ > int whichfork, > - xfs_extnum_t *idx, /* extent number to update/insert */ > + struct xfs_iext_cursor *icur, > xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ > xfs_bmbt_irec_t *new, /* new data to add to file extents */ > xfs_fsblock_t *first, /* pointer to firstblock variable */ > @@ -2064,8 +2063,6 @@ xfs_bmap_add_extent_unwritten_real( > cur = *curp; > ifp = XFS_IFORK_PTR(ip, whichfork); > > - ASSERT(*idx >= 0); > - ASSERT(*idx <= xfs_iext_count(ifp)); > ASSERT(!isnullstartblock(new->br_startblock)); > > XFS_STATS_INC(mp, xs_add_exlist); > @@ -2078,7 +2075,7 @@ xfs_bmap_add_extent_unwritten_real( > * Set up a bunch of variables to make the tests simpler. > */ > error = 0; > - xfs_iext_get_extent(ifp, *idx, &PREV); > + xfs_iext_get_extent(ifp, icur, &PREV); > ASSERT(new->br_state != PREV.br_state); > new_endoff = new->br_startoff + new->br_blockcount; > ASSERT(PREV.br_startoff <= new->br_startoff); > @@ -2097,10 +2094,8 @@ xfs_bmap_add_extent_unwritten_real( > * Check and set flags if this segment has a left neighbor. > * Don't set contiguous if the combined extent would be too large. > */ > - if (*idx > 0) { > + if (xfs_iext_peek_prev_extent(ifp, icur, &LEFT)) { > state |= BMAP_LEFT_VALID; > - xfs_iext_get_extent(ifp, *idx - 1, &LEFT); > - > if (isnullstartblock(LEFT.br_startblock)) > state |= BMAP_LEFT_DELAY; > } > @@ -2117,9 +2112,8 @@ xfs_bmap_add_extent_unwritten_real( > * Don't set contiguous if the combined extent would be too large. > * Also check for all-three-contiguous being too large. > */ > - if (*idx < xfs_iext_count(ifp) - 1) { > + if (xfs_iext_peek_next_extent(ifp, icur, &RIGHT)) { > state |= BMAP_RIGHT_VALID; > - xfs_iext_get_extent(ifp, *idx + 1, &RIGHT); > if (isnullstartblock(RIGHT.br_startblock)) > state |= BMAP_RIGHT_DELAY; > } > @@ -2150,9 +2144,9 @@ xfs_bmap_add_extent_unwritten_real( > */ > LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount; > > - xfs_iext_remove(ip, *idx, 2, state); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &LEFT); > + xfs_iext_remove(ip, icur, 2, state); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &LEFT); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 2); > if (cur == NULL) > @@ -2188,9 +2182,9 @@ xfs_bmap_add_extent_unwritten_real( > */ > LEFT.br_blockcount += PREV.br_blockcount; > > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &LEFT); > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &LEFT); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > if (cur == NULL) > @@ -2221,10 +2215,10 @@ xfs_bmap_add_extent_unwritten_real( > PREV.br_blockcount += RIGHT.br_blockcount; > PREV.br_state = new->br_state; > > - ++*idx; > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &PREV); > + xfs_iext_next(ifp, icur); > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &PREV); > > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > @@ -2255,7 +2249,7 @@ xfs_bmap_add_extent_unwritten_real( > * the new one. > */ > PREV.br_state = new->br_state; > - xfs_iext_update_extent(ip, state, *idx, &PREV); > + xfs_iext_update_extent(ip, state, icur, &PREV); > > if (cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -2283,9 +2277,9 @@ xfs_bmap_add_extent_unwritten_real( > PREV.br_startblock += new->br_blockcount; > PREV.br_blockcount -= new->br_blockcount; > > - xfs_iext_update_extent(ip, state, *idx, &PREV); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &LEFT); > + xfs_iext_update_extent(ip, state, icur, &PREV); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &LEFT); > > if (cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -2317,8 +2311,8 @@ xfs_bmap_add_extent_unwritten_real( > PREV.br_startblock += new->br_blockcount; > PREV.br_blockcount -= new->br_blockcount; > > - xfs_iext_update_extent(ip, state, *idx, &PREV); > - xfs_iext_insert(ip, *idx, 1, new, state); > + xfs_iext_update_extent(ip, state, icur, &PREV); > + xfs_iext_insert(ip, icur, 1, new, state); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > if (cur == NULL) > @@ -2351,9 +2345,9 @@ xfs_bmap_add_extent_unwritten_real( > RIGHT.br_startblock = new->br_startblock; > RIGHT.br_blockcount += new->br_blockcount; > > - xfs_iext_update_extent(ip, state, *idx, &PREV); > - ++*idx; > - xfs_iext_update_extent(ip, state, *idx, &RIGHT); > + xfs_iext_update_extent(ip, state, icur, &PREV); > + xfs_iext_next(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &RIGHT); > > if (cur == NULL) > rval = XFS_ILOG_DEXT; > @@ -2383,9 +2377,9 @@ xfs_bmap_add_extent_unwritten_real( > old = PREV; > PREV.br_blockcount -= new->br_blockcount; > > - xfs_iext_update_extent(ip, state, *idx, &PREV); > - ++*idx; > - xfs_iext_insert(ip, *idx, 1, new, state); > + xfs_iext_update_extent(ip, state, icur, &PREV); > + xfs_iext_next(ifp, icur); > + xfs_iext_insert(ip, icur, 1, new, state); > > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > @@ -2426,9 +2420,9 @@ xfs_bmap_add_extent_unwritten_real( > r[1].br_startblock = new->br_startblock + new->br_blockcount; > r[1].br_state = PREV.br_state; > > - xfs_iext_update_extent(ip, state, *idx, &PREV); > - ++*idx; > - xfs_iext_insert(ip, *idx, 2, &r[0], state); > + xfs_iext_update_extent(ip, state, icur, &PREV); > + xfs_iext_next(ifp, icur); > + xfs_iext_insert(ip, icur, 2, &r[0], state); > > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 2); > @@ -2517,7 +2511,7 @@ STATIC void > xfs_bmap_add_extent_hole_delay( > xfs_inode_t *ip, /* incore inode pointer */ > int whichfork, > - xfs_extnum_t *idx, /* extent number to update/insert */ > + struct xfs_iext_cursor *icur, > xfs_bmbt_irec_t *new) /* new data to add to file extents */ > { > xfs_ifork_t *ifp; /* inode fork pointer */ > @@ -2534,10 +2528,8 @@ xfs_bmap_add_extent_hole_delay( > /* > * Check and set flags if this segment has a left neighbor > */ > - if (*idx > 0) { > + if (xfs_iext_peek_prev_extent(ifp, icur, &left)) { > state |= BMAP_LEFT_VALID; > - xfs_iext_get_extent(ifp, *idx - 1, &left); > - > if (isnullstartblock(left.br_startblock)) > state |= BMAP_LEFT_DELAY; > } > @@ -2546,10 +2538,8 @@ xfs_bmap_add_extent_hole_delay( > * Check and set flags if the current (right) segment exists. > * If it doesn't exist, we're converting the hole at end-of-file. > */ > - if (*idx < xfs_iext_count(ifp)) { > + if (xfs_iext_get_extent(ifp, icur, &right)) { > state |= BMAP_RIGHT_VALID; > - xfs_iext_get_extent(ifp, *idx, &right); > - > if (isnullstartblock(right.br_startblock)) > state |= BMAP_RIGHT_DELAY; > } > @@ -2592,9 +2582,9 @@ xfs_bmap_add_extent_hole_delay( > left.br_startblock = nullstartblock(newlen); > left.br_blockcount = temp; > > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &left); > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &left); > break; > > case BMAP_LEFT_CONTIG: > @@ -2612,8 +2602,8 @@ xfs_bmap_add_extent_hole_delay( > left.br_blockcount = temp; > left.br_startblock = nullstartblock(newlen); > > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &left); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &left); > break; > > case BMAP_RIGHT_CONTIG: > @@ -2630,7 +2620,7 @@ xfs_bmap_add_extent_hole_delay( > right.br_startoff = new->br_startoff; > right.br_startblock = nullstartblock(newlen); > right.br_blockcount = temp; > - xfs_iext_update_extent(ip, state, *idx, &right); > + xfs_iext_update_extent(ip, state, icur, &right); > break; > > case 0: > @@ -2640,7 +2630,7 @@ xfs_bmap_add_extent_hole_delay( > * Insert a new entry. > */ > oldlen = newlen = 0; > - xfs_iext_insert(ip, *idx, 1, new, state); > + xfs_iext_insert(ip, icur, 1, new, state); > break; > } > if (oldlen != newlen) { > @@ -2661,7 +2651,7 @@ xfs_bmap_add_extent_hole_real( > struct xfs_trans *tp, > struct xfs_inode *ip, > int whichfork, > - xfs_extnum_t *idx, > + struct xfs_iext_cursor *icur, > struct xfs_btree_cur **curp, > struct xfs_bmbt_irec *new, > xfs_fsblock_t *first, > @@ -2679,8 +2669,6 @@ xfs_bmap_add_extent_hole_real( > int state = xfs_bmap_fork_to_state(whichfork); > struct xfs_bmbt_irec old; > > - ASSERT(*idx >= 0); > - ASSERT(*idx <= xfs_iext_count(ifp)); > ASSERT(!isnullstartblock(new->br_startblock)); > ASSERT(!cur || !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); > > @@ -2689,9 +2677,8 @@ xfs_bmap_add_extent_hole_real( > /* > * Check and set flags if this segment has a left neighbor. > */ > - if (*idx > 0) { > + if (xfs_iext_peek_prev_extent(ifp, icur, &left)) { > state |= BMAP_LEFT_VALID; > - xfs_iext_get_extent(ifp, *idx - 1, &left); > if (isnullstartblock(left.br_startblock)) > state |= BMAP_LEFT_DELAY; > } > @@ -2700,9 +2687,8 @@ xfs_bmap_add_extent_hole_real( > * Check and set flags if this segment has a current value. > * Not true if we're inserting into the "hole" at eof. > */ > - if (*idx < xfs_iext_count(ifp)) { > + if (xfs_iext_get_extent(ifp, icur, &right)) { > state |= BMAP_RIGHT_VALID; > - xfs_iext_get_extent(ifp, *idx, &right); > if (isnullstartblock(right.br_startblock)) > state |= BMAP_RIGHT_DELAY; > } > @@ -2741,9 +2727,9 @@ xfs_bmap_add_extent_hole_real( > */ > left.br_blockcount += new->br_blockcount + right.br_blockcount; > > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &left); > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &left); > > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > @@ -2778,8 +2764,8 @@ xfs_bmap_add_extent_hole_real( > old = left; > left.br_blockcount += new->br_blockcount; > > - --*idx; > - xfs_iext_update_extent(ip, state, *idx, &left); > + xfs_iext_prev(ifp, icur); > + xfs_iext_update_extent(ip, state, icur, &left); > > if (cur == NULL) { > rval = xfs_ilog_fext(whichfork); > @@ -2806,7 +2792,7 @@ xfs_bmap_add_extent_hole_real( > right.br_startoff = new->br_startoff; > right.br_startblock = new->br_startblock; > right.br_blockcount += new->br_blockcount; > - xfs_iext_update_extent(ip, state, *idx, &right); > + xfs_iext_update_extent(ip, state, icur, &right); > > if (cur == NULL) { > rval = xfs_ilog_fext(whichfork); > @@ -2828,7 +2814,7 @@ xfs_bmap_add_extent_hole_real( > * real allocation. > * Insert a new entry. > */ > - xfs_iext_insert(ip, *idx, 1, new, state); > + xfs_iext_insert(ip, icur, 1, new, state); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > if (cur == NULL) { > @@ -3778,7 +3764,7 @@ xfs_bmapi_read( > struct xfs_bmbt_irec got; > xfs_fileoff_t obno; > xfs_fileoff_t end; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > int error; > bool eof = false; > int n = 0; > @@ -3820,7 +3806,7 @@ xfs_bmapi_read( > return error; > } > > - if (!xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got)) > + if (!xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) > eof = true; > end = bno + len; > obno = bno; > @@ -3852,7 +3838,7 @@ xfs_bmapi_read( > break; > > /* Else go on to the next record. */ > - if (!xfs_iext_get_extent(ifp, ++idx, &got)) > + if (!xfs_iext_next_extent(ifp, &icur, &got)) > eof = true; > } > *nmap = n; > @@ -3880,7 +3866,7 @@ xfs_bmapi_reserve_delalloc( > xfs_filblks_t len, > xfs_filblks_t prealloc, > struct xfs_bmbt_irec *got, > - xfs_extnum_t *lastx, > + struct xfs_iext_cursor *icur, > int eof) > { > struct xfs_mount *mp = ip->i_mount; > @@ -3910,7 +3896,7 @@ xfs_bmapi_reserve_delalloc( > if (extsz) { > struct xfs_bmbt_irec prev; > > - if (!xfs_iext_get_extent(ifp, *lastx - 1, &prev)) > + if (!xfs_iext_peek_prev_extent(ifp, icur, &prev)) > prev.br_startoff = NULLFILEOFF; > > error = xfs_bmap_extsize_align(mp, got, &prev, extsz, rt, eof, > @@ -3959,7 +3945,7 @@ xfs_bmapi_reserve_delalloc( > got->br_blockcount = alen; > got->br_state = XFS_EXT_NORM; > > - xfs_bmap_add_extent_hole_delay(ip, whichfork, lastx, got); > + xfs_bmap_add_extent_hole_delay(ip, whichfork, icur, got); > > /* > * Tag the inode if blocks were preallocated. Note that COW fork > @@ -4004,8 +3990,7 @@ xfs_bmapi_allocate( > if (bma->wasdel) { > bma->length = (xfs_extlen_t)bma->got.br_blockcount; > bma->offset = bma->got.br_startoff; > - if (bma->idx) > - xfs_iext_get_extent(ifp, bma->idx - 1, &bma->prev); > + xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev); > } else { > bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN); > if (!bma->eof) > @@ -4090,7 +4075,7 @@ xfs_bmapi_allocate( > error = xfs_bmap_add_extent_delay_real(bma, whichfork); > else > error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, > - whichfork, &bma->idx, &bma->cur, &bma->got, > + whichfork, &bma->icur, &bma->cur, &bma->got, > bma->firstblock, bma->dfops, &bma->logflags); > > bma->logflags |= tmp_logflags; > @@ -4102,7 +4087,7 @@ xfs_bmapi_allocate( > * or xfs_bmap_add_extent_hole_real might have merged it into one of > * the neighbouring ones. > */ > - xfs_iext_get_extent(ifp, bma->idx, &bma->got); > + xfs_iext_get_extent(ifp, &bma->icur, &bma->got); > > ASSERT(bma->got.br_startoff <= bma->offset); > ASSERT(bma->got.br_startoff + bma->got.br_blockcount >= > @@ -4160,8 +4145,8 @@ xfs_bmapi_convert_unwritten( > } > > error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, > - &bma->idx, &bma->cur, mval, bma->firstblock, bma->dfops, > - &tmp_logflags); > + &bma->icur, &bma->cur, mval, bma->firstblock, > + bma->dfops, &tmp_logflags); > /* > * Log the inode core unconditionally in the unwritten extent conversion > * path because the conversion might not have done so (e.g., if the > @@ -4183,7 +4168,7 @@ xfs_bmapi_convert_unwritten( > * xfs_bmap_add_extent_unwritten_real might have merged it into one > * of the neighbouring ones. > */ > - xfs_iext_get_extent(ifp, bma->idx, &bma->got); > + xfs_iext_get_extent(ifp, &bma->icur, &bma->got); > > /* > * We may have combined previously unwritten space with written space, > @@ -4302,9 +4287,9 @@ xfs_bmapi_write( > end = bno + len; > obno = bno; > > - if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.idx, &bma.got)) > + if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.icur, &bma.got)) > eof = true; > - if (!xfs_iext_get_extent(ifp, bma.idx - 1, &bma.prev)) > + if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev)) > bma.prev.br_startoff = NULLFILEOFF; > bma.tp = tp; > bma.ip = ip; > @@ -4409,7 +4394,7 @@ xfs_bmapi_write( > > /* Else go on to the next record. */ > bma.prev = bma.got; > - if (!xfs_iext_get_extent(ifp, ++bma.idx, &bma.got)) > + if (!xfs_iext_next_extent(ifp, &bma.icur, &bma.got)) > eof = true; > } > *nmap = n; > @@ -4482,7 +4467,7 @@ xfs_bmapi_remap( > struct xfs_btree_cur *cur = NULL; > xfs_fsblock_t firstblock = NULLFSBLOCK; > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > int logflags = 0, error; > > ASSERT(len > 0); > @@ -4506,7 +4491,7 @@ xfs_bmapi_remap( > return error; > } > > - if (xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got)) { > + if (xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) { > /* make sure we only reflink into a hole. */ > ASSERT(got.br_startoff > bno); > ASSERT(got.br_startoff - bno >= len); > @@ -4527,8 +4512,8 @@ xfs_bmapi_remap( > got.br_blockcount = len; > got.br_state = XFS_EXT_NORM; > > - error = xfs_bmap_add_extent_hole_real(tp, ip, XFS_DATA_FORK, &idx, &cur, > - &got, &firstblock, dfops, &logflags); > + error = xfs_bmap_add_extent_hole_real(tp, ip, XFS_DATA_FORK, &icur, > + &cur, &got, &firstblock, dfops, &logflags); > if (error) > goto error0; > > @@ -4644,7 +4629,7 @@ int > xfs_bmap_del_extent_delay( > struct xfs_inode *ip, > int whichfork, > - xfs_extnum_t *idx, > + struct xfs_iext_cursor *icur, > struct xfs_bmbt_irec *got, > struct xfs_bmbt_irec *del) > { > @@ -4666,8 +4651,6 @@ xfs_bmap_del_extent_delay( > da_old = startblockval(got->br_startblock); > da_new = 0; > > - ASSERT(*idx >= 0); > - ASSERT(*idx <= xfs_iext_count(ifp)); > ASSERT(del->br_blockcount > 0); > ASSERT(got->br_startoff <= del->br_startoff); > ASSERT(got_endoff >= del_endoff); > @@ -4701,8 +4684,8 @@ xfs_bmap_del_extent_delay( > /* > * Matches the whole extent. Delete the entry. > */ > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > break; > case BMAP_LEFT_FILLING: > /* > @@ -4713,7 +4696,7 @@ xfs_bmap_del_extent_delay( > da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, > got->br_blockcount), da_old); > got->br_startblock = nullstartblock((int)da_new); > - xfs_iext_update_extent(ip, state, *idx, got); > + xfs_iext_update_extent(ip, state, icur, got); > break; > case BMAP_RIGHT_FILLING: > /* > @@ -4723,7 +4706,7 @@ xfs_bmap_del_extent_delay( > da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, > got->br_blockcount), da_old); > got->br_startblock = nullstartblock((int)da_new); > - xfs_iext_update_extent(ip, state, *idx, got); > + xfs_iext_update_extent(ip, state, icur, got); > break; > case 0: > /* > @@ -4751,9 +4734,9 @@ xfs_bmap_del_extent_delay( > new.br_state = got->br_state; > new.br_startblock = nullstartblock((int)new_indlen); > > - xfs_iext_update_extent(ip, state, *idx, got); > - ++*idx; > - xfs_iext_insert(ip, *idx, 1, &new, state); > + xfs_iext_update_extent(ip, state, icur, got); > + xfs_iext_next(ifp, icur); > + xfs_iext_insert(ip, icur, 1, &new, state); > > da_new = got_indlen + new_indlen - stolen; > del->br_blockcount -= stolen; > @@ -4772,7 +4755,7 @@ xfs_bmap_del_extent_delay( > void > xfs_bmap_del_extent_cow( > struct xfs_inode *ip, > - xfs_extnum_t *idx, > + struct xfs_iext_cursor *icur, > struct xfs_bmbt_irec *got, > struct xfs_bmbt_irec *del) > { > @@ -4787,8 +4770,6 @@ xfs_bmap_del_extent_cow( > del_endoff = del->br_startoff + del->br_blockcount; > got_endoff = got->br_startoff + got->br_blockcount; > > - ASSERT(*idx >= 0); > - ASSERT(*idx <= xfs_iext_count(ifp)); > ASSERT(del->br_blockcount > 0); > ASSERT(got->br_startoff <= del->br_startoff); > ASSERT(got_endoff >= del_endoff); > @@ -4804,8 +4785,8 @@ xfs_bmap_del_extent_cow( > /* > * Matches the whole extent. Delete the entry. > */ > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > break; > case BMAP_LEFT_FILLING: > /* > @@ -4814,14 +4795,14 @@ xfs_bmap_del_extent_cow( > got->br_startoff = del_endoff; > got->br_blockcount -= del->br_blockcount; > got->br_startblock = del->br_startblock + del->br_blockcount; > - xfs_iext_update_extent(ip, state, *idx, got); > + xfs_iext_update_extent(ip, state, icur, got); > break; > case BMAP_RIGHT_FILLING: > /* > * Deleting the last part of the extent. > */ > got->br_blockcount -= del->br_blockcount; > - xfs_iext_update_extent(ip, state, *idx, got); > + xfs_iext_update_extent(ip, state, icur, got); > break; > case 0: > /* > @@ -4834,9 +4815,9 @@ xfs_bmap_del_extent_cow( > new.br_state = got->br_state; > new.br_startblock = del->br_startblock + del->br_blockcount; > > - xfs_iext_update_extent(ip, state, *idx, got); > - ++*idx; > - xfs_iext_insert(ip, *idx, 1, &new, state); > + xfs_iext_update_extent(ip, state, icur, got); > + xfs_iext_next(ifp, icur); > + xfs_iext_insert(ip, icur, 1, &new, state); > break; > } > } > @@ -4849,7 +4830,7 @@ STATIC int /* error */ > xfs_bmap_del_extent_real( > xfs_inode_t *ip, /* incore inode pointer */ > xfs_trans_t *tp, /* current transaction pointer */ > - xfs_extnum_t *idx, /* extent number to update/delete */ > + struct xfs_iext_cursor *icur, > struct xfs_defer_ops *dfops, /* list of extents to be freed */ > xfs_btree_cur_t *cur, /* if null, not a btree */ > xfs_bmbt_irec_t *del, /* data to remove from extents */ > @@ -4878,9 +4859,8 @@ xfs_bmap_del_extent_real( > XFS_STATS_INC(mp, xs_del_exlist); > > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT((*idx >= 0) && (*idx < xfs_iext_count(ifp))); > ASSERT(del->br_blockcount > 0); > - xfs_iext_get_extent(ifp, *idx, &got); > + xfs_iext_get_extent(ifp, icur, &got); > ASSERT(got.br_startoff <= del->br_startoff); > del_endoff = del->br_startoff + del->br_blockcount; > got_endoff = got.br_startoff + got.br_blockcount; > @@ -4945,9 +4925,8 @@ xfs_bmap_del_extent_real( > /* > * Matches the whole extent. Delete the entry. > */ > - xfs_iext_remove(ip, *idx, 1, state); > - --*idx; > - > + xfs_iext_remove(ip, icur, 1, state); > + xfs_iext_prev(ifp, icur); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > flags |= XFS_ILOG_CORE; > @@ -4966,7 +4945,7 @@ xfs_bmap_del_extent_real( > got.br_startoff = del_endoff; > got.br_startblock = del_endblock; > got.br_blockcount -= del->br_blockcount; > - xfs_iext_update_extent(ip, state, *idx, &got); > + xfs_iext_update_extent(ip, state, icur, &got); > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > break; > @@ -4980,7 +4959,7 @@ xfs_bmap_del_extent_real( > * Deleting the last part of the extent. > */ > got.br_blockcount -= del->br_blockcount; > - xfs_iext_update_extent(ip, state, *idx, &got); > + xfs_iext_update_extent(ip, state, icur, &got); > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > break; > @@ -4996,7 +4975,7 @@ xfs_bmap_del_extent_real( > old = got; > > got.br_blockcount = del->br_startoff - got.br_startoff; > - xfs_iext_update_extent(ip, state, *idx, &got); > + xfs_iext_update_extent(ip, state, icur, &got); > > new.br_startoff = del_endoff; > new.br_blockcount = got_endoff - del_endoff; > @@ -5040,7 +5019,7 @@ xfs_bmap_del_extent_real( > * Reset the extent record back > * to the original value. > */ > - xfs_iext_update_extent(ip, state, *idx, &old); > + xfs_iext_update_extent(ip, state, icur, &old); > flags = 0; > error = -ENOSPC; > goto done; > @@ -5050,8 +5029,8 @@ xfs_bmap_del_extent_real( > flags |= xfs_ilog_fext(whichfork); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > - ++*idx; > - xfs_iext_insert(ip, *idx, 1, &new, state); > + xfs_iext_next(ifp, icur); > + xfs_iext_insert(ip, icur, 1, &new, state); > break; > } > > @@ -5114,7 +5093,6 @@ __xfs_bunmapi( > xfs_bmbt_irec_t got; /* current extent record */ > xfs_ifork_t *ifp; /* inode fork pointer */ > int isrt; /* freeing in rt area */ > - xfs_extnum_t lastx; /* last extent index used */ > int logflags; /* transaction logging flags */ > xfs_extlen_t mod; /* rt extent offset */ > xfs_mount_t *mp; /* mount structure */ > @@ -5126,6 +5104,8 @@ __xfs_bunmapi( > xfs_fileoff_t max_len; > xfs_agnumber_t prev_agno = NULLAGNUMBER, agno; > xfs_fileoff_t end; > + struct xfs_iext_cursor icur; > + bool done = false; > > trace_xfs_bunmap(ip, start, len, flags, _RET_IP_); > > @@ -5168,7 +5148,7 @@ __xfs_bunmapi( > isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); > end = start + len; > > - if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &lastx, &got)) { > + if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &icur, &got)) { > *rlen = 0; > return 0; > } > @@ -5195,16 +5175,16 @@ __xfs_bunmapi( > } > > extno = 0; > - while (end != (xfs_fileoff_t)-1 && end >= start && lastx >= 0 && > + while (end != (xfs_fileoff_t)-1 && end >= start && > (nexts == 0 || extno < nexts) && max_len > 0) { > /* > * Is the found extent after a hole in which end lives? > * Just back up to the previous extent, if so. > */ > - if (got.br_startoff > end) { > - if (--lastx < 0) > - break; > - xfs_iext_get_extent(ifp, lastx, &got); > + if (got.br_startoff > end && > + !xfs_iext_prev_extent(ifp, &icur, &got)) { > + done = true; > + break; > } > /* > * Is the last block of this extent before the range > @@ -5267,10 +5247,10 @@ __xfs_bunmapi( > ASSERT(end >= mod); > end -= mod > del.br_blockcount ? > del.br_blockcount : mod; > - if (end < got.br_startoff) { > - if (--lastx >= 0) > - xfs_iext_get_extent(ifp, lastx, > - &got); > + if (end < got.br_startoff && > + !xfs_iext_prev_extent(ifp, &icur, &got)) { > + done = true; > + break; > } > continue; > } > @@ -5291,7 +5271,7 @@ __xfs_bunmapi( > } > del.br_state = XFS_EXT_UNWRITTEN; > error = xfs_bmap_add_extent_unwritten_real(tp, ip, > - whichfork, &lastx, &cur, &del, > + whichfork, &icur, &cur, &del, > firstblock, dfops, &logflags); > if (error) > goto error0; > @@ -5318,8 +5298,11 @@ __xfs_bunmapi( > */ > ASSERT(end >= del.br_blockcount); > end -= del.br_blockcount; > - if (got.br_startoff > end && --lastx >= 0) > - xfs_iext_get_extent(ifp, lastx, &got); > + if (got.br_startoff > end && > + !xfs_iext_prev_extent(ifp, &icur, &got)) { > + done = true; > + break; > + } > continue; > } else if (del.br_state == XFS_EXT_UNWRITTEN) { > struct xfs_bmbt_irec prev; > @@ -5330,8 +5313,8 @@ __xfs_bunmapi( > * Unwrite the killed part of that one and > * try again. > */ > - ASSERT(lastx > 0); > - xfs_iext_get_extent(ifp, lastx - 1, &prev); > + if (!xfs_iext_prev_extent(ifp, &icur, &prev)) > + ASSERT(0); > ASSERT(prev.br_state == XFS_EXT_NORM); > ASSERT(!isnullstartblock(prev.br_startblock)); > ASSERT(del.br_startblock == > @@ -5343,9 +5326,8 @@ __xfs_bunmapi( > prev.br_startoff = start; > } > prev.br_state = XFS_EXT_UNWRITTEN; > - lastx--; > error = xfs_bmap_add_extent_unwritten_real(tp, > - ip, whichfork, &lastx, &cur, > + ip, whichfork, &icur, &cur, > &prev, firstblock, dfops, > &logflags); > if (error) > @@ -5355,7 +5337,7 @@ __xfs_bunmapi( > ASSERT(del.br_state == XFS_EXT_NORM); > del.br_state = XFS_EXT_UNWRITTEN; > error = xfs_bmap_add_extent_unwritten_real(tp, > - ip, whichfork, &lastx, &cur, > + ip, whichfork, &icur, &cur, > &del, firstblock, dfops, > &logflags); > if (error) > @@ -5365,10 +5347,10 @@ __xfs_bunmapi( > } > > if (wasdel) { > - error = xfs_bmap_del_extent_delay(ip, whichfork, &lastx, > + error = xfs_bmap_del_extent_delay(ip, whichfork, &icur, > &got, &del); > } else { > - error = xfs_bmap_del_extent_real(ip, tp, &lastx, dfops, > + error = xfs_bmap_del_extent_real(ip, tp, &icur, dfops, > cur, &del, &tmp_logflags, whichfork, > flags); > logflags |= tmp_logflags; > @@ -5384,15 +5366,16 @@ __xfs_bunmapi( > * If not done go on to the next (previous) record. > */ > if (end != (xfs_fileoff_t)-1 && end >= start) { > - if (lastx >= 0) { > - xfs_iext_get_extent(ifp, lastx, &got); > - if (got.br_startoff > end && --lastx >= 0) > - xfs_iext_get_extent(ifp, lastx, &got); > + if (!xfs_iext_get_extent(ifp, &icur, &got) || > + (got.br_startoff > end && > + !xfs_iext_prev_extent(ifp, &icur, &got))) { > + done = true; > + break; > } > extno++; > } > } > - if (end == (xfs_fileoff_t)-1 || end < start || lastx < 0) > + if (done || end == (xfs_fileoff_t)-1 || end < start) > *rlen = 0; > else > *rlen = end - start + 1; > @@ -5513,7 +5496,7 @@ xfs_bmse_merge( > struct xfs_inode *ip, > int whichfork, > xfs_fileoff_t shift, /* shift fsb */ > - int *current_ext, /* idx of gotp */ > + struct xfs_iext_cursor *icur, > struct xfs_bmbt_irec *got, /* extent to shift */ > struct xfs_bmbt_irec *left, /* preceding extent */ > struct xfs_btree_cur *cur, > @@ -5568,10 +5551,10 @@ xfs_bmse_merge( > return error; > > done: > - xfs_iext_remove(ip, *current_ext, 1, 0); > - --*current_ext; > - xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), > - *current_ext, &new); > + xfs_iext_remove(ip, icur, 1, 0); > + xfs_iext_prev(XFS_IFORK_PTR(ip, whichfork), icur); > + xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, > + &new); > > /* update reverse mapping. rmap functions merge the rmaps for us */ > error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got); > @@ -5586,7 +5569,7 @@ static int > xfs_bmap_shift_update_extent( > struct xfs_inode *ip, > int whichfork, > - xfs_extnum_t idx, > + struct xfs_iext_cursor *icur, > struct xfs_bmbt_irec *got, > struct xfs_btree_cur *cur, > int *logflags, > @@ -5614,7 +5597,8 @@ xfs_bmap_shift_update_extent( > *logflags |= XFS_ILOG_DEXT; > } > > - xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), idx, got); > + xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, > + got); > > /* update reverse mapping */ > error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &prev); > @@ -5639,7 +5623,7 @@ xfs_bmap_collapse_extents( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_cur *cur = NULL; > struct xfs_bmbt_irec got, prev; > - xfs_extnum_t current_ext; > + struct xfs_iext_cursor icur; > xfs_fileoff_t new_startoff; > int error = 0; > int logflags = 0; > @@ -5670,14 +5654,14 @@ xfs_bmap_collapse_extents( > cur->bc_private.b.flags = 0; > } > > - if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, ¤t_ext, &got)) { > + if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) { > *done = true; > goto del_cursor; > } > XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock)); > > new_startoff = got.br_startoff - offset_shift_fsb; > - if (xfs_iext_get_extent(ifp, current_ext - 1, &prev)) { > + if (xfs_iext_peek_prev_extent(ifp, &icur, &prev)) { > if (new_startoff < prev.br_startoff + prev.br_blockcount) { > error = -EINVAL; > goto del_cursor; > @@ -5685,8 +5669,8 @@ xfs_bmap_collapse_extents( > > if (xfs_bmse_can_merge(&prev, &got, offset_shift_fsb)) { > error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb, > - ¤t_ext, &got, &prev, cur, > - &logflags, dfops); > + &icur, &got, &prev, cur, &logflags, > + dfops); > if (error) > goto del_cursor; > goto done; > @@ -5698,15 +5682,15 @@ xfs_bmap_collapse_extents( > } > } > > - error = xfs_bmap_shift_update_extent(ip, whichfork, current_ext, &got, > - cur, &logflags, dfops, new_startoff); > + error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, > + &logflags, dfops, new_startoff); > if (error) > goto del_cursor; > > done: > - if (!xfs_iext_get_extent(ifp, ++current_ext, &got)) { > - *done = true; > - goto del_cursor; > + if (!xfs_iext_next_extent(ifp, &icur, &got)) { > + *done = true; > + goto del_cursor; > } > > *next_fsb = got.br_startoff; > @@ -5735,7 +5719,7 @@ xfs_bmap_insert_extents( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_cur *cur = NULL; > struct xfs_bmbt_irec got, next; > - xfs_extnum_t current_ext; > + struct xfs_iext_cursor icur; > xfs_fileoff_t new_startoff; > int error = 0; > int logflags = 0; > @@ -5767,15 +5751,14 @@ xfs_bmap_insert_extents( > } > > if (*next_fsb == NULLFSBLOCK) { > - current_ext = xfs_iext_count(ifp) - 1; > - if (!xfs_iext_get_extent(ifp, current_ext, &got) || > + xfs_iext_last(ifp, &icur); > + if (!xfs_iext_get_extent(ifp, &icur, &got) || > stop_fsb > got.br_startoff) { > *done = true; > goto del_cursor; > } > } else { > - if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, ¤t_ext, > - &got)) { > + if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) { > *done = true; > goto del_cursor; > } > @@ -5788,7 +5771,7 @@ xfs_bmap_insert_extents( > } > > new_startoff = got.br_startoff + offset_shift_fsb; > - if (xfs_iext_get_extent(ifp, current_ext + 1, &next)) { > + if (xfs_iext_peek_next_extent(ifp, &icur, &next)) { > if (new_startoff + got.br_blockcount > next.br_startoff) { > error = -EINVAL; > goto del_cursor; > @@ -5804,12 +5787,12 @@ xfs_bmap_insert_extents( > WARN_ON_ONCE(1); > } > > - error = xfs_bmap_shift_update_extent(ip, whichfork, current_ext, &got, > - cur, &logflags, dfops, new_startoff); > + error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, > + &logflags, dfops, new_startoff); > if (error) > goto del_cursor; > > - if (!xfs_iext_get_extent(ifp, --current_ext, &got) || > + if (!xfs_iext_prev_extent(ifp, &icur, &got) || > stop_fsb >= got.br_startoff + got.br_blockcount) { > *done = true; > goto del_cursor; > @@ -5826,10 +5809,10 @@ xfs_bmap_insert_extents( > } > > /* > - * Splits an extent into two extents at split_fsb block such that it is > - * the first block of the current_ext. @current_ext is a target extent > - * to be split. @split_fsb is a block where the extents is split. > - * If split_fsb lies in a hole or the first block of extents, just return 0. > + * Splits an extent into two extents at split_fsb block such that it is the > + * first block of the current_ext. @ext is a target extent to be split. > + * @split_fsb is a block where the extents is split. If split_fsb lies in a > + * hole or the first block of extents, just return 0. > */ > STATIC int > xfs_bmap_split_extent_at( > @@ -5846,7 +5829,7 @@ xfs_bmap_split_extent_at( > struct xfs_mount *mp = ip->i_mount; > struct xfs_ifork *ifp; > xfs_fsblock_t gotblkcnt; /* new block count for got */ > - xfs_extnum_t current_ext; > + struct xfs_iext_cursor icur; > int error = 0; > int logflags = 0; > int i = 0; > @@ -5874,7 +5857,7 @@ xfs_bmap_split_extent_at( > /* > * If there are not extents, or split_fsb lies in a hole we are done. > */ > - if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, ¤t_ext, &got) || > + if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, &icur, &got) || > got.br_startoff >= split_fsb) > return 0; > > @@ -5896,8 +5879,8 @@ xfs_bmap_split_extent_at( > } > > got.br_blockcount = gotblkcnt; > - xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), > - current_ext, &got); > + xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), &icur, > + &got); > > logflags = XFS_ILOG_CORE; > if (cur) { > @@ -5908,8 +5891,8 @@ xfs_bmap_split_extent_at( > logflags |= XFS_ILOG_DEXT; > > /* Add new extent */ > - current_ext++; > - xfs_iext_insert(ip, current_ext, 1, &new, 0); > + xfs_iext_next(ifp, &icur); > + xfs_iext_insert(ip, &icur, 1, &new, 0); > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > > diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h > index a8777682ba57..b6a395949d0c 100644 > --- a/fs/xfs/libxfs/xfs_bmap.h > +++ b/fs/xfs/libxfs/xfs_bmap.h > @@ -43,7 +43,7 @@ struct xfs_bmalloca { > xfs_fsblock_t blkno; /* starting block of new extent */ > > struct xfs_btree_cur *cur; /* btree cursor */ > - xfs_extnum_t idx; /* current extent index */ > + struct xfs_iext_cursor icur; /* incore extent cursor */ > int nallocs;/* number of extents alloc'd */ > int logflags;/* flags for transaction logging */ > > @@ -216,10 +216,11 @@ int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, > xfs_extnum_t nexts, xfs_fsblock_t *firstblock, > struct xfs_defer_ops *dfops, int *done); > int xfs_bmap_del_extent_delay(struct xfs_inode *ip, int whichfork, > - xfs_extnum_t *idx, struct xfs_bmbt_irec *got, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, > + struct xfs_bmbt_irec *del); > +void xfs_bmap_del_extent_cow(struct xfs_inode *ip, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, > struct xfs_bmbt_irec *del); > -void xfs_bmap_del_extent_cow(struct xfs_inode *ip, xfs_extnum_t *idx, > - struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *del); > uint xfs_default_attroffset(struct xfs_inode *ip); > int xfs_bmap_collapse_extents(struct xfs_trans *tp, struct xfs_inode *ip, > xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, > @@ -232,7 +233,8 @@ int xfs_bmap_insert_extents(struct xfs_trans *tp, struct xfs_inode *ip, > int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); > int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, > xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc, > - struct xfs_bmbt_irec *got, xfs_extnum_t *lastx, int eof); > + struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur, > + int eof); > > enum xfs_bmap_intent_type { > XFS_BMAP_MAP = 1, > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 7dd77b497fc2..1e28532ff551 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -343,6 +343,7 @@ xfs_iformat_extents( > int state = xfs_bmap_fork_to_state(whichfork); > int nex = XFS_DFORK_NEXTENTS(dip, whichfork); > int size = nex * sizeof(xfs_bmbt_rec_t); > + struct xfs_iext_cursor icur; > struct xfs_bmbt_rec *dp; > int i; > > @@ -369,16 +370,21 @@ xfs_iformat_extents( > ifp->if_bytes = size; > if (size) { > dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); > + > + xfs_iext_first(ifp, &icur); > for (i = 0; i < nex; i++, dp++) { > xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); > + > if (!xfs_bmbt_validate_extent(mp, whichfork, dp)) { > XFS_ERROR_REPORT("xfs_iformat_extents(2)", > XFS_ERRLEVEL_LOW, mp); > return -EFSCORRUPTED; > } > + > ep->l0 = get_unaligned_be64(&dp->l0); > ep->l1 = get_unaligned_be64(&dp->l1); > - trace_xfs_read_extent(ip, i, state, _THIS_IP_); > + trace_xfs_read_extent(ip, &icur, state, _THIS_IP_); > + xfs_iext_next(ifp, &icur); > } > } > ifp->if_flags |= XFS_IFEXTENTS; > @@ -739,17 +745,18 @@ xfs_iextents_copy( > { > int state = xfs_bmap_fork_to_state(whichfork); > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > + struct xfs_iext_cursor icur; > struct xfs_bmbt_irec rec; > - int copied = 0, i = 0; > + int copied = 0; > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); > ASSERT(ifp->if_bytes > 0); > > - while (xfs_iext_get_extent(ifp, i++, &rec)) { > + for_each_iext(ifp, &icur, &rec) { > if (isnullstartblock(rec.br_startblock)) > continue; > xfs_bmbt_disk_set_all(dp, &rec); > - trace_xfs_write_extent(ip, i, state, _RET_IP_); > + trace_xfs_write_extent(ip, &icur, state, _RET_IP_); > ASSERT(xfs_bmbt_validate_extent(ip->i_mount, whichfork, dp)); > copied += sizeof(struct xfs_bmbt_rec); > dp++; > @@ -894,7 +901,7 @@ xfs_iext_state_to_fork( > void > xfs_iext_insert( > xfs_inode_t *ip, /* incore inode pointer */ > - xfs_extnum_t idx, /* starting index of new items */ > + struct xfs_iext_cursor *cur, > xfs_extnum_t count, /* number of inserted items */ > xfs_bmbt_irec_t *new, /* items to insert */ > int state) /* type of extent conversion */ > @@ -902,12 +909,12 @@ xfs_iext_insert( > xfs_ifork_t *ifp = xfs_iext_state_to_fork(ip, state); > xfs_extnum_t i; /* extent record index */ > > - trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); > + trace_xfs_iext_insert(ip, cur->idx, new, state, _RET_IP_); > > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > - xfs_iext_add(ifp, idx, count); > - for (i = idx; i < idx + count; i++, new++) > - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); > + xfs_iext_add(ifp, cur->idx, count); > + for (i = 0; i < count; i++, new++) > + xfs_bmbt_set_all(xfs_iext_get_ext(ifp, cur->idx + i), new); > } > > /* > @@ -1145,7 +1152,7 @@ xfs_iext_add_indirect_multi( > void > xfs_iext_remove( > xfs_inode_t *ip, /* incore inode pointer */ > - xfs_extnum_t idx, /* index to begin removing exts */ > + struct xfs_iext_cursor *cur, > int ext_diff, /* number of extents to remove */ > int state) /* type of extent conversion */ > { > @@ -1153,7 +1160,7 @@ xfs_iext_remove( > xfs_extnum_t nextents; /* number of extents in file */ > int new_size; /* size of extents after removal */ > > - trace_xfs_iext_remove(ip, idx, state, _RET_IP_); > + trace_xfs_iext_remove(ip, cur, state, _RET_IP_); > > ASSERT(ext_diff > 0); > nextents = xfs_iext_count(ifp); > @@ -1162,11 +1169,11 @@ xfs_iext_remove( > if (new_size == 0) { > xfs_iext_destroy(ifp); > } else if (ifp->if_flags & XFS_IFEXTIREC) { > - xfs_iext_remove_indirect(ifp, idx, ext_diff); > + xfs_iext_remove_indirect(ifp, cur->idx, ext_diff); > } else if (ifp->if_real_bytes) { > - xfs_iext_remove_direct(ifp, idx, ext_diff); > + xfs_iext_remove_direct(ifp, cur->idx, ext_diff); > } else { > - xfs_iext_remove_inline(ifp, idx, ext_diff); > + xfs_iext_remove_inline(ifp, cur->idx, ext_diff); > } > ifp->if_bytes = new_size; > } > @@ -1913,26 +1920,26 @@ xfs_ifork_init_cow( > * Lookup the extent covering bno. > * > * If there is an extent covering bno return the extent index, and store the > - * expanded extent structure in *gotp, and the extent index in *idx. > + * expanded extent structure in *gotp, and the extent cursor in *cur. > * If there is no extent covering bno, but there is an extent after it (e.g. > - * it lies in a hole) return that extent in *gotp and its index in *idx > + * it lies in a hole) return that extent in *gotp and its cursor in *cur > * instead. > - * If bno is beyond the last extent return false, and return the index after > - * the last valid index in *idxp. > + * If bno is beyond the last extent return false, and return an invalid > + * cursor value. > */ > bool > xfs_iext_lookup_extent( > struct xfs_inode *ip, > struct xfs_ifork *ifp, > xfs_fileoff_t bno, > - xfs_extnum_t *idxp, > + struct xfs_iext_cursor *cur, > struct xfs_bmbt_irec *gotp) > { > struct xfs_bmbt_rec_host *ep; > > XFS_STATS_INC(ip->i_mount, xs_look_exlist); > > - ep = xfs_iext_bno_to_ext(ifp, bno, idxp); > + ep = xfs_iext_bno_to_ext(ifp, bno, &cur->idx); > if (!ep) > return false; > xfs_bmbt_get_all(ep, gotp); > @@ -1948,31 +1955,31 @@ xfs_iext_lookup_extent_before( > struct xfs_inode *ip, > struct xfs_ifork *ifp, > xfs_fileoff_t *end, > - xfs_extnum_t *idxp, > + struct xfs_iext_cursor *cur, > struct xfs_bmbt_irec *gotp) > { > - if (xfs_iext_lookup_extent(ip, ifp, *end - 1, idxp, gotp) && > + if (xfs_iext_lookup_extent(ip, ifp, *end - 1, cur, gotp) && > gotp->br_startoff <= *end - 1) > return true; > - if (!xfs_iext_get_extent(ifp, --*idxp, gotp)) > + if (!xfs_iext_prev_extent(ifp, cur, gotp)) > return false; > *end = gotp->br_startoff + gotp->br_blockcount; > return true; > } > > /* > - * Return true if there is an extent at index idx, and return the expanded > - * extent structure at idx in that case. Else return false. > + * Return true if the cursor points at an extent and return the extent structure > + * in gotp. Else return false. > */ > bool > xfs_iext_get_extent( > struct xfs_ifork *ifp, > - xfs_extnum_t idx, > + struct xfs_iext_cursor *cur, > struct xfs_bmbt_irec *gotp) > { > - if (idx < 0 || idx >= xfs_iext_count(ifp)) > + if (cur->idx < 0 || cur->idx >= xfs_iext_count(ifp)) > return false; > - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp); > + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, cur->idx), gotp); > return true; > } > > @@ -1980,15 +1987,15 @@ void > xfs_iext_update_extent( > struct xfs_inode *ip, > int state, > - xfs_extnum_t idx, > + struct xfs_iext_cursor *cur, > struct xfs_bmbt_irec *gotp) > { > struct xfs_ifork *ifp = xfs_iext_state_to_fork(ip, state); > > - ASSERT(idx >= 0); > - ASSERT(idx < xfs_iext_count(ifp)); > + ASSERT(cur->idx >= 0); > + ASSERT(cur->idx < xfs_iext_count(ifp)); > > - trace_xfs_bmap_pre_update(ip, idx, state, _RET_IP_); > - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, idx), gotp); > - trace_xfs_bmap_post_update(ip, idx, state, _RET_IP_); > + trace_xfs_bmap_pre_update(ip, cur, state, _RET_IP_); > + xfs_bmbt_set_all(xfs_iext_get_ext(ifp, cur->idx), gotp); > + trace_xfs_bmap_post_update(ip, cur, state, _RET_IP_); > } > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index 113fd42ec36d..7065544f446a 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -151,12 +151,13 @@ void xfs_init_local_fork(struct xfs_inode *, int, const void *, int); > struct xfs_bmbt_rec_host * > xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t); > xfs_extnum_t xfs_iext_count(struct xfs_ifork *); > -void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t, > - struct xfs_bmbt_irec *, int); > +void xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur, > + xfs_extnum_t, struct xfs_bmbt_irec *, int); > void xfs_iext_add(struct xfs_ifork *, xfs_extnum_t, int); > void xfs_iext_add_indirect_multi(struct xfs_ifork *, int, > xfs_extnum_t, int); > -void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int); > +void xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *, > + int, int); > void xfs_iext_remove_inline(struct xfs_ifork *, xfs_extnum_t, int); > void xfs_iext_remove_direct(struct xfs_ifork *, xfs_extnum_t, int); > void xfs_iext_remove_indirect(struct xfs_ifork *, xfs_extnum_t, int); > @@ -182,15 +183,85 @@ void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int); > > bool xfs_iext_lookup_extent(struct xfs_inode *ip, > struct xfs_ifork *ifp, xfs_fileoff_t bno, > - xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp); > + struct xfs_iext_cursor *cur, > + struct xfs_bmbt_irec *gotp); > bool xfs_iext_lookup_extent_before(struct xfs_inode *ip, > struct xfs_ifork *ifp, xfs_fileoff_t *end, > - xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp); > - > -bool xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx, > + struct xfs_iext_cursor *cur, > + struct xfs_bmbt_irec *gotp); > +bool xfs_iext_get_extent(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur, > struct xfs_bmbt_irec *gotp); > void xfs_iext_update_extent(struct xfs_inode *ip, int state, > - xfs_extnum_t idx, struct xfs_bmbt_irec *gotp); > + struct xfs_iext_cursor *cur, > + struct xfs_bmbt_irec *gotp); > + > +static inline void xfs_iext_first(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur) > +{ > + cur->idx = 0; > +} > + > +static inline void xfs_iext_last(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur) > +{ > + cur->idx = xfs_iext_count(ifp) - 1; > +} > + > +static inline void xfs_iext_next(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur) > +{ > + cur->idx++; > +} > + > +static inline void xfs_iext_prev(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur) > +{ > + cur->idx--; > +} > + > +static inline bool xfs_iext_next_extent(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) > +{ > + xfs_iext_next(ifp, cur); > + return xfs_iext_get_extent(ifp, cur, gotp); > +} > + > +static inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) > +{ > + xfs_iext_prev(ifp, cur); > + return xfs_iext_get_extent(ifp, cur, gotp); > +} > + > +/* > + * Return the extent after cur in gotp without updating the cursor. > + */ > +static inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) > +{ > + struct xfs_iext_cursor ncur = *cur; > + > + xfs_iext_next(ifp, &ncur); > + return xfs_iext_get_extent(ifp, &ncur, gotp); > +} > + > +/* > + * Return the extent before cur in gotp without updating the cursor. > + */ > +static inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp, > + struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) > +{ > + struct xfs_iext_cursor ncur = *cur; > + > + xfs_iext_prev(ifp, &ncur); > + return xfs_iext_get_extent(ifp, &ncur, gotp); > +} > + > +#define for_each_iext(ifp, ext, got) \ > + for (xfs_iext_first((ifp), (ext)); \ > + xfs_iext_get_extent((ifp), (ext), (got)); \ > + xfs_iext_next((ifp), (ext))) > > extern struct kmem_zone *xfs_ifork_zone; > > diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h > index f04dbfb2f50d..5da6382bdaf1 100644 > --- a/fs/xfs/libxfs/xfs_types.h > +++ b/fs/xfs/libxfs/xfs_types.h > @@ -142,5 +142,8 @@ typedef uint32_t xfs_dqid_t; > #define XFS_NBWORD (1 << XFS_NBWORDLOG) > #define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) > > +struct xfs_iext_cursor { > + xfs_extnum_t idx; > +}; > > #endif /* __XFS_TYPES_H__ */ > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 3c17b182616f..be0bc11b6594 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -237,7 +237,7 @@ xfs_scrub_bmap( > struct xfs_inode *ip = sc->ip; > struct xfs_ifork *ifp; > xfs_fileoff_t endoff; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > bool found; > int error = 0; > > @@ -317,9 +317,9 @@ xfs_scrub_bmap( > /* Scrub extent records. */ > info.lastoff = 0; > ifp = XFS_IFORK_PTR(ip, whichfork); > - for (found = xfs_iext_lookup_extent(ip, ifp, 0, &idx, &irec); > + for (found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &irec); > found != 0; > - found = xfs_iext_get_extent(ifp, ++idx, &irec)) { > + found = xfs_iext_next_extent(ifp, &icur, &irec)) { > if (xfs_scrub_should_terminate(sc, &error)) > break; > if (isnullstartblock(irec.br_startblock)) > diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c > index c61362faed4a..73ac795aa6a5 100644 > --- a/fs/xfs/scrub/dir.c > +++ b/fs/xfs/scrub/dir.c > @@ -614,7 +614,7 @@ xfs_scrub_directory_blocks( > xfs_fileoff_t leaf_lblk; > xfs_fileoff_t free_lblk; > xfs_fileoff_t lblk; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > xfs_dablk_t dabno; > bool found; > int is_block = 0; > @@ -639,7 +639,7 @@ xfs_scrub_directory_blocks( > goto out; > > /* Iterate all the data extents in the directory... */ > - found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &idx, &got); > + found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); > while (found) { > /* Block directories only have a single block at offset 0. */ > if (is_block && > @@ -676,17 +676,17 @@ xfs_scrub_directory_blocks( > } > dabno = got.br_startoff + got.br_blockcount; > lblk = roundup(dabno, args.geo->fsbcount); > - found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &idx, &got); > + found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); > } > > if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > goto out; > > /* Look for a leaf1 block, which has free info. */ > - if (xfs_iext_lookup_extent(sc->ip, ifp, leaf_lblk, &idx, &got) && > + if (xfs_iext_lookup_extent(sc->ip, ifp, leaf_lblk, &icur, &got) && > got.br_startoff == leaf_lblk && > got.br_blockcount == args.geo->fsbcount && > - !xfs_iext_get_extent(ifp, ++idx, &got)) { > + !xfs_iext_next_extent(ifp, &icur, &got)) { > if (is_block) { > xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); > goto out; > @@ -702,7 +702,7 @@ xfs_scrub_directory_blocks( > > /* Scan for free blocks */ > lblk = free_lblk; > - found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &idx, &got); > + found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); > while (found) { > /* > * Dirs can't have blocks mapped above 2^32. > @@ -740,7 +740,7 @@ xfs_scrub_directory_blocks( > } > dabno = got.br_startoff + got.br_blockcount; > lblk = roundup(dabno, args.geo->fsbcount); > - found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &idx, &got); > + found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); > } > out: > return error; > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 170b74c7f2d5..515eec004971 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -229,15 +229,17 @@ xfs_bmap_count_leaves( > struct xfs_ifork *ifp, > xfs_filblks_t *count) > { > + struct xfs_iext_cursor icur; > struct xfs_bmbt_irec got; > - xfs_extnum_t numrecs = 0, i = 0; > + xfs_extnum_t numrecs = 0; > > - while (xfs_iext_get_extent(ifp, i++, &got)) { > + for_each_iext(ifp, &icur, &got) { > if (!isnullstartblock(got.br_startblock)) { > *count += got.br_blockcount; > numrecs++; > } > } > + > return numrecs; > } > > @@ -525,7 +527,7 @@ xfs_getbmap( > struct xfs_ifork *ifp; > struct xfs_bmbt_irec got, rec; > xfs_filblks_t len; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > if (bmv->bmv_iflags & ~BMV_IF_VALID) > return -EINVAL; > @@ -629,7 +631,7 @@ xfs_getbmap( > goto out_unlock_ilock; > } > > - if (!xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got)) { > + if (!xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) { > /* > * Report a whole-file hole if the delalloc flag is set to > * stay compatible with the old implementation. > @@ -668,7 +670,7 @@ xfs_getbmap( > goto out_unlock_ilock; > } while (xfs_getbmap_next_rec(&rec, bno)); > > - if (!xfs_iext_get_extent(ifp, ++idx, &got)) { > + if (!xfs_iext_next_extent(ifp, &icur, &got)) { > xfs_fileoff_t end = XFS_B_TO_FSB(mp, XFS_ISIZE(ip)); > > out[bmv->bmv_entries - 1].bmv_oflags |= BMV_OF_LAST; > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c > index 238e3650a9d2..0c58918bc0ad 100644 > --- a/fs/xfs/xfs_dir2_readdir.c > +++ b/fs/xfs/xfs_dir2_readdir.c > @@ -266,7 +266,7 @@ xfs_dir2_leaf_readbuf( > xfs_dablk_t next_ra; > xfs_dablk_t map_off; > xfs_dablk_t last_da; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > int ra_want; > int error = 0; > > @@ -283,7 +283,7 @@ xfs_dir2_leaf_readbuf( > */ > last_da = xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET); > map_off = xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, *cur_off)); > - if (!xfs_iext_lookup_extent(dp, ifp, map_off, &idx, &map)) > + if (!xfs_iext_lookup_extent(dp, ifp, map_off, &icur, &map)) > goto out; > if (map.br_startoff >= last_da) > goto out; > @@ -311,7 +311,7 @@ xfs_dir2_leaf_readbuf( > if (next_ra >= last_da) > goto out_no_ra; > if (map.br_blockcount < geo->fsbcount && > - !xfs_iext_get_extent(ifp, ++idx, &map)) > + !xfs_iext_next_extent(ifp, &icur, &map)) > goto out_no_ra; > if (map.br_startoff >= last_da) > goto out_no_ra; > @@ -334,7 +334,7 @@ xfs_dir2_leaf_readbuf( > ra_want -= geo->fsbcount; > next_ra += geo->fsbcount; > } > - if (!xfs_iext_get_extent(ifp, ++idx, &map)) { > + if (!xfs_iext_next_extent(ifp, &icur, &map)) { > *ra_blk = last_da; > break; > } > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index cd82429d8df7..8338b894d54f 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -703,7 +703,7 @@ xfs_dq_get_next_id( > xfs_dqid_t next_id = *id + 1; /* simple advance */ > uint lock_flags; > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor cur; > xfs_fsblock_t start; > int error = 0; > > @@ -727,7 +727,7 @@ xfs_dq_get_next_id( > return error; > } > > - if (xfs_iext_lookup_extent(quotip, "ip->i_df, start, &idx, &got)) { > + if (xfs_iext_lookup_extent(quotip, "ip->i_df, start, &cur, &got)) { > /* contiguous chunk, bump startoff for the id calculation */ > if (got.br_startoff < start) > got.br_startoff = start; > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index da0abc8a0725..ad48e2f24699 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -390,7 +390,7 @@ xfs_iomap_prealloc_size( > struct xfs_inode *ip, > loff_t offset, > loff_t count, > - xfs_extnum_t idx) > + struct xfs_iext_cursor *icur) > { > struct xfs_mount *mp = ip->i_mount; > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > @@ -415,7 +415,7 @@ xfs_iomap_prealloc_size( > */ > if ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) || > XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) || > - !xfs_iext_get_extent(ifp, idx - 1, &prev) || > + !xfs_iext_peek_prev_extent(ifp, icur, &prev) || > prev.br_startoff + prev.br_blockcount < offset_fsb) > return mp->m_writeio_blocks; > > @@ -533,7 +533,7 @@ xfs_file_iomap_begin_delay( > xfs_fileoff_t end_fsb; > int error = 0, eof = 0; > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > xfs_fsblock_t prealloc_blocks = 0; > > ASSERT(!XFS_IS_REALTIME_INODE(ip)); > @@ -558,7 +558,7 @@ xfs_file_iomap_begin_delay( > goto out_unlock; > } > > - eof = !xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got); > + eof = !xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got); > if (!eof && got.br_startoff <= offset_fsb) { > if (xfs_is_reflink_inode(ip)) { > bool shared; > @@ -592,7 +592,8 @@ xfs_file_iomap_begin_delay( > end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb); > > if (eof) { > - prealloc_blocks = xfs_iomap_prealloc_size(ip, offset, count, idx); > + prealloc_blocks = xfs_iomap_prealloc_size(ip, offset, count, > + &icur); > if (prealloc_blocks) { > xfs_extlen_t align; > xfs_off_t end_offset; > @@ -614,7 +615,8 @@ xfs_file_iomap_begin_delay( > > retry: > error = xfs_bmapi_reserve_delalloc(ip, XFS_DATA_FORK, offset_fsb, > - end_fsb - offset_fsb, prealloc_blocks, &got, &idx, eof); > + end_fsb - offset_fsb, prealloc_blocks, &got, &icur, > + eof); > switch (error) { > case 0: > break; > diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c > index 1205747e1409..d86c4378facf 100644 > --- a/fs/xfs/xfs_reflink.c > +++ b/fs/xfs/xfs_reflink.c > @@ -273,7 +273,7 @@ xfs_reflink_reserve_cow( > struct xfs_bmbt_irec got; > int error = 0; > bool eof = false, trimmed; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > /* > * Search the COW fork extent list first. This serves two purposes: > @@ -284,7 +284,7 @@ xfs_reflink_reserve_cow( > * tree. > */ > > - if (!xfs_iext_lookup_extent(ip, ifp, imap->br_startoff, &idx, &got)) > + if (!xfs_iext_lookup_extent(ip, ifp, imap->br_startoff, &icur, &got)) > eof = true; > if (!eof && got.br_startoff <= imap->br_startoff) { > trace_xfs_reflink_cow_found(ip, imap); > @@ -312,7 +312,7 @@ xfs_reflink_reserve_cow( > return error; > > error = xfs_bmapi_reserve_delalloc(ip, XFS_COW_FORK, imap->br_startoff, > - imap->br_blockcount, 0, &got, &idx, eof); > + imap->br_blockcount, 0, &got, &icur, eof); > if (error == -ENOSPC || error == -EDQUOT) > trace_xfs_reflink_cow_enospc(ip, imap); > if (error) > @@ -359,16 +359,16 @@ xfs_reflink_convert_cow( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); > xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); > xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + count); > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > bool found; > int error = 0; > > xfs_ilock(ip, XFS_ILOCK_EXCL); > > /* Convert all the extents to real from unwritten. */ > - for (found = xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got); > + for (found = xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got); > found && got.br_startoff < end_fsb; > - found = xfs_iext_get_extent(ifp, ++idx, &got)) { > + found = xfs_iext_next_extent(ifp, &icur, &got)) { > error = xfs_reflink_convert_cow_extent(ip, &got, offset_fsb, > end_fsb - offset_fsb, &dfops); > if (error) > @@ -399,7 +399,7 @@ xfs_reflink_allocate_cow( > bool trimmed; > xfs_filblks_t resaligned; > xfs_extlen_t resblks = 0; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > retry: > ASSERT(xfs_is_reflink_inode(ip)); > @@ -409,7 +409,7 @@ xfs_reflink_allocate_cow( > * Even if the extent is not shared we might have a preallocation for > * it in the COW fork. If so use it. > */ > - if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &idx, &got) && > + if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got) && > got.br_startoff <= offset_fsb) { > *shared = true; > > @@ -496,13 +496,13 @@ xfs_reflink_find_cow_mapping( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); > xfs_fileoff_t offset_fsb; > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); > ASSERT(xfs_is_reflink_inode(ip)); > > offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); > - if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got)) > + if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) > return false; > if (got.br_startoff > offset_fsb) > return false; > @@ -524,18 +524,18 @@ xfs_reflink_trim_irec_to_next_cow( > { > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); > struct xfs_bmbt_irec got; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > if (!xfs_is_reflink_inode(ip)) > return; > > /* Find the extent in the CoW fork. */ > - if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got)) > + if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) > return; > > /* This is the extent before; try sliding up one. */ > if (got.br_startoff < offset_fsb) { > - if (!xfs_iext_get_extent(ifp, idx + 1, &got)) > + if (!xfs_iext_next_extent(ifp, &icur, &got)) > return; > } > > @@ -562,14 +562,14 @@ xfs_reflink_cancel_cow_blocks( > { > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); > struct xfs_bmbt_irec got, del; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > xfs_fsblock_t firstfsb; > struct xfs_defer_ops dfops; > int error = 0; > > if (!xfs_is_reflink_inode(ip)) > return 0; > - if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got)) > + if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) > return 0; > > while (got.br_startoff < end_fsb) { > @@ -579,7 +579,7 @@ xfs_reflink_cancel_cow_blocks( > > if (isnullstartblock(del.br_startblock)) { > error = xfs_bmap_del_extent_delay(ip, XFS_COW_FORK, > - &idx, &got, &del); > + &icur, &got, &del); > if (error) > break; > } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { > @@ -610,10 +610,10 @@ xfs_reflink_cancel_cow_blocks( > } > > /* Remove the mapping from the CoW fork. */ > - xfs_bmap_del_extent_cow(ip, &idx, &got, &del); > + xfs_bmap_del_extent_cow(ip, &icur, &got, &del); > } > > - if (!xfs_iext_get_extent(ifp, ++idx, &got)) > + if (!xfs_iext_next_extent(ifp, &icur, &got)) > break; > } > > @@ -698,7 +698,7 @@ xfs_reflink_end_cow( > int error; > unsigned int resblks; > xfs_filblks_t rlen; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > > trace_xfs_reflink_end_cow(ip, offset, count); > > @@ -738,7 +738,7 @@ xfs_reflink_end_cow( > * left by the time I/O completes for the loser of the race. In that > * case we are done. > */ > - if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &idx, &got)) > + if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got)) > goto out_cancel; > > /* Walk backwards until we're out of the I/O range... */ > @@ -746,9 +746,9 @@ xfs_reflink_end_cow( > del = got; > xfs_trim_extent(&del, offset_fsb, end_fsb - offset_fsb); > > - /* Extent delete may have bumped idx forward */ > + /* Extent delete may have bumped ext forward */ > if (!del.br_blockcount) { > - idx--; > + xfs_iext_prev(ifp, &icur); > goto next_extent; > } > > @@ -760,7 +760,7 @@ xfs_reflink_end_cow( > * allocated but have not yet been involved in a write. > */ > if (got.br_state == XFS_EXT_UNWRITTEN) { > - idx--; > + xfs_iext_prev(ifp, &icur); > goto next_extent; > } > > @@ -791,14 +791,14 @@ xfs_reflink_end_cow( > goto out_defer; > > /* Remove the mapping from the CoW fork. */ > - xfs_bmap_del_extent_cow(ip, &idx, &got, &del); > + xfs_bmap_del_extent_cow(ip, &icur, &got, &del); > > xfs_defer_ijoin(&dfops, ip); > error = xfs_defer_finish(&tp, &dfops); > if (error) > goto out_defer; > next_extent: > - if (!xfs_iext_get_extent(ifp, idx, &got)) > + if (!xfs_iext_get_extent(ifp, &icur, &got)) > break; > } > > @@ -1428,7 +1428,7 @@ xfs_reflink_inode_has_shared_extents( > xfs_extlen_t aglen; > xfs_agblock_t rbno; > xfs_extlen_t rlen; > - xfs_extnum_t idx; > + struct xfs_iext_cursor icur; > bool found; > int error; > > @@ -1440,7 +1440,7 @@ xfs_reflink_inode_has_shared_extents( > } > > *has_shared = false; > - found = xfs_iext_lookup_extent(ip, ifp, 0, &idx, &got); > + found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got); > while (found) { > if (isnullstartblock(got.br_startblock) || > got.br_state != XFS_EXT_NORM) > @@ -1459,7 +1459,7 @@ xfs_reflink_inode_has_shared_extents( > return 0; > } > next: > - found = xfs_iext_get_extent(ifp, ++idx, &got); > + found = xfs_iext_next_extent(ifp, &icur, &got); > } > > return 0; > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 665ef6cca90c..667bfce802cd 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -258,9 +258,9 @@ TRACE_EVENT(xfs_iext_insert, > ); > > DECLARE_EVENT_CLASS(xfs_bmap_class, > - TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, int state, > + TP_PROTO(struct xfs_inode *ip, struct xfs_iext_cursor *cur, int state, > unsigned long caller_ip), > - TP_ARGS(ip, idx, state, caller_ip), > + TP_ARGS(ip, cur, state, caller_ip), > TP_STRUCT__entry( > __field(dev_t, dev) > __field(xfs_ino_t, ino) > @@ -277,10 +277,10 @@ DECLARE_EVENT_CLASS(xfs_bmap_class, > struct xfs_bmbt_irec r; > > ifp = xfs_iext_state_to_fork(ip, state); > - xfs_iext_get_extent(ifp, idx, &r); > + xfs_iext_get_extent(ifp, cur, &r); > __entry->dev = VFS_I(ip)->i_sb->s_dev; > __entry->ino = ip->i_ino; > - __entry->idx = idx; > + __entry->idx = cur->idx; > __entry->startoff = r.br_startoff; > __entry->startblock = r.br_startblock; > __entry->blockcount = r.br_blockcount; > @@ -303,9 +303,9 @@ DECLARE_EVENT_CLASS(xfs_bmap_class, > > #define DEFINE_BMAP_EVENT(name) \ > DEFINE_EVENT(xfs_bmap_class, name, \ > - TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, int state, \ > + TP_PROTO(struct xfs_inode *ip, struct xfs_iext_cursor *cur, int state, \ > unsigned long caller_ip), \ > - TP_ARGS(ip, idx, state, caller_ip)) > + TP_ARGS(ip, cur, state, caller_ip)) > DEFINE_BMAP_EVENT(xfs_iext_remove); > DEFINE_BMAP_EVENT(xfs_bmap_pre_update); > DEFINE_BMAP_EVENT(xfs_bmap_post_update); > -- > 2.14.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html