Skip to content

Commit 8541a7d

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
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>
1 parent c81a01a commit 8541a7d

1 file changed

Lines changed: 96 additions & 52 deletions

File tree

fs/xfs/libxfs/xfs_ialloc.c

Lines changed: 96 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -529,16 +529,14 @@ __xfs_inobt_rec_merge(
529529
}
530530

531531
/*
532-
* Insert a new sparse inode chunk into the associated inode btree. The inode
533-
* record for the sparse chunk is pre-aligned to a startino that should match
534-
* any pre-existing sparse inode record in the tree. This allows sparse chunks
535-
* to fill over time.
532+
* Insert a new sparse inode chunk into the associated inode allocation btree.
533+
* The inode record for the sparse chunk is pre-aligned to a startino that
534+
* should match any pre-existing sparse inode record in the tree. This allows
535+
* sparse chunks to fill over time.
536536
*
537-
* This function supports two modes of handling preexisting records depending on
538-
* the merge flag. If merge is true, the provided record is merged with the
537+
* If no preexisting record exists, the provided record is inserted.
538+
* If there is a preexisting record, the provided record is merged with the
539539
* existing record and updated in place. The merged record is returned in nrec.
540-
* If merge is false, an existing record is replaced with the provided record.
541-
* If no preexisting record exists, the provided record is always inserted.
542540
*
543541
* It is considered corruption if a merge is requested and not possible. Given
544542
* the sparse inode alignment constraints, this should never happen.
@@ -548,17 +546,15 @@ xfs_inobt_insert_sprec(
548546
struct xfs_perag *pag,
549547
struct xfs_trans *tp,
550548
struct xfs_buf *agbp,
551-
int btnum,
552-
struct xfs_inobt_rec_incore *nrec, /* in/out: new/merged rec. */
553-
bool merge) /* merge or replace */
549+
struct xfs_inobt_rec_incore *nrec) /* in/out: new/merged rec. */
554550
{
555551
struct xfs_mount *mp = pag->pag_mount;
556552
struct xfs_btree_cur *cur;
557553
int error;
558554
int i;
559555
struct xfs_inobt_rec_incore rec;
560556

561-
cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
557+
cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
562558

563559
/* the new record is pre-aligned so we know where to look */
564560
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@@ -581,48 +577,45 @@ xfs_inobt_insert_sprec(
581577
}
582578

583579
/*
584-
* A record exists at this startino. Merge or replace the record
585-
* depending on what we've been asked to do.
580+
* A record exists at this startino. Merge the records.
586581
*/
587-
if (merge) {
588-
error = xfs_inobt_get_rec(cur, &rec, &i);
589-
if (error)
590-
goto error;
591-
if (XFS_IS_CORRUPT(mp, i != 1)) {
592-
xfs_btree_mark_sick(cur);
593-
error = -EFSCORRUPTED;
594-
goto error;
595-
}
596-
if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
597-
xfs_btree_mark_sick(cur);
598-
error = -EFSCORRUPTED;
599-
goto error;
600-
}
582+
error = xfs_inobt_get_rec(cur, &rec, &i);
583+
if (error)
584+
goto error;
585+
if (XFS_IS_CORRUPT(mp, i != 1)) {
586+
xfs_btree_mark_sick(cur);
587+
error = -EFSCORRUPTED;
588+
goto error;
589+
}
590+
if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
591+
xfs_btree_mark_sick(cur);
592+
error = -EFSCORRUPTED;
593+
goto error;
594+
}
601595

602-
/*
603-
* This should never fail. If we have coexisting records that
604-
* cannot merge, something is seriously wrong.
605-
*/
606-
if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
607-
xfs_btree_mark_sick(cur);
608-
error = -EFSCORRUPTED;
609-
goto error;
610-
}
596+
/*
597+
* This should never fail. If we have coexisting records that
598+
* cannot merge, something is seriously wrong.
599+
*/
600+
if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
601+
xfs_btree_mark_sick(cur);
602+
error = -EFSCORRUPTED;
603+
goto error;
604+
}
611605

612-
trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
613-
rec.ir_holemask, nrec->ir_startino,
614-
nrec->ir_holemask);
606+
trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
607+
rec.ir_holemask, nrec->ir_startino,
608+
nrec->ir_holemask);
615609

616-
/* merge to nrec to output the updated record */
617-
__xfs_inobt_rec_merge(nrec, &rec);
610+
/* merge to nrec to output the updated record */
611+
__xfs_inobt_rec_merge(nrec, &rec);
618612

619-
trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
620-
nrec->ir_holemask);
613+
trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
614+
nrec->ir_holemask);
621615

622-
error = xfs_inobt_rec_check_count(mp, nrec);
623-
if (error)
624-
goto error;
625-
}
616+
error = xfs_inobt_rec_check_count(mp, nrec);
617+
if (error)
618+
goto error;
626619

627620
error = xfs_inobt_update(cur, nrec);
628621
if (error)
@@ -636,6 +629,59 @@ xfs_inobt_insert_sprec(
636629
return error;
637630
}
638631

632+
/*
633+
* Insert a new sparse inode chunk into the free inode btree. The inode
634+
* record for the sparse chunk is pre-aligned to a startino that should match
635+
* any pre-existing sparse inode record in the tree. This allows sparse chunks
636+
* to fill over time.
637+
*
638+
* The new record is always inserted, overwriting a pre-existing record if
639+
* there is one.
640+
*/
641+
STATIC int
642+
xfs_finobt_insert_sprec(
643+
struct xfs_perag *pag,
644+
struct xfs_trans *tp,
645+
struct xfs_buf *agbp,
646+
struct xfs_inobt_rec_incore *nrec) /* in/out: new rec. */
647+
{
648+
struct xfs_mount *mp = pag->pag_mount;
649+
struct xfs_btree_cur *cur;
650+
int error;
651+
int i;
652+
653+
cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
654+
655+
/* the new record is pre-aligned so we know where to look */
656+
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
657+
if (error)
658+
goto error;
659+
/* if nothing there, insert a new record and return */
660+
if (i == 0) {
661+
error = xfs_inobt_insert_rec(cur, nrec->ir_holemask,
662+
nrec->ir_count, nrec->ir_freecount,
663+
nrec->ir_free, &i);
664+
if (error)
665+
goto error;
666+
if (XFS_IS_CORRUPT(mp, i != 1)) {
667+
xfs_btree_mark_sick(cur);
668+
error = -EFSCORRUPTED;
669+
goto error;
670+
}
671+
} else {
672+
error = xfs_inobt_update(cur, nrec);
673+
if (error)
674+
goto error;
675+
}
676+
677+
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
678+
return 0;
679+
error:
680+
xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
681+
return error;
682+
}
683+
684+
639685
/*
640686
* Allocate new inodes in the allocation group specified by agbp. Returns 0 if
641687
* inodes were allocated in this AG; -EAGAIN if there was no space in this AG so
@@ -862,8 +908,7 @@ xfs_ialloc_ag_alloc(
862908
* if necessary. If a merge does occur, rec is updated to the
863909
* merged record.
864910
*/
865-
error = xfs_inobt_insert_sprec(pag, tp, agbp,
866-
XFS_BTNUM_INO, &rec, true);
911+
error = xfs_inobt_insert_sprec(pag, tp, agbp, &rec);
867912
if (error == -EFSCORRUPTED) {
868913
xfs_alert(args.mp,
869914
"invalid sparse inode record: ino 0x%llx holemask 0x%x count %u",
@@ -887,8 +932,7 @@ xfs_ialloc_ag_alloc(
887932
* existing record with this one.
888933
*/
889934
if (xfs_has_finobt(args.mp)) {
890-
error = xfs_inobt_insert_sprec(pag, tp, agbp,
891-
XFS_BTNUM_FINO, &rec, false);
935+
error = xfs_finobt_insert_sprec(pag, tp, agbp, &rec);
892936
if (error)
893937
return error;
894938
}

0 commit comments

Comments
 (0)