Skip to content

Commit

Permalink
xfs: add a couple of queries to iterate free extents in the rtbitmap
Browse files Browse the repository at this point in the history
Add _query_range and _query_all functions to the realtime bitmap
allocator.  These two functions are similar in usage to the btree
functions with the same name and will be used for getfsmap and scrub.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
  • Loading branch information
Darrick J. Wong committed Apr 3, 2017
1 parent e9a2599 commit fb3c3de
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
70 changes: 70 additions & 0 deletions fs/xfs/libxfs/xfs_rtbitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,3 +1016,73 @@ xfs_rtfree_extent(
}
return 0;
}

/* Find all the free records within a given range. */
int
xfs_rtalloc_query_range(
struct xfs_trans *tp,
struct xfs_rtalloc_rec *low_rec,
struct xfs_rtalloc_rec *high_rec,
xfs_rtalloc_query_range_fn fn,
void *priv)
{
struct xfs_rtalloc_rec rec;
struct xfs_mount *mp = tp->t_mountp;
xfs_rtblock_t rtstart;
xfs_rtblock_t rtend;
xfs_rtblock_t rem;
int is_free;
int error = 0;

if (low_rec->ar_startblock > high_rec->ar_startblock)
return -EINVAL;
else if (low_rec->ar_startblock == high_rec->ar_startblock)
return 0;

/* Iterate the bitmap, looking for discrepancies. */
rtstart = low_rec->ar_startblock;
rem = high_rec->ar_startblock - rtstart;
while (rem) {
/* Is the first block free? */
error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
&is_free);
if (error)
break;

/* How long does the extent go for? */
error = xfs_rtfind_forw(mp, tp, rtstart,
high_rec->ar_startblock - 1, &rtend);
if (error)
break;

if (is_free) {
rec.ar_startblock = rtstart;
rec.ar_blockcount = rtend - rtstart + 1;

error = fn(tp, &rec, priv);
if (error)
break;
}

rem -= rtend - rtstart + 1;
rtstart = rtend + 1;
}

return error;
}

/* Find all the free records. */
int
xfs_rtalloc_query_all(
struct xfs_trans *tp,
xfs_rtalloc_query_range_fn fn,
void *priv)
{
struct xfs_rtalloc_rec keys[2];

keys[0].ar_startblock = 0;
keys[1].ar_startblock = tp->t_mountp->m_sb.sb_rblocks;
keys[0].ar_blockcount = keys[1].ar_blockcount = 0;

return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv);
}
22 changes: 20 additions & 2 deletions fs/xfs/xfs_rtalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
struct xfs_mount;
struct xfs_trans;

struct xfs_rtalloc_rec {
xfs_rtblock_t ar_startblock;
xfs_rtblock_t ar_blockcount;
};

typedef int (*xfs_rtalloc_query_range_fn)(
struct xfs_trans *tp,
struct xfs_rtalloc_rec *rec,
void *priv);

#ifdef CONFIG_XFS_RT
/*
* Function prototypes for exported functions.
Expand Down Expand Up @@ -118,13 +128,21 @@ int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
xfs_rtblock_t start, xfs_extlen_t len,
struct xfs_buf **rbpp, xfs_fsblock_t *rsb);


int xfs_rtalloc_query_range(struct xfs_trans *tp,
struct xfs_rtalloc_rec *low_rec,
struct xfs_rtalloc_rec *high_rec,
xfs_rtalloc_query_range_fn fn,
void *priv);
int xfs_rtalloc_query_all(struct xfs_trans *tp,
xfs_rtalloc_query_range_fn fn,
void *priv);
#else
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS)
# define xfs_rtfree_extent(t,b,l) (ENOSYS)
# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS)
# define xfs_growfs_rt(mp,in) (ENOSYS)
# define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS)
# define xfs_rtalloc_query_all(t,f,p) (ENOSYS)
static inline int /* error */
xfs_rtmount_init(
xfs_mount_t *mp) /* file system mount structure */
Expand Down

0 comments on commit fb3c3de

Please sign in to comment.