Commit b2b1712a authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

xfs: introduce the xfs_iext_cursor abstraction

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.

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