xfs: split xfs_inobt_insert_sprec
authorChristoph Hellwig <hch@lst.de>
Thu, 22 Feb 2024 20:40:48 +0000 (12:40 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 22 Feb 2024 20:40:48 +0000 (12:40 -0800)
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>
fs/xfs/libxfs/xfs_ialloc.c

index 52b82cd7e6c9cabf9ce9ae7db334cff917e8152a..17a53f635c9fb31b06dca6caf0db60abccc10c75 100644 (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,48 +577,45 @@ 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;
-               if (XFS_IS_CORRUPT(mp, i != 1)) {
-                       xfs_btree_mark_sick(cur);
-                       error = -EFSCORRUPTED;
-                       goto error;
-               }
-               if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
-                       xfs_btree_mark_sick(cur);
-                       error = -EFSCORRUPTED;
-                       goto error;
-               }
+       error = xfs_inobt_get_rec(cur, &rec, &i);
+       if (error)
+               goto error;
+       if (XFS_IS_CORRUPT(mp, i != 1)) {
+               xfs_btree_mark_sick(cur);
+               error = -EFSCORRUPTED;
+               goto error;
+       }
+       if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
+               xfs_btree_mark_sick(cur);
+               error = -EFSCORRUPTED;
+               goto error;
+       }
 
-               /*
-                * This should never fail. If we have coexisting records that
-                * cannot merge, something is seriously wrong.
-                */
-               if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
-                       xfs_btree_mark_sick(cur);
-                       error = -EFSCORRUPTED;
-                       goto error;
-               }
+       /*
+        * This should never fail. If we have coexisting records that
+        * cannot merge, something is seriously wrong.
+        */
+       if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
+               xfs_btree_mark_sick(cur);
+               error = -EFSCORRUPTED;
+               goto error;
+       }
 
-               trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
-                                        rec.ir_holemask, nrec->ir_startino,
-                                        nrec->ir_holemask);
+       trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
+                                rec.ir_holemask, nrec->ir_startino,
+                                nrec->ir_holemask);
 
-               /* merge to nrec to output the updated record */
-               __xfs_inobt_rec_merge(nrec, &rec);
+       /* merge to nrec to output the updated record */
+       __xfs_inobt_rec_merge(nrec, &rec);
 
-               trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
-                                         nrec->ir_holemask);
+       trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
+                                 nrec->ir_holemask);
 
-               error = xfs_inobt_rec_check_count(mp, nrec);
-               if (error)
-                       goto error;
-       }
+       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;
                }