xfs
[Top] [All Lists]

[PATCH v2 08/17] xfs: create helper to manage record overlap for sparse

To: xfs@xxxxxxxxxxx
Subject: [PATCH v2 08/17] xfs: create helper to manage record overlap for sparse inode chunks
From: Brian Foster <bfoster@xxxxxxxxxx>
Date: Mon, 3 Nov 2014 11:12:17 -0500
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1415031146-9107-1-git-send-email-bfoster@xxxxxxxxxx>
References: <1415031146-9107-1-git-send-email-bfoster@xxxxxxxxxx>
Create xfs_inobt_rec_exists() to receive the parameters of a new sparse
inode chunk allocation and identify whether a record exists that is
capable of tracking this sparse chunk.

Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_ialloc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index b53fb5d..6879213 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -359,6 +359,67 @@ xfs_ialloc_inode_init(
 }
 
 /*
+ * Determine whether part of a sparse inode chunk that has just been allocated
+ * is covered by an existing inobt record.
+ */
+STATIC int
+xfs_inobt_rec_exists(
+       struct xfs_mount                *mp,
+       struct xfs_trans                *tp,
+       struct xfs_buf                  *agbp,
+       xfs_agino_t                     newino,
+       xfs_agino_t                     count,
+       xfs_btnum_t                     btnum,
+       struct xfs_inobt_rec_incore     *orec)
+{
+       struct xfs_btree_cur            *cur;
+       struct xfs_agi                  *agi = XFS_BUF_TO_AGI(agbp);
+       xfs_agnumber_t                  agno = be32_to_cpu(agi->agi_seqno);
+       int                             error;
+       int                             i;
+       struct xfs_inobt_rec_incore     rec;
+
+       orec->ir_startino = NULLAGINO;
+
+       cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
+
+       /*
+        * Find the first record prior to the inode that has just been
+        * allocated.
+        */
+       error = xfs_inobt_lookup(cur, newino, XFS_LOOKUP_LE, &i);
+       if (error)
+               goto error;
+       if (i == 0)
+               goto out;
+
+       error = xfs_inobt_get_rec(cur, &rec, &i);
+       if (error)
+               goto error;
+       XFS_WANT_CORRUPTED_GOTO(i == 1, error);
+
+       /*
+        * Check whether the record covers a range that includes the new inodes.
+        * We can't allocate a sparse chunk that spans multiple records, so we
+        * only need to check the ino range.
+        */
+       if (rec.ir_startino + XFS_INODES_PER_CHUNK <= newino)
+               goto out;
+
+       ASSERT(rec.ir_startino <= newino &&
+              rec.ir_startino + XFS_INODES_PER_CHUNK > newino);
+
+       *orec = rec;    /* struct copy */
+
+out:
+       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.
  * Return 0 for success, else error code.
  */
-- 
1.8.3.1

<Prev in Thread] Current Thread [Next in Thread>