From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Connect the getfsmap ioctl to the realtime rmapbt. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- fs/xfs/xfs_fsmap.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 3d76a9e35870..b63435b1df2e 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -28,6 +28,7 @@ #include "xfs_refcount_btree.h" #include "xfs_alloc_btree.h" #include "xfs_rtalloc.h" +#include "xfs_rtrmap_btree.h" /* Convert an xfs_fsmap to an fsmap. */ void @@ -550,7 +551,65 @@ xfs_getfsmap_rtdev_rtbitmap( return __xfs_getfsmap_rtdev(tp, keys, xfs_getfsmap_rtdev_rtbitmap_query, info); } -#endif /* CONFIG_XFS_RT */ + +/* Transform a absolute-startblock rmap (rtdev, logdev) into a fsmap */ +STATIC int +xfs_getfsmap_rtdev_helper( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *rec, + void *priv) +{ + struct xfs_mount *mp = cur->bc_mp; + struct xfs_getfsmap_info *info = priv; + xfs_daddr_t rec_daddr; + + rec_daddr = XFS_FSB_TO_BB(mp, rec->rm_startblock); + + return xfs_getfsmap_helper(cur->bc_tp, info, rec, rec_daddr); +} + +/* Actually query the rtrmap btree. */ +STATIC int +xfs_getfsmap_rtdev_rmapbt_query( + struct xfs_trans *tp, + struct xfs_getfsmap_info *info) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_btree_cur *bt_cur; + int error; + + /* Query the rtrmapbt */ + xfs_ilock(mp->m_rrmapip, XFS_ILOCK_SHARED); + bt_cur = xfs_rtrmapbt_init_cursor(mp, tp, mp->m_rrmapip); + error = xfs_rmap_query_range(bt_cur, &info->low, &info->high, + xfs_getfsmap_rtdev_helper, info); + if (error) + goto err; + + /* Report any gaps at the end of the rtrmapbt */ + info->last = true; + error = xfs_getfsmap_rtdev_helper(bt_cur, &info->high, info); + if (error) + goto err; + +err: + xfs_btree_del_cursor(bt_cur, error); + xfs_iunlock(mp->m_rrmapip, XFS_ILOCK_SHARED); + return error; +} + +/* Execute a getfsmap query against the realtime device rmapbt. */ +STATIC int +xfs_getfsmap_rtdev_rmapbt( + struct xfs_trans *tp, + struct xfs_fsmap *keys, + struct xfs_getfsmap_info *info) +{ + info->missing_owner = XFS_FMR_OWN_FREE; + return __xfs_getfsmap_rtdev(tp, keys, xfs_getfsmap_rtdev_rmapbt_query, + info); +} +#endif /* Execute a getfsmap query against the regular data device. */ STATIC int @@ -854,7 +913,10 @@ xfs_getfsmap( #ifdef CONFIG_XFS_RT if (mp->m_rtdev_targp) { handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev); - handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap; + if (use_rmap) + handlers[2].fn = xfs_getfsmap_rtdev_rmapbt; + else + handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap; } #endif /* CONFIG_XFS_RT */