aboutsummaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c1360
1 files changed, 629 insertions, 731 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 70625e577c7..d384e489705 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -89,7 +89,7 @@ xfs_bmap_add_attrfork_local(
int *flags); /* inode logging flags */
/*
- * Called by xfs_bmapi to update extent list structure and the btree
+ * Called by xfs_bmapi to update file extent records and the btree
* after allocating space (or doing a delayed allocation).
*/
STATIC int /* error */
@@ -97,7 +97,7 @@ xfs_bmap_add_extent(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
@@ -113,7 +113,7 @@ xfs_bmap_add_extent_delay_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
@@ -129,7 +129,7 @@ xfs_bmap_add_extent_hole_delay(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
int rsvd); /* OK to allocate reserved blocks */
@@ -142,7 +142,7 @@ xfs_bmap_add_extent_hole_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
int whichfork); /* data or attr fork */
@@ -155,7 +155,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp); /* inode logging flags */
/*
@@ -169,7 +169,7 @@ xfs_bmap_alloc(
/*
* Transform a btree format file with only one leaf node, where the
* extents list will fit in the inode, into an extents format file.
- * Since the extent list is already in-core, all we have to do is
+ * Since the file extents are already in-core, all we have to do is
* give up the space for the btree root and pitch the leaf block.
*/
STATIC int /* error */
@@ -191,7 +191,7 @@ xfs_bmap_check_extents(
#endif
/*
- * Called by xfs_bmapi to update extent list structure and the btree
+ * Called by xfs_bmapi to update file extent records and the btree
* after removing space (or undoing a delayed allocation).
*/
STATIC int /* error */
@@ -201,7 +201,7 @@ xfs_bmap_del_extent(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_bmap_free_t *flist, /* list of extents to be freed */
xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
int whichfork, /* data or attr fork */
int rsvd); /* OK to allocate reserved blocks */
@@ -217,18 +217,6 @@ xfs_bmap_del_free(
xfs_bmap_free_item_t *free); /* list item to be freed */
/*
- * Remove count entries from the extents array for inode "ip", starting
- * at index "idx". Copies the remaining items down over the deleted ones,
- * and gives back the excess memory.
- */
-STATIC void
-xfs_bmap_delete_exlist(
- xfs_inode_t *ip, /* incode inode pointer */
- xfs_extnum_t idx, /* starting delete index */
- xfs_extnum_t count, /* count of items to delete */
- int whichfork); /* data or attr fork */
-
-/*
* Convert an extents-format file into a btree-format file.
* The new file will have a root block (in the inode) and a single child block.
*/
@@ -244,18 +232,6 @@ xfs_bmap_extents_to_btree(
int whichfork); /* data or attr fork */
/*
- * Insert new item(s) in the extent list for inode "ip".
- * Count new items are inserted at offset idx.
- */
-STATIC void
-xfs_bmap_insert_exlist(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* starting index of new items */
- xfs_extnum_t count, /* number of inserted items */
- xfs_bmbt_irec_t *new, /* items to insert */
- int whichfork); /* data or attr fork */
-
-/*
* Convert a local file to an extents file.
* This code is sort of bogus, since the file data needs to get
* logged so it won't be lost. The bmap-level manipulations are ok, though.
@@ -316,7 +292,7 @@ xfs_bmap_trace_addentry(
int whichfork); /* data or attr fork */
/*
- * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist.
+ * Add bmap trace entry prior to a call to xfs_iext_remove.
*/
STATIC void
xfs_bmap_trace_delete(
@@ -328,7 +304,7 @@ xfs_bmap_trace_delete(
int whichfork); /* data or attr fork */
/*
- * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or
+ * Add bmap trace entry prior to a call to xfs_iext_insert, or
* reading in the extents list from the disk (in the btree).
*/
STATIC void
@@ -343,7 +319,7 @@ xfs_bmap_trace_insert(
int whichfork); /* data or attr fork */
/*
- * Add bmap trace entry after updating an extent list entry in place.
+ * Add bmap trace entry after updating an extent record in place.
*/
STATIC void
xfs_bmap_trace_post_update(
@@ -354,7 +330,7 @@ xfs_bmap_trace_post_update(
int whichfork); /* data or attr fork */
/*
- * Add bmap trace entry prior to updating an extent list entry in place.
+ * Add bmap trace entry prior to updating an extent record in place.
*/
STATIC void
xfs_bmap_trace_pre_update(
@@ -413,19 +389,24 @@ STATIC int
xfs_bmap_count_tree(
xfs_mount_t *mp,
xfs_trans_t *tp,
+ xfs_ifork_t *ifp,
xfs_fsblock_t blockno,
int levelin,
int *count);
STATIC int
xfs_bmap_count_leaves(
- xfs_bmbt_rec_t *frp,
+ xfs_ifork_t *ifp,
+ xfs_extnum_t idx,
int numrecs,
int *count);
STATIC int
xfs_bmap_disk_count_leaves(
- xfs_bmbt_rec_t *frp,
+ xfs_ifork_t *ifp,
+ xfs_mount_t *mp,
+ xfs_extnum_t idx,
+ xfs_bmbt_block_t *block,
int numrecs,
int *count);
@@ -537,7 +518,7 @@ xfs_bmap_add_attrfork_local(
}
/*
- * Called by xfs_bmapi to update extent list structure and the btree
+ * Called by xfs_bmapi to update file extent records and the btree
* after allocating space (or doing a delayed allocation).
*/
STATIC int /* error */
@@ -545,7 +526,7 @@ xfs_bmap_add_extent(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
@@ -578,7 +559,7 @@ xfs_bmap_add_extent(
if (nextents == 0) {
xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new,
NULL, whichfork);
- xfs_bmap_insert_exlist(ip, 0, 1, new, whichfork);
+ xfs_iext_insert(ifp, 0, 1, new);
ASSERT(cur == NULL);
ifp->if_lastex = 0;
if (!ISNULLSTARTBLOCK(new->br_startblock)) {
@@ -614,7 +595,7 @@ xfs_bmap_add_extent(
/*
* Get the record referred to by idx.
*/
- xfs_bmbt_get_all(&ifp->if_u1.if_extents[idx], &prev);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev);
/*
* If it's a real allocation record, and the new allocation ends
* after the start of the referred to record, then we're filling
@@ -714,14 +695,13 @@ xfs_bmap_add_extent_delay_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
int rsvd) /* OK to use reserved data block allocation */
{
- xfs_bmbt_rec_t *base; /* base of extent entry list */
xfs_btree_cur_t *cur; /* btree cursor */
int diff; /* temp value */
xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -730,6 +710,7 @@ xfs_bmap_add_extent_delay_real(
static char fname[] = "xfs_bmap_add_extent_delay_real";
#endif
int i; /* temp state */
+ xfs_ifork_t *ifp; /* inode fork pointer */
xfs_fileoff_t new_endoff; /* end offset of new entry */
xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
/* left is 0, right is 1, prev is 2 */
@@ -763,8 +744,8 @@ xfs_bmap_add_extent_delay_real(
* Set up a bunch of variables to make the tests simpler.
*/
cur = *curp;
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx];
+ ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+ ep = xfs_iext_get_ext(ifp, idx);
xfs_bmbt_get_all(ep, &PREV);
new_endoff = new->br_startoff + new->br_blockcount;
ASSERT(PREV.br_startoff <= new->br_startoff);
@@ -781,7 +762,7 @@ xfs_bmap_add_extent_delay_real(
* Don't set contiguous if the combined extent would be too large.
*/
if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(ep - 1, &LEFT);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
}
STATE_SET(LEFT_CONTIG,
@@ -798,7 +779,7 @@ xfs_bmap_add_extent_delay_real(
if (STATE_SET_TEST(RIGHT_VALID,
idx <
ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
- xfs_bmbt_get_all(ep + 1, &RIGHT);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
}
STATE_SET(RIGHT_CONTIG,
@@ -825,14 +806,14 @@ xfs_bmap_add_extent_delay_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + PREV.br_blockcount +
RIGHT.br_blockcount);
xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
XFS_DATA_FORK);
xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx, 2);
ip->i_df.if_lastex = idx - 1;
ip->i_d.di_nextents--;
if (cur == NULL)
@@ -867,14 +848,14 @@ xfs_bmap_add_extent_delay_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + PREV.br_blockcount);
xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
XFS_DATA_FORK);
ip->i_df.if_lastex = idx - 1;
xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx, 1);
if (cur == NULL)
rval = XFS_ILOG_DEXT;
else {
@@ -908,7 +889,7 @@ xfs_bmap_add_extent_delay_real(
ip->i_df.if_lastex = idx;
xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx + 1, 1);
if (cur == NULL)
rval = XFS_ILOG_DEXT;
else {
@@ -964,7 +945,7 @@ xfs_bmap_add_extent_delay_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + new->br_blockcount);
xfs_bmbt_set_startoff(ep,
PREV.br_startoff + new->br_blockcount);
@@ -1010,7 +991,7 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_blockcount(ep, temp);
xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx, 1, new);
ip->i_df.if_lastex = idx;
ip->i_d.di_nextents++;
if (cur == NULL)
@@ -1039,8 +1020,7 @@ xfs_bmap_add_extent_delay_real(
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
STARTBLOCKVAL(PREV.br_startblock) -
(cur ? cur->bc_private.b.allocated : 0));
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx + 1];
+ ep = xfs_iext_get_ext(ifp, idx + 1);
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
XFS_DATA_FORK);
@@ -1058,7 +1038,8 @@ xfs_bmap_add_extent_delay_real(
xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1,
XFS_DATA_FORK);
xfs_bmbt_set_blockcount(ep, temp);
- xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock,
+ xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
+ new->br_startoff, new->br_startblock,
new->br_blockcount + RIGHT.br_blockcount,
RIGHT.br_state);
xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
@@ -1098,7 +1079,7 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_blockcount(ep, temp);
xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
new, NULL, XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx + 1, 1, new);
ip->i_df.if_lastex = idx + 1;
ip->i_d.di_nextents++;
if (cur == NULL)
@@ -1127,8 +1108,7 @@ xfs_bmap_add_extent_delay_real(
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
STARTBLOCKVAL(PREV.br_startblock) -
(cur ? cur->bc_private.b.allocated : 0));
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx];
+ ep = xfs_iext_get_ext(ifp, idx);
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
*dnew = temp;
@@ -1149,7 +1129,7 @@ xfs_bmap_add_extent_delay_real(
r[1].br_blockcount = temp2;
xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
ip->i_df.if_lastex = idx + 1;
ip->i_d.di_nextents++;
if (cur == NULL)
@@ -1204,13 +1184,13 @@ xfs_bmap_add_extent_delay_real(
}
}
}
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx];
+ ep = xfs_iext_get_ext(ifp, idx);
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK);
xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2,
XFS_DATA_FORK);
- xfs_bmbt_set_startblock(ep + 2, NULLSTARTBLOCK((int)temp2));
+ xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2),
+ NULLSTARTBLOCK((int)temp2));
xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
XFS_DATA_FORK);
*dnew = temp + temp2;
@@ -1254,10 +1234,9 @@ xfs_bmap_add_extent_unwritten_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp) /* inode logging flags */
{
- xfs_bmbt_rec_t *base; /* base of extent entry list */
xfs_btree_cur_t *cur; /* btree cursor */
xfs_bmbt_rec_t *ep; /* extent entry for idx */
int error; /* error return value */
@@ -1265,6 +1244,7 @@ xfs_bmap_add_extent_unwritten_real(
static char fname[] = "xfs_bmap_add_extent_unwritten_real";
#endif
int i; /* temp state */
+ xfs_ifork_t *ifp; /* inode fork pointer */
xfs_fileoff_t new_endoff; /* end offset of new entry */
xfs_exntst_t newext; /* new extent state */
xfs_exntst_t oldext; /* old extent state */
@@ -1298,8 +1278,8 @@ xfs_bmap_add_extent_unwritten_real(
*/
error = 0;
cur = *curp;
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx];
+ ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+ ep = xfs_iext_get_ext(ifp, idx);
xfs_bmbt_get_all(ep, &PREV);
newext = new->br_state;
oldext = (newext == XFS_EXT_UNWRITTEN) ?
@@ -1320,7 +1300,7 @@ xfs_bmap_add_extent_unwritten_real(
* Don't set contiguous if the combined extent would be too large.
*/
if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(ep - 1, &LEFT);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
}
STATE_SET(LEFT_CONTIG,
@@ -1337,7 +1317,7 @@ xfs_bmap_add_extent_unwritten_real(
if (STATE_SET_TEST(RIGHT_VALID,
idx <
ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
- xfs_bmbt_get_all(ep + 1, &RIGHT);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
}
STATE_SET(RIGHT_CONTIG,
@@ -1363,14 +1343,14 @@ xfs_bmap_add_extent_unwritten_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + PREV.br_blockcount +
RIGHT.br_blockcount);
xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
XFS_DATA_FORK);
xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx, 2);
ip->i_df.if_lastex = idx - 1;
ip->i_d.di_nextents -= 2;
if (cur == NULL)
@@ -1409,14 +1389,14 @@ xfs_bmap_add_extent_unwritten_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + PREV.br_blockcount);
xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
XFS_DATA_FORK);
ip->i_df.if_lastex = idx - 1;
xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx, 1);
ip->i_d.di_nextents--;
if (cur == NULL)
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1456,7 +1436,7 @@ xfs_bmap_add_extent_unwritten_real(
ip->i_df.if_lastex = idx;
xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx + 1, 1);
ip->i_d.di_nextents--;
if (cur == NULL)
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1516,7 +1496,7 @@ xfs_bmap_add_extent_unwritten_real(
*/
xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
LEFT.br_blockcount + new->br_blockcount);
xfs_bmbt_set_startoff(ep,
PREV.br_startoff + new->br_blockcount);
@@ -1571,7 +1551,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK);
xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx, 1, new);
ip->i_df.if_lastex = idx;
ip->i_d.di_nextents++;
if (cur == NULL)
@@ -1609,7 +1589,8 @@ xfs_bmap_add_extent_unwritten_real(
PREV.br_blockcount - new->br_blockcount);
xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
XFS_DATA_FORK);
- xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock,
+ xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
+ new->br_startoff, new->br_startblock,
new->br_blockcount + RIGHT.br_blockcount, newext);
xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
XFS_DATA_FORK);
@@ -1649,7 +1630,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
new, NULL, XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx + 1, 1, new);
ip->i_df.if_lastex = idx + 1;
ip->i_d.di_nextents++;
if (cur == NULL)
@@ -1696,7 +1677,7 @@ xfs_bmap_add_extent_unwritten_real(
r[1].br_state = oldext;
xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
ip->i_df.if_lastex = idx + 1;
ip->i_d.di_nextents += 2;
if (cur == NULL)
@@ -1770,15 +1751,15 @@ xfs_bmap_add_extent_hole_delay(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
int rsvd) /* OK to allocate reserved blocks */
{
- xfs_bmbt_rec_t *base; /* base of extent entry list */
- xfs_bmbt_rec_t *ep; /* extent list entry for idx */
+ xfs_bmbt_rec_t *ep; /* extent record for idx */
#ifdef XFS_BMAP_TRACE
static char fname[] = "xfs_bmap_add_extent_hole_delay";
#endif
+ xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_irec_t left; /* left neighbor extent entry */
xfs_filblks_t newlen=0; /* new indirect size */
xfs_filblks_t oldlen=0; /* old indirect size */
@@ -1799,15 +1780,15 @@ xfs_bmap_add_extent_hole_delay(
((state &= ~MASK(b)), 0))
#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
- base = ip->i_df.if_u1.if_extents;
- ep = &base[idx];
+ ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+ ep = xfs_iext_get_ext(ifp, idx);
state = 0;
ASSERT(ISNULLSTARTBLOCK(new->br_startblock));
/*
* Check and set flags if this segment has a left neighbor
*/
if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(ep - 1, &left);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
}
/*
@@ -1844,23 +1825,24 @@ xfs_bmap_add_extent_hole_delay(
/*
* New allocation is contiguous with delayed allocations
* on the left and on the right.
- * Merge all three into a single extent list entry.
+ * Merge all three into a single extent record.
*/
temp = left.br_blockcount + new->br_blockcount +
right.br_blockcount;
xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1, temp);
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
oldlen = STARTBLOCKVAL(left.br_startblock) +
STARTBLOCKVAL(new->br_startblock) +
STARTBLOCKVAL(right.br_startblock);
newlen = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen));
+ xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
+ NULLSTARTBLOCK((int)newlen));
xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
XFS_DATA_FORK);
xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1,
XFS_DATA_FORK);
- xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK);
+ xfs_iext_remove(ifp, idx, 1);
ip->i_df.if_lastex = idx - 1;
break;
@@ -1873,11 +1855,12 @@ xfs_bmap_add_extent_hole_delay(
temp = left.br_blockcount + new->br_blockcount;
xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1,
XFS_DATA_FORK);
- xfs_bmbt_set_blockcount(ep - 1, temp);
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
oldlen = STARTBLOCKVAL(left.br_startblock) +
STARTBLOCKVAL(new->br_startblock);
newlen = xfs_bmap_worst_indlen(ip, temp);
- xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen));
+ xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
+ NULLSTARTBLOCK((int)newlen));
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
XFS_DATA_FORK);
ip->i_df.if_lastex = idx - 1;
@@ -1909,7 +1892,7 @@ xfs_bmap_add_extent_hole_delay(
oldlen = newlen = 0;
xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
XFS_DATA_FORK);
- xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK);
+ xfs_iext_insert(ifp, idx, 1, new);
ip->i_df.if_lastex = idx;
break;
}
@@ -1940,7 +1923,7 @@ xfs_bmap_add_extent_hole_real(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t *cur, /* if null, not a btree */
- xfs_bmbt_irec_t *new, /* new data to put in extent list */
+ xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
int whichfork) /* data or attr fork */
{
@@ -1970,13 +1953,13 @@ xfs_bmap_add_extent_hole_real(
ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
- ep = &ifp->if_u1.if_extents[idx];
+ ep = xfs_iext_get_ext(ifp, idx);
state = 0;
/*
* Check and set flags if this segment has a left neighbor.
*/
if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
- xfs_bmbt_get_all(ep - 1, &left);
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
}
/*
@@ -2019,18 +2002,18 @@ xfs_bmap_add_extent_hole_real(
/*
* New allocation is contiguous with real allocations on the
* left and on the right.
- * Merge all three into a single extent list entry.
+ * Merge all three into a single extent record.
*/
xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
whichfork);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
left.br_blockcount + new->br_blockcount +
right.br_blockcount);
xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
whichfork);
xfs_bmap_trace_delete(fname, "LC|RC", ip,
idx, 1, whichfork);
- xfs_bmap_delete_exlist(ip, idx, 1, whichfork);
+ xfs_iext_remove(ifp, idx, 1);
ifp->if_lastex = idx - 1;
XFS_IFORK_NEXT_SET(ip, whichfork,
XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
@@ -2062,7 +2045,7 @@ xfs_bmap_add_extent_hole_real(
* Merge the new allocation with the left neighbor.
*/
xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork);
- xfs_bmbt_set_blockcount(ep - 1,
+ xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
left.br_blockcount + new->br_blockcount);
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
ifp->if_lastex = idx - 1;
@@ -2116,7 +2099,7 @@ xfs_bmap_add_extent_hole_real(
*/
xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
whichfork);
- xfs_bmap_insert_exlist(ip, idx, 1, new, whichfork);
+ xfs_iext_insert(ifp, idx, 1, new);
ifp->if_lastex = idx;
XFS_IFORK_NEXT_SET(ip, whichfork,
XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
@@ -2311,25 +2294,15 @@ xfs_bmap_extsize_align(
#define XFS_ALLOC_GAP_UNITS 4
-/*
- * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
- * It figures out where to ask the underlying allocator to put the new extent.
- */
STATIC int
-xfs_bmap_alloc(
+xfs_bmap_adjacent(
xfs_bmalloca_t *ap) /* bmap alloc argument struct */
{
xfs_fsblock_t adjust; /* adjustment to block numbers */
- xfs_alloctype_t atype=0; /* type for allocation routines */
- int error; /* error return value */
xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
xfs_mount_t *mp; /* mount point structure */
int nullfb; /* true if ap->firstblock isn't set */
int rt; /* true if inode is realtime */
- xfs_extlen_t prod = 0; /* product factor for allocators */
- xfs_extlen_t ralen = 0; /* realtime allocation length */
- xfs_extlen_t align; /* minimum allocation alignment */
- xfs_rtblock_t rtx;
#define ISVALID(x,y) \
(rt ? \
@@ -2338,75 +2311,10 @@ xfs_bmap_alloc(
XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
- /*
- * Set up variables.
- */
mp = ap->ip->i_mount;
nullfb = ap->firstblock == NULLFSBLOCK;
rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
- if (rt) {
- align = ap->ip->i_d.di_extsize ?
- ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
- /* Set prod to match the extent size */
- prod = align / mp->m_sb.sb_rextsize;
-
- error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
- align, rt, ap->eof, 0,
- ap->conv, &ap->off, &ap->alen);
- if (error)
- return error;
- ASSERT(ap->alen);
- ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
-
- /*
- * If the offset & length are not perfectly aligned
- * then kill prod, it will just get us in trouble.
- */
- if (do_mod(ap->off, align) || ap->alen % align)
- prod = 1;
- /*
- * Set ralen to be the actual requested length in rtextents.
- */
- ralen = ap->alen / mp->m_sb.sb_rextsize;
- /*
- * If the old value was close enough to MAXEXTLEN that
- * we rounded up to it, cut it back so it's valid again.
- * Note that if it's a really large request (bigger than
- * MAXEXTLEN), we don't hear about that number, and can't
- * adjust the starting point to match it.
- */
- if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
- ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
- /*
- * If it's an allocation to an empty file at offset 0,
- * pick an extent that will space things out in the rt area.
- */
- if (ap->eof && ap->off == 0) {
- error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
- if (error)
- return error;
- ap->rval = rtx * mp->m_sb.sb_rextsize;
- } else
- ap->rval = 0;
- } else {
- align = (ap->userdata && ap->ip->i_d.di_extsize &&
- (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
- ap->ip->i_d.di_extsize : 0;
- if (unlikely(align)) {
- error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
- align, rt,
- ap->eof, 0, ap->conv,
- &ap->off, &ap->alen);
- ASSERT(!error);
- ASSERT(ap->alen);
- }
- if (nullfb)
- ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
- else
- ap->rval = ap->firstblock;
- }
-
/*
* If allocating at eof, and there's a previous real block,
* try to use it's last block as our starting point.
@@ -2531,287 +2439,384 @@ xfs_bmap_alloc(
else if (gotbno != NULLFSBLOCK)
ap->rval = gotbno;
}
+#undef ISVALID
+ return 0;
+}
+
+STATIC int
+xfs_bmap_rtalloc(
+ xfs_bmalloca_t *ap) /* bmap alloc argument struct */
+{
+ xfs_alloctype_t atype = 0; /* type for allocation routines */
+ int error; /* error return value */
+ xfs_mount_t *mp; /* mount point structure */
+ xfs_extlen_t prod = 0; /* product factor for allocators */
+ xfs_extlen_t ralen = 0; /* realtime allocation length */
+ xfs_extlen_t align; /* minimum allocation alignment */
+ xfs_rtblock_t rtx; /* realtime extent number */
+ xfs_rtblock_t rtb;
+
+ mp = ap->ip->i_mount;
+ align = ap->ip->i_d.di_extsize ?
+ ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
+ prod = align / mp->m_sb.sb_rextsize;
+ error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
+ align, 1, ap->eof, 0,
+ ap->conv, &ap->off, &ap->alen);
+ if (error)
+ return error;
+ ASSERT(ap->alen);
+ ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
+
+ /*
+ * If the offset & length are not perfectly aligned
+ * then kill prod, it will just get us in trouble.
+ */
+ if (do_mod(ap->off, align) || ap->alen % align)
+ prod = 1;
+ /*
+ * Set ralen to be the actual requested length in rtextents.
+ */
+ ralen = ap->alen / mp->m_sb.sb_rextsize;
+ /*
+ * If the old value was close enough to MAXEXTLEN that
+ * we rounded up to it, cut it back so it's valid again.
+ * Note that if it's a really large request (bigger than
+ * MAXEXTLEN), we don't hear about that number, and can't
+ * adjust the starting point to match it.
+ */
+ if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
+ ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
+ /*
+ * If it's an allocation to an empty file at offset 0,
+ * pick an extent that will space things out in the rt area.
+ */
+ if (ap->eof && ap->off == 0) {
+ error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
+ if (error)
+ return error;
+ ap->rval = rtx * mp->m_sb.sb_rextsize;
+ } else {
+ ap->rval = 0;
+ }
+
+ xfs_bmap_adjacent(ap);
+
+ /*
+ * Realtime allocation, done through xfs_rtallocate_extent.
+ */
+ atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO;
+ do_div(ap->rval, mp->m_sb.sb_rextsize);
+ rtb = ap->rval;
+ ap->alen = ralen;
+ if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen,
+ &ralen, atype, ap->wasdel, prod, &rtb)))
+ return error;
+ if (rtb == NULLFSBLOCK && prod > 1 &&
+ (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1,
+ ap->alen, &ralen, atype,
+ ap->wasdel, 1, &rtb)))
+ return error;
+ ap->rval = rtb;
+ if (ap->rval != NULLFSBLOCK) {
+ ap->rval *= mp->m_sb.sb_rextsize;
+ ralen *= mp->m_sb.sb_rextsize;
+ ap->alen = ralen;
+ ap->ip->i_d.di_nblocks += ralen;
+ xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
+ if (ap->wasdel)
+ ap->ip->i_delayed_blks -= ralen;
+ /*
+ * Adjust the disk quota also. This was reserved
+ * earlier.
+ */
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
+ ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
+ XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
+ } else {
+ ap->alen = 0;
+ }
+ return 0;
+}
+
+STATIC int
+xfs_bmap_btalloc(
+ xfs_bmalloca_t *ap) /* bmap alloc argument struct */
+{
+ xfs_mount_t *mp; /* mount point structure */
+ xfs_alloctype_t atype = 0; /* type for allocation routines */
+ xfs_extlen_t align; /* minimum allocation alignment */
+ xfs_agnumber_t ag;
+ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
+ xfs_agnumber_t startag;
+ xfs_alloc_arg_t args;
+ xfs_extlen_t blen;
+ xfs_extlen_t delta;
+ xfs_extlen_t longest;
+ xfs_extlen_t need;
+ xfs_extlen_t nextminlen = 0;
+ xfs_perag_t *pag;
+ int nullfb; /* true if ap->firstblock isn't set */
+ int isaligned;
+ int notinit;
+ int tryagain;
+ int error;
+
+ mp = ap->ip->i_mount;
+ align = (ap->userdata && ap->ip->i_d.di_extsize &&
+ (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
+ ap->ip->i_d.di_extsize : 0;
+ if (unlikely(align)) {
+ error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
+ align, 0, ap->eof, 0, ap->conv,
+ &ap->off, &ap->alen);
+ ASSERT(!error);
+ ASSERT(ap->alen);
+ }
+ nullfb = ap->firstblock == NULLFSBLOCK;
+ fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
+ if (nullfb)
+ ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
+ else
+ ap->rval = ap->firstblock;
+
+ xfs_bmap_adjacent(ap);
+
/*
* If allowed, use ap->rval; otherwise must use firstblock since
* it's in the right allocation group.
*/
- if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
+ if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
;
else
ap->rval = ap->firstblock;
/*
- * Realtime allocation, done through xfs_rtallocate_extent.
+ * Normal allocation, done through xfs_alloc_vextent.
*/
- if (rt) {
-#ifndef __KERNEL__
- ASSERT(0);
-#else
- xfs_rtblock_t rtb;
-
- atype = ap->rval == 0 ?
- XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO;
- do_div(ap->rval, mp->m_sb.sb_rextsize);
- rtb = ap->rval;
- ap->alen = ralen;
- if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen,
- &ralen, atype, ap->wasdel, prod, &rtb)))
- return error;
- if (rtb == NULLFSBLOCK && prod > 1 &&
- (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1,
- ap->alen, &ralen, atype,
- ap->wasdel, 1, &rtb)))
- return error;
- ap->rval = rtb;
- if (ap->rval != NULLFSBLOCK) {
- ap->rval *= mp->m_sb.sb_rextsize;
- ralen *= mp->m_sb.sb_rextsize;
- ap->alen = ralen;
- ap->ip->i_d.di_nblocks += ralen;
- xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
- if (ap->wasdel)
- ap->ip->i_delayed_blks -= ralen;
+ tryagain = isaligned = 0;
+ args.tp = ap->tp;
+ args.mp = mp;
+ args.fsbno = ap->rval;
+ args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
+ blen = 0;
+ if (nullfb) {
+ args.type = XFS_ALLOCTYPE_START_BNO;
+ args.total = ap->total;
+ /*
+ * Find the longest available space.
+ * We're going to try for the whole allocation at once.
+ */
+ startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
+ notinit = 0;
+ down_read(&mp->m_peraglock);
+ while (blen < ap->alen) {