Commit 6ece924b authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: create separate structures and code for u32 bitmaps

Create a version of the xbitmap that handles 32-bit integer intervals
and adapt the xfs_agblock_t bitmap to use it.  This reduces the size of
the interval tree nodes from 48 to 36 bytes and enables us to use a more
efficient slab (:0000040 instead of :0000048) which allows us to pack
more nodes into a single slab page (102 vs 85).

As a side effect, the users of these bitmaps no longer have to convert
between u32 and u64 quantities just to use the bitmap; and the hairy
overflow checking code in xagb_bitmap_test goes away.

Later in this patchset we're going to add bitmaps for xfs_agino_t,
xfs_rgblock_t, and xfs_dablk_t, so the increase in code size (5622 vs.
9959 bytes) seems worth it.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent e069d549
...@@ -494,12 +494,11 @@ xrep_agfl_walk_rmap( ...@@ -494,12 +494,11 @@ xrep_agfl_walk_rmap(
/* Strike out the blocks that are cross-linked according to the rmapbt. */ /* Strike out the blocks that are cross-linked according to the rmapbt. */
STATIC int STATIC int
xrep_agfl_check_extent( xrep_agfl_check_extent(
uint64_t start, uint32_t agbno,
uint64_t len, uint32_t len,
void *priv) void *priv)
{ {
struct xrep_agfl *ra = priv; struct xrep_agfl *ra = priv;
xfs_agblock_t agbno = start;
xfs_agblock_t last_agbno = agbno + len - 1; xfs_agblock_t last_agbno = agbno + len - 1;
int error; int error;
...@@ -647,8 +646,8 @@ struct xrep_agfl_fill { ...@@ -647,8 +646,8 @@ struct xrep_agfl_fill {
/* Fill the AGFL with whatever blocks are in this extent. */ /* Fill the AGFL with whatever blocks are in this extent. */
static int static int
xrep_agfl_fill( xrep_agfl_fill(
uint64_t start, uint32_t start,
uint64_t len, uint32_t len,
void *priv) void *priv)
{ {
struct xrep_agfl_fill *af = priv; struct xrep_agfl_fill *af = priv;
......
This diff is collapsed.
...@@ -6,17 +6,47 @@ ...@@ -6,17 +6,47 @@
#ifndef __XFS_SCRUB_BITMAP_H__ #ifndef __XFS_SCRUB_BITMAP_H__
#define __XFS_SCRUB_BITMAP_H__ #define __XFS_SCRUB_BITMAP_H__
struct xbitmap { /* u64 bitmap */
struct xbitmap64 {
struct rb_root_cached xb_root;
};
void xbitmap64_init(struct xbitmap64 *bitmap);
void xbitmap64_destroy(struct xbitmap64 *bitmap);
int xbitmap64_clear(struct xbitmap64 *bitmap, uint64_t start, uint64_t len);
int xbitmap64_set(struct xbitmap64 *bitmap, uint64_t start, uint64_t len);
int xbitmap64_disunion(struct xbitmap64 *bitmap, struct xbitmap64 *sub);
uint64_t xbitmap64_hweight(struct xbitmap64 *bitmap);
/*
* Return codes for the bitmap iterator functions are 0 to continue iterating,
* and non-zero to stop iterating. Any non-zero value will be passed up to the
* iteration caller. The special value -ECANCELED can be used to stop
* iteration, because neither bitmap iterator ever generates that error code on
* its own. Callers must not modify the bitmap while walking it.
*/
typedef int (*xbitmap64_walk_fn)(uint64_t start, uint64_t len, void *priv);
int xbitmap64_walk(struct xbitmap64 *bitmap, xbitmap64_walk_fn fn,
void *priv);
bool xbitmap64_empty(struct xbitmap64 *bitmap);
bool xbitmap64_test(struct xbitmap64 *bitmap, uint64_t start, uint64_t *len);
/* u32 bitmap */
struct xbitmap32 {
struct rb_root_cached xb_root; struct rb_root_cached xb_root;
}; };
void xbitmap_init(struct xbitmap *bitmap); void xbitmap32_init(struct xbitmap32 *bitmap);
void xbitmap_destroy(struct xbitmap *bitmap); void xbitmap32_destroy(struct xbitmap32 *bitmap);
int xbitmap_clear(struct xbitmap *bitmap, uint64_t start, uint64_t len); int xbitmap32_clear(struct xbitmap32 *bitmap, uint32_t start, uint32_t len);
int xbitmap_set(struct xbitmap *bitmap, uint64_t start, uint64_t len); int xbitmap32_set(struct xbitmap32 *bitmap, uint32_t start, uint32_t len);
int xbitmap_disunion(struct xbitmap *bitmap, struct xbitmap *sub); int xbitmap32_disunion(struct xbitmap32 *bitmap, struct xbitmap32 *sub);
uint64_t xbitmap_hweight(struct xbitmap *bitmap); uint32_t xbitmap32_hweight(struct xbitmap32 *bitmap);
/* /*
* Return codes for the bitmap iterator functions are 0 to continue iterating, * Return codes for the bitmap iterator functions are 0 to continue iterating,
...@@ -25,79 +55,65 @@ uint64_t xbitmap_hweight(struct xbitmap *bitmap); ...@@ -25,79 +55,65 @@ uint64_t xbitmap_hweight(struct xbitmap *bitmap);
* iteration, because neither bitmap iterator ever generates that error code on * iteration, because neither bitmap iterator ever generates that error code on
* its own. Callers must not modify the bitmap while walking it. * its own. Callers must not modify the bitmap while walking it.
*/ */
typedef int (*xbitmap_walk_fn)(uint64_t start, uint64_t len, void *priv); typedef int (*xbitmap32_walk_fn)(uint32_t start, uint32_t len, void *priv);
int xbitmap_walk(struct xbitmap *bitmap, xbitmap_walk_fn fn, int xbitmap32_walk(struct xbitmap32 *bitmap, xbitmap32_walk_fn fn,
void *priv); void *priv);
bool xbitmap_empty(struct xbitmap *bitmap); bool xbitmap32_empty(struct xbitmap32 *bitmap);
bool xbitmap_test(struct xbitmap *bitmap, uint64_t start, uint64_t *len); bool xbitmap32_test(struct xbitmap32 *bitmap, uint32_t start, uint32_t *len);
/* Bitmaps, but for type-checked for xfs_agblock_t */ /* Bitmaps, but for type-checked for xfs_agblock_t */
struct xagb_bitmap { struct xagb_bitmap {
struct xbitmap agbitmap; struct xbitmap32 agbitmap;
}; };
static inline void xagb_bitmap_init(struct xagb_bitmap *bitmap) static inline void xagb_bitmap_init(struct xagb_bitmap *bitmap)
{ {
xbitmap_init(&bitmap->agbitmap); xbitmap32_init(&bitmap->agbitmap);
} }
static inline void xagb_bitmap_destroy(struct xagb_bitmap *bitmap) static inline void xagb_bitmap_destroy(struct xagb_bitmap *bitmap)
{ {
xbitmap_destroy(&bitmap->agbitmap); xbitmap32_destroy(&bitmap->agbitmap);
} }
static inline int xagb_bitmap_clear(struct xagb_bitmap *bitmap, static inline int xagb_bitmap_clear(struct xagb_bitmap *bitmap,
xfs_agblock_t start, xfs_extlen_t len) xfs_agblock_t start, xfs_extlen_t len)
{ {
return xbitmap_clear(&bitmap->agbitmap, start, len); return xbitmap32_clear(&bitmap->agbitmap, start, len);
} }
static inline int xagb_bitmap_set(struct xagb_bitmap *bitmap, static inline int xagb_bitmap_set(struct xagb_bitmap *bitmap,
xfs_agblock_t start, xfs_extlen_t len) xfs_agblock_t start, xfs_extlen_t len)
{ {
return xbitmap_set(&bitmap->agbitmap, start, len); return xbitmap32_set(&bitmap->agbitmap, start, len);
} }
static inline bool static inline bool xagb_bitmap_test(struct xagb_bitmap *bitmap,
xagb_bitmap_test( xfs_agblock_t start, xfs_extlen_t *len)
struct xagb_bitmap *bitmap,
xfs_agblock_t start,
xfs_extlen_t *len)
{ {
uint64_t biglen = *len; return xbitmap32_test(&bitmap->agbitmap, start, len);
bool ret;
ret = xbitmap_test(&bitmap->agbitmap, start, &biglen);
if (start + biglen >= UINT_MAX) {
ASSERT(0);
biglen = UINT_MAX - start;
}
*len = biglen;
return ret;
} }
static inline int xagb_bitmap_disunion(struct xagb_bitmap *bitmap, static inline int xagb_bitmap_disunion(struct xagb_bitmap *bitmap,
struct xagb_bitmap *sub) struct xagb_bitmap *sub)
{ {
return xbitmap_disunion(&bitmap->agbitmap, &sub->agbitmap); return xbitmap32_disunion(&bitmap->agbitmap, &sub->agbitmap);
} }
static inline uint32_t xagb_bitmap_hweight(struct xagb_bitmap *bitmap) static inline uint32_t xagb_bitmap_hweight(struct xagb_bitmap *bitmap)
{ {
return xbitmap_hweight(&bitmap->agbitmap); return xbitmap32_hweight(&bitmap->agbitmap);
} }
static inline bool xagb_bitmap_empty(struct xagb_bitmap *bitmap) static inline bool xagb_bitmap_empty(struct xagb_bitmap *bitmap)
{ {
return xbitmap_empty(&bitmap->agbitmap); return xbitmap32_empty(&bitmap->agbitmap);
} }
static inline int xagb_bitmap_walk(struct xagb_bitmap *bitmap, static inline int xagb_bitmap_walk(struct xagb_bitmap *bitmap,
xbitmap_walk_fn fn, void *priv) xbitmap32_walk_fn fn, void *priv)
{ {
return xbitmap_walk(&bitmap->agbitmap, fn, priv); return xbitmap32_walk(&bitmap->agbitmap, fn, priv);
} }
int xagb_bitmap_set_btblocks(struct xagb_bitmap *bitmap, int xagb_bitmap_set_btblocks(struct xagb_bitmap *bitmap,
......
...@@ -430,13 +430,12 @@ xreap_agextent_iter( ...@@ -430,13 +430,12 @@ xreap_agextent_iter(
*/ */
STATIC int STATIC int
xreap_agmeta_extent( xreap_agmeta_extent(
uint64_t fsbno, uint32_t agbno,
uint64_t len, uint32_t len,
void *priv) void *priv)
{ {
struct xreap_state *rs = priv; struct xreap_state *rs = priv;
struct xfs_scrub *sc = rs->sc; struct xfs_scrub *sc = rs->sc;
xfs_agblock_t agbno = fsbno;
xfs_agblock_t agbno_next = agbno + len; xfs_agblock_t agbno_next = agbno + len;
int error = 0; int error = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment