Commit 8541a7d9 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent c81a01a7
Loading
Loading
Loading
Loading
+96 −52
Original line number Diff line number Diff line
@@ -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 @@ xfs_inobt_insert_sprec(
	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 @@ xfs_ialloc_ag_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 @@ xfs_ialloc_ag_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;
		}