diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_rtbitmap.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_rtbitmap.c | 70 | 
1 files changed, 70 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index ea45584a9913..e47b99e59f60 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -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); +}  |