Commit 6772fcc8 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: convert xbitmap to interval tree

Convert the xbitmap code to use interval trees instead of linked lists.
This reduces the amount of coding required to handle the disunion
operation and in the future will make it easier to set bits in arbitrary
order yet later be able to extract maximally sized extents, which we'll
need for rebuilding certain structures.  We define our own interval tree
type so that it can deal with 64-bit indices even on 32-bit machines.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 7296a6d6
...@@ -663,7 +663,7 @@ xrep_agfl_fill( ...@@ -663,7 +663,7 @@ xrep_agfl_fill(
} }
/* Write out a totally new AGFL. */ /* Write out a totally new AGFL. */
STATIC void STATIC int
xrep_agfl_init_header( xrep_agfl_init_header(
struct xfs_scrub *sc, struct xfs_scrub *sc,
struct xfs_buf *agfl_bp, struct xfs_buf *agfl_bp,
...@@ -676,6 +676,7 @@ xrep_agfl_init_header( ...@@ -676,6 +676,7 @@ xrep_agfl_init_header(
}; };
struct xfs_mount *mp = sc->mp; struct xfs_mount *mp = sc->mp;
struct xfs_agfl *agfl; struct xfs_agfl *agfl;
int error;
ASSERT(flcount <= xfs_agfl_size(mp)); ASSERT(flcount <= xfs_agfl_size(mp));
...@@ -697,12 +698,15 @@ xrep_agfl_init_header( ...@@ -697,12 +698,15 @@ xrep_agfl_init_header(
xbitmap_init(&af.used_extents); xbitmap_init(&af.used_extents);
af.agfl_bno = xfs_buf_to_agfl_bno(agfl_bp), af.agfl_bno = xfs_buf_to_agfl_bno(agfl_bp),
xbitmap_walk(agfl_extents, xrep_agfl_fill, &af); xbitmap_walk(agfl_extents, xrep_agfl_fill, &af);
xbitmap_disunion(agfl_extents, &af.used_extents); error = xbitmap_disunion(agfl_extents, &af.used_extents);
if (error)
return error;
/* Write new AGFL to disk. */ /* Write new AGFL to disk. */
xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF); xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF);
xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1); xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1);
xbitmap_destroy(&af.used_extents); xbitmap_destroy(&af.used_extents);
return 0;
} }
/* Repair the AGFL. */ /* Repair the AGFL. */
...@@ -755,7 +759,9 @@ xrep_agfl( ...@@ -755,7 +759,9 @@ xrep_agfl(
* buffers until we know that part works. * buffers until we know that part works.
*/ */
xrep_agfl_update_agf(sc, agf_bp, flcount); xrep_agfl_update_agf(sc, agf_bp, flcount);
xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount); error = xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount);
if (error)
goto err;
/* /*
* Ok, the AGFL should be ready to go now. Roll the transaction to * Ok, the AGFL should be ready to go now. Roll the transaction to
......
This diff is collapsed.
...@@ -6,19 +6,14 @@ ...@@ -6,19 +6,14 @@
#ifndef __XFS_SCRUB_BITMAP_H__ #ifndef __XFS_SCRUB_BITMAP_H__
#define __XFS_SCRUB_BITMAP_H__ #define __XFS_SCRUB_BITMAP_H__
struct xbitmap_range {
struct list_head list;
uint64_t start;
uint64_t len;
};
struct xbitmap { struct xbitmap {
struct list_head list; struct rb_root_cached xb_root;
}; };
void xbitmap_init(struct xbitmap *bitmap); void xbitmap_init(struct xbitmap *bitmap);
void xbitmap_destroy(struct xbitmap *bitmap); void xbitmap_destroy(struct xbitmap *bitmap);
int xbitmap_clear(struct xbitmap *bitmap, uint64_t start, uint64_t len);
int xbitmap_set(struct xbitmap *bitmap, uint64_t start, uint64_t len); int xbitmap_set(struct xbitmap *bitmap, uint64_t start, uint64_t len);
int xbitmap_disunion(struct xbitmap *bitmap, struct xbitmap *sub); int xbitmap_disunion(struct xbitmap *bitmap, struct xbitmap *sub);
int xbitmap_set_btcur_path(struct xbitmap *bitmap, int xbitmap_set_btcur_path(struct xbitmap *bitmap,
...@@ -42,4 +37,6 @@ typedef int (*xbitmap_walk_bits_fn)(uint64_t bit, void *priv); ...@@ -42,4 +37,6 @@ typedef int (*xbitmap_walk_bits_fn)(uint64_t bit, void *priv);
int xbitmap_walk_bits(struct xbitmap *bitmap, xbitmap_walk_bits_fn fn, int xbitmap_walk_bits(struct xbitmap *bitmap, xbitmap_walk_bits_fn fn,
void *priv); void *priv);
bool xbitmap_empty(struct xbitmap *bitmap);
#endif /* __XFS_SCRUB_BITMAP_H__ */ #endif /* __XFS_SCRUB_BITMAP_H__ */
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