diff options
author | Brian Foster <bfoster@redhat.com> | 2015-05-29 02:20:10 +0300 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-05-29 02:20:10 +0300 |
commit | 26dd5217dee0ecfb95f8015ed8e9deebf8257608 (patch) | |
tree | 4fb075d2c0f6486bacfc253476bdec8eceb6430b /fs/xfs/libxfs/xfs_ialloc.c | |
parent | 1cdadee11f8d44b16f8110cf01498bd7c38474d8 (diff) | |
download | linux-26dd5217dee0ecfb95f8015ed8e9deebf8257608.tar.xz |
xfs: filter out sparse regions from individual inode allocation
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>
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 9a18c0b5beb9..6451a8009874 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -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); } /* |