xfs: filter out sparse regions from individual inode allocation
authorBrian Foster <bfoster@redhat.com>
Thu, 28 May 2015 23:20:10 +0000 (09:20 +1000)
committerDave Chinner <david@fromorbit.com>
Thu, 28 May 2015 23:20:10 +0000 (09:20 +1000)
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.

Update 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@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/libxfs/xfs_ialloc.c

index 9a18c0b..6451a80 100644 (file)
@@ -1076,13 +1076,24 @@ xfs_ialloc_get_rec(
 }
 
 /*
- * Return the offset of the first free inode in the record.
+ * 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)
 {
-       return xfs_lowbit64(rec->ir_free);
+       xfs_inofree_t                   realfree;
+
+       /* if there are no holes, return the first available offset */
+       if (!xfs_inobt_issparse(rec->ir_holemask))
+               return xfs_lowbit64(rec->ir_free);
+
+       realfree = xfs_inobt_irec_to_allocmask(rec);
+       realfree &= rec->ir_free;
+
+       return xfs_lowbit64(realfree);
 }
 
 /*