xfs: provide a query_range function for freespace btrees
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 28 Mar 2017 21:56:35 +0000 (14:56 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 3 Apr 2017 22:18:17 +0000 (15:18 -0700)
Implement a query_range function for the bnobt and cntbt.  This will
be used for getfsmap fallback if there is no rmapbt and by the online
scrub and repair code.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.h

index 369adcc18c02900f096a5ccd543a8c424dff7894..f65b8d49ec16120ea6e69da504f61a5da3f1708e 100644 (file)
@@ -2868,3 +2868,45 @@ err:
        xfs_trans_brelse(tp, agbp);
        return error;
 }
+
+struct xfs_alloc_query_range_info {
+       xfs_alloc_query_range_fn        fn;
+       void                            *priv;
+};
+
+/* Format btree record and pass to our callback. */
+STATIC int
+xfs_alloc_query_range_helper(
+       struct xfs_btree_cur            *cur,
+       union xfs_btree_rec             *rec,
+       void                            *priv)
+{
+       struct xfs_alloc_query_range_info       *query = priv;
+       struct xfs_alloc_rec_incore             irec;
+
+       irec.ar_startblock = be32_to_cpu(rec->alloc.ar_startblock);
+       irec.ar_blockcount = be32_to_cpu(rec->alloc.ar_blockcount);
+       return query->fn(cur, &irec, query->priv);
+}
+
+/* Find all free space within a given range of blocks. */
+int
+xfs_alloc_query_range(
+       struct xfs_btree_cur                    *cur,
+       struct xfs_alloc_rec_incore             *low_rec,
+       struct xfs_alloc_rec_incore             *high_rec,
+       xfs_alloc_query_range_fn                fn,
+       void                                    *priv)
+{
+       union xfs_btree_irec                    low_brec;
+       union xfs_btree_irec                    high_brec;
+       struct xfs_alloc_query_range_info       query;
+
+       ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
+       low_brec.a = *low_rec;
+       high_brec.a = *high_rec;
+       query.priv = priv;
+       query.fn = fn;
+       return xfs_btree_query_range(cur, &low_brec, &high_brec,
+                       xfs_alloc_query_range_helper, &query);
+}
index 2a8d0fa6fbbea3973f96183934d2ff2e0e581f53..6c2643c4abd3f2f51ea114db23aef89802db5c4c 100644 (file)
@@ -219,4 +219,14 @@ int xfs_free_extent_fix_freelist(struct xfs_trans *tp, xfs_agnumber_t agno,
 
 xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp);
 
+typedef int (*xfs_alloc_query_range_fn)(
+       struct xfs_btree_cur            *cur,
+       struct xfs_alloc_rec_incore     *rec,
+       void                            *priv);
+
+int xfs_alloc_query_range(struct xfs_btree_cur *cur,
+               struct xfs_alloc_rec_incore *low_rec,
+               struct xfs_alloc_rec_incore *high_rec,
+               xfs_alloc_query_range_fn fn, void *priv);
+
 #endif /* __XFS_ALLOC_H__ */