Skip to content

Commit 4148c34

Browse files
Brian Fosterdchinner
authored andcommitted
xfs: helper to convert holemask to inode alloc. bitmap
The inobt record holemask field is a condensed data type designed to fit into the existing on-disk record and is zero based (allocated regions are set to 0, sparse regions are set to 1) to provide backwards compatibility. This makes the type somewhat complex for use in higher level inode manipulations such as individual inode allocation, etc. Rather than foist the complexity of dealing with this field to every bit of logic that requires inode granular information, create a helper to convert the holemask to an inode allocation bitmap. The inode allocation bitmap is inode granularity similar to the inobt record free mask and indicates which inodes of the chunk are physically allocated on disk, irrespective of whether the inode is considered allocated or free by the filesystem. Signed-off-by: Brian Foster <[email protected]> Reviewed-by: Dave Chinner <[email protected]> Signed-off-by: Dave Chinner <[email protected]>
1 parent 7f43c90 commit 4148c34

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,54 @@ xfs_inobt_maxrecs(
427427
return blocklen / sizeof(xfs_inobt_rec_t);
428428
return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t));
429429
}
430+
431+
/*
432+
* Convert the inode record holemask to an inode allocation bitmap. The inode
433+
* allocation bitmap is inode granularity and specifies whether an inode is
434+
* physically allocated on disk (not whether the inode is considered allocated
435+
* or free by the fs).
436+
*
437+
* A bit value of 1 means the inode is allocated, a value of 0 means it is free.
438+
*/
439+
uint64_t
440+
xfs_inobt_irec_to_allocmask(
441+
struct xfs_inobt_rec_incore *rec)
442+
{
443+
uint64_t bitmap = 0;
444+
uint64_t inodespbit;
445+
int nextbit;
446+
uint allocbitmap;
447+
448+
/*
449+
* The holemask has 16-bits for a 64 inode record. Therefore each
450+
* holemask bit represents multiple inodes. Create a mask of bits to set
451+
* in the allocmask for each holemask bit.
452+
*/
453+
inodespbit = (1 << XFS_INODES_PER_HOLEMASK_BIT) - 1;
454+
455+
/*
456+
* Allocated inodes are represented by 0 bits in holemask. Invert the 0
457+
* bits to 1 and convert to a uint so we can use xfs_next_bit(). Mask
458+
* anything beyond the 16 holemask bits since this casts to a larger
459+
* type.
460+
*/
461+
allocbitmap = ~rec->ir_holemask & ((1 << XFS_INOBT_HOLEMASK_BITS) - 1);
462+
463+
/*
464+
* allocbitmap is the inverted holemask so every set bit represents
465+
* allocated inodes. To expand from 16-bit holemask granularity to
466+
* 64-bit (e.g., bit-per-inode), set inodespbit bits in the target
467+
* bitmap for every holemask bit.
468+
*/
469+
nextbit = xfs_next_bit(&allocbitmap, 1, 0);
470+
while (nextbit != -1) {
471+
ASSERT(nextbit < (sizeof(rec->ir_holemask) * NBBY));
472+
473+
bitmap |= (inodespbit <<
474+
(nextbit * XFS_INODES_PER_HOLEMASK_BIT));
475+
476+
nextbit = xfs_next_bit(&allocbitmap, 1, nextbit + 1);
477+
}
478+
479+
return bitmap;
480+
}

fs/xfs/libxfs/xfs_ialloc_btree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,7 @@ extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *,
6262
xfs_btnum_t);
6363
extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);
6464

65+
/* ir_holemask to inode allocation bitmap conversion */
66+
uint64_t xfs_inobt_irec_to_allocmask(struct xfs_inobt_rec_incore *);
67+
6568
#endif /* __XFS_IALLOC_BTREE_H__ */

0 commit comments

Comments
 (0)