xfs: split xfs_inobt_insert_sprec

Split the finobt version that never merges and uses a different cursor
out of xfs_inobt_insert_sprec to prepare for removing xfs_btnum_t.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
Christoph Hellwig 2024-02-22 12:40:48 -08:00 committed by Darrick J. Wong
parent c81a01a74a
commit 8541a7d9da

View File

@ -529,16 +529,14 @@ __xfs_inobt_rec_merge(
}
/*
* Insert a new sparse inode chunk into the associated inode btree. The inode
* record for the sparse chunk is pre-aligned to a startino that should match
* any pre-existing sparse inode record in the tree. This allows sparse chunks
* to fill over time.
* Insert a new sparse inode chunk into the associated inode allocation btree.
* The inode record for the sparse chunk is pre-aligned to a startino that
* should match any pre-existing sparse inode record in the tree. This allows
* sparse chunks to fill over time.
*
* This function supports two modes of handling preexisting records depending on
* the merge flag. If merge is true, the provided record is merged with the
* If no preexisting record exists, the provided record is inserted.
* If there is a preexisting record, the provided record is merged with the
* existing record and updated in place. The merged record is returned in nrec.
* If merge is false, an existing record is replaced with the provided record.
* If no preexisting record exists, the provided record is always inserted.
*
* It is considered corruption if a merge is requested and not possible. Given
* the sparse inode alignment constraints, this should never happen.
@ -548,9 +546,7 @@ xfs_inobt_insert_sprec(
struct xfs_perag *pag,
struct xfs_trans *tp,
struct xfs_buf *agbp,
int btnum,
struct xfs_inobt_rec_incore *nrec, /* in/out: new/merged rec. */
bool merge) /* merge or replace */
struct xfs_inobt_rec_incore *nrec) /* in/out: new/merged rec. */
{
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
@ -558,7 +554,7 @@ xfs_inobt_insert_sprec(
int i;
struct xfs_inobt_rec_incore rec;
cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
/* the new record is pre-aligned so we know where to look */
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@ -581,10 +577,8 @@ xfs_inobt_insert_sprec(
}
/*
* A record exists at this startino. Merge or replace the record
* depending on what we've been asked to do.
* A record exists at this startino. Merge the records.
*/
if (merge) {
error = xfs_inobt_get_rec(cur, &rec, &i);
if (error)
goto error;
@ -622,7 +616,6 @@ xfs_inobt_insert_sprec(
error = xfs_inobt_rec_check_count(mp, nrec);
if (error)
goto error;
}
error = xfs_inobt_update(cur, nrec);
if (error)
@ -636,6 +629,59 @@ error:
return error;
}
/*
* Insert a new sparse inode chunk into the free inode btree. The inode
* record for the sparse chunk is pre-aligned to a startino that should match
* any pre-existing sparse inode record in the tree. This allows sparse chunks
* to fill over time.
*
* The new record is always inserted, overwriting a pre-existing record if
* there is one.
*/
STATIC int
xfs_finobt_insert_sprec(
struct xfs_perag *pag,
struct xfs_trans *tp,
struct xfs_buf *agbp,
struct xfs_inobt_rec_incore *nrec) /* in/out: new rec. */
{
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
int error;
int i;
cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
/* the new record is pre-aligned so we know where to look */
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
if (error)
goto error;
/* if nothing there, insert a new record and return */
if (i == 0) {
error = xfs_inobt_insert_rec(cur, nrec->ir_holemask,
nrec->ir_count, nrec->ir_freecount,
nrec->ir_free, &i);
if (error)
goto error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
} else {
error = xfs_inobt_update(cur, nrec);
if (error)
goto error;
}
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
return 0;
error:
xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
return error;
}
/*
* Allocate new inodes in the allocation group specified by agbp. Returns 0 if
* inodes were allocated in this AG; -EAGAIN if there was no space in this AG so
@ -862,8 +908,7 @@ sparse_alloc:
* if necessary. If a merge does occur, rec is updated to the
* merged record.
*/
error = xfs_inobt_insert_sprec(pag, tp, agbp,
XFS_BTNUM_INO, &rec, true);
error = xfs_inobt_insert_sprec(pag, tp, agbp, &rec);
if (error == -EFSCORRUPTED) {
xfs_alert(args.mp,
"invalid sparse inode record: ino 0x%llx holemask 0x%x count %u",
@ -887,8 +932,7 @@ sparse_alloc:
* existing record with this one.
*/
if (xfs_has_finobt(args.mp)) {
error = xfs_inobt_insert_sprec(pag, tp, agbp,
XFS_BTNUM_FINO, &rec, false);
error = xfs_finobt_insert_sprec(pag, tp, agbp, &rec);
if (error)
return error;
}