diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 441 |
1 files changed, 212 insertions, 229 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index f4d0639dc4ae..e48fc5c6fcdf 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_xfs_iext(ifp, &icur, &rec) { 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_xfs_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 @@ nodelete: * 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 @@ del_cursor: } /* - * 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); |