xfs
[Top] [All Lists]

[PATCH v2 11/17] xfs: filter out sparse regions from individual inode al

To: xfs@xxxxxxxxxxx
Subject: [PATCH v2 11/17] xfs: filter out sparse regions from individual inode allocation
From: Brian Foster <bfoster@xxxxxxxxxx>
Date: Mon, 3 Nov 2014 11:12:20 -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>
Inode allocation from an existing record with free inodes traditionally
selects the first inode available according to the ir_free mask. With
sparse inode chunks, the ir_free mask could refer to an unallocated
region. We must mask the unallocated regions out of ir_free before using
it to select a free inode in the chunk.

Create the xfs_inobt_first_free_inode() helper to find the first free
inode available of the allocated regions of the inode chunk.

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

diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 88ca72f..2bc998d 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -978,6 +978,30 @@ xfs_inobt_ialloc_bitmap(
 }
 
 /*
+ * Return the offset of the first free inode in the record. If the inode chunk
+ * is sparsely allocated, we convert the record holemask to inode granularity
+ * and mask off the unallocated regions from the inode free mask.
+ */
+STATIC int
+xfs_inobt_first_free_inode(
+       struct xfs_inobt_rec_incore     *rec)
+{
+       xfs_inofree_t   realfree;
+       DECLARE_BITMAP(alloc, 64);
+
+       /* if there are no holes, return the first available offset */
+       if (!xfs_inobt_issparse(rec->ir_holemask))
+               return xfs_lowbit64(rec->ir_free);
+
+       xfs_inobt_ialloc_bitmap(alloc, rec);
+       realfree = bitmap_to_u64(alloc, 64);
+
+       realfree &= rec->ir_free;
+
+       return xfs_lowbit64(realfree);
+}
+
+/*
  * Allocate an inode using the inobt-only algorithm.
  */
 STATIC int
@@ -1207,7 +1231,7 @@ newino:
        }
 
 alloc_inode:
-       offset = xfs_lowbit64(rec.ir_free);
+       offset = xfs_inobt_first_free_inode(&rec);
        ASSERT(offset >= 0);
        ASSERT(offset < XFS_INODES_PER_CHUNK);
        ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
@@ -1460,7 +1484,7 @@ xfs_dialloc_ag(
        if (error)
                goto error_cur;
 
-       offset = xfs_lowbit64(rec.ir_free);
+       offset = xfs_inobt_first_free_inode(&rec);
        ASSERT(offset >= 0);
        ASSERT(offset < XFS_INODES_PER_CHUNK);
        ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
-- 
1.8.3.1

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