mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
xfs: enable fsmap reporting for internal RT devices
File system with internal RT devices are a bit odd in that we need to report AGs and RGs. To make this happen use separate synthetic fmr_device values for the different sections instead of the dev_t mapping used by other XFS configurations. The data device is reported as file system metadata before the start of the RGs for the synthetic RT fmr_device. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
This commit is contained in:
parent
14d355dcec
commit
e50ec7fac8
2 changed files with 72 additions and 17 deletions
|
@ -1082,6 +1082,15 @@ struct xfs_rtgroup_geometry {
|
||||||
#define XFS_IOC_COMMIT_RANGE _IOW ('X', 131, struct xfs_commit_range)
|
#define XFS_IOC_COMMIT_RANGE _IOW ('X', 131, struct xfs_commit_range)
|
||||||
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
|
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Devices supported by a single XFS file system. Reported in fsmaps fmr_device
|
||||||
|
* when using internal RT devices.
|
||||||
|
*/
|
||||||
|
enum xfs_device {
|
||||||
|
XFS_DEV_DATA = 1,
|
||||||
|
XFS_DEV_LOG = 2,
|
||||||
|
XFS_DEV_RT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef HAVE_BBMACROS
|
#ifndef HAVE_BBMACROS
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -879,17 +879,39 @@ xfs_getfsmap_rtdev_rmapbt(
|
||||||
struct xfs_mount *mp = tp->t_mountp;
|
struct xfs_mount *mp = tp->t_mountp;
|
||||||
struct xfs_rtgroup *rtg = NULL;
|
struct xfs_rtgroup *rtg = NULL;
|
||||||
struct xfs_btree_cur *bt_cur = NULL;
|
struct xfs_btree_cur *bt_cur = NULL;
|
||||||
|
xfs_daddr_t rtstart_daddr;
|
||||||
xfs_rtblock_t start_rtb;
|
xfs_rtblock_t start_rtb;
|
||||||
xfs_rtblock_t end_rtb;
|
xfs_rtblock_t end_rtb;
|
||||||
xfs_rgnumber_t start_rg, end_rg;
|
xfs_rgnumber_t start_rg, end_rg;
|
||||||
uint64_t eofs;
|
uint64_t eofs;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
|
eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart + mp->m_sb.sb_rblocks);
|
||||||
if (keys[0].fmr_physical >= eofs)
|
if (keys[0].fmr_physical >= eofs)
|
||||||
return 0;
|
return 0;
|
||||||
start_rtb = xfs_daddr_to_rtb(mp, keys[0].fmr_physical);
|
|
||||||
end_rtb = xfs_daddr_to_rtb(mp, min(eofs - 1, keys[1].fmr_physical));
|
rtstart_daddr = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart);
|
||||||
|
if (keys[0].fmr_physical < rtstart_daddr) {
|
||||||
|
struct xfs_fsmap_irec frec = {
|
||||||
|
.owner = XFS_RMAP_OWN_FS,
|
||||||
|
.len_daddr = rtstart_daddr,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Adjust the low key if we are continuing from where we left off. */
|
||||||
|
if (keys[0].fmr_length > 0) {
|
||||||
|
info->low_daddr = keys[0].fmr_physical + keys[0].fmr_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fabricate an rmap entry for space occupied by the data dev */
|
||||||
|
error = xfs_getfsmap_helper(tp, info, &frec);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_rtb = xfs_daddr_to_rtb(mp, rtstart_daddr + keys[0].fmr_physical);
|
||||||
|
end_rtb = xfs_daddr_to_rtb(mp, rtstart_daddr +
|
||||||
|
min(eofs - 1, keys[1].fmr_physical));
|
||||||
|
|
||||||
info->missing_owner = XFS_FMR_OWN_FREE;
|
info->missing_owner = XFS_FMR_OWN_FREE;
|
||||||
|
|
||||||
|
@ -1004,22 +1026,40 @@ xfs_getfsmap_rtdev_rmapbt(
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_XFS_RT */
|
#endif /* CONFIG_XFS_RT */
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
xfs_getfsmap_device(
|
||||||
|
struct xfs_mount *mp,
|
||||||
|
enum xfs_device dev)
|
||||||
|
{
|
||||||
|
if (mp->m_sb.sb_rtstart)
|
||||||
|
return dev;
|
||||||
|
|
||||||
|
switch (dev) {
|
||||||
|
case XFS_DEV_DATA:
|
||||||
|
return new_encode_dev(mp->m_ddev_targp->bt_dev);
|
||||||
|
case XFS_DEV_LOG:
|
||||||
|
return new_encode_dev(mp->m_logdev_targp->bt_dev);
|
||||||
|
case XFS_DEV_RT:
|
||||||
|
if (!mp->m_rtdev_targp)
|
||||||
|
break;
|
||||||
|
return new_encode_dev(mp->m_rtdev_targp->bt_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do we recognize the device? */
|
/* Do we recognize the device? */
|
||||||
STATIC bool
|
STATIC bool
|
||||||
xfs_getfsmap_is_valid_device(
|
xfs_getfsmap_is_valid_device(
|
||||||
struct xfs_mount *mp,
|
struct xfs_mount *mp,
|
||||||
struct xfs_fsmap *fm)
|
struct xfs_fsmap *fm)
|
||||||
{
|
{
|
||||||
if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX ||
|
return fm->fmr_device == 0 ||
|
||||||
fm->fmr_device == new_encode_dev(mp->m_ddev_targp->bt_dev))
|
fm->fmr_device == UINT_MAX ||
|
||||||
return true;
|
fm->fmr_device == xfs_getfsmap_device(mp, XFS_DEV_DATA) ||
|
||||||
if (mp->m_logdev_targp &&
|
fm->fmr_device == xfs_getfsmap_device(mp, XFS_DEV_LOG) ||
|
||||||
fm->fmr_device == new_encode_dev(mp->m_logdev_targp->bt_dev))
|
(mp->m_rtdev_targp &&
|
||||||
return true;
|
fm->fmr_device == xfs_getfsmap_device(mp, XFS_DEV_RT));
|
||||||
if (mp->m_rtdev_targp &&
|
|
||||||
fm->fmr_device == new_encode_dev(mp->m_rtdev_targp->bt_dev))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that the low key is less than the high key. */
|
/* Ensure that the low key is less than the high key. */
|
||||||
|
@ -1126,7 +1166,7 @@ xfs_getfsmap(
|
||||||
/* Set up our device handlers. */
|
/* Set up our device handlers. */
|
||||||
memset(handlers, 0, sizeof(handlers));
|
memset(handlers, 0, sizeof(handlers));
|
||||||
handlers[0].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
|
handlers[0].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
|
||||||
handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev);
|
handlers[0].dev = xfs_getfsmap_device(mp, XFS_DEV_DATA);
|
||||||
if (use_rmap)
|
if (use_rmap)
|
||||||
handlers[0].fn = xfs_getfsmap_datadev_rmapbt;
|
handlers[0].fn = xfs_getfsmap_datadev_rmapbt;
|
||||||
else
|
else
|
||||||
|
@ -1134,7 +1174,7 @@ xfs_getfsmap(
|
||||||
if (mp->m_logdev_targp != mp->m_ddev_targp) {
|
if (mp->m_logdev_targp != mp->m_ddev_targp) {
|
||||||
handlers[1].nr_sectors = XFS_FSB_TO_BB(mp,
|
handlers[1].nr_sectors = XFS_FSB_TO_BB(mp,
|
||||||
mp->m_sb.sb_logblocks);
|
mp->m_sb.sb_logblocks);
|
||||||
handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev);
|
handlers[1].dev = xfs_getfsmap_device(mp, XFS_DEV_LOG);
|
||||||
handlers[1].fn = xfs_getfsmap_logdev;
|
handlers[1].fn = xfs_getfsmap_logdev;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_XFS_RT
|
#ifdef CONFIG_XFS_RT
|
||||||
|
@ -1144,7 +1184,7 @@ xfs_getfsmap(
|
||||||
*/
|
*/
|
||||||
if (mp->m_rtdev_targp && (use_rmap || !xfs_has_zoned(mp))) {
|
if (mp->m_rtdev_targp && (use_rmap || !xfs_has_zoned(mp))) {
|
||||||
handlers[2].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
|
handlers[2].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
|
||||||
handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev);
|
handlers[2].dev = xfs_getfsmap_device(mp, XFS_DEV_RT);
|
||||||
if (use_rmap)
|
if (use_rmap)
|
||||||
handlers[2].fn = xfs_getfsmap_rtdev_rmapbt;
|
handlers[2].fn = xfs_getfsmap_rtdev_rmapbt;
|
||||||
else
|
else
|
||||||
|
@ -1234,6 +1274,12 @@ xfs_getfsmap(
|
||||||
|
|
||||||
if (tp)
|
if (tp)
|
||||||
xfs_trans_cancel(tp);
|
xfs_trans_cancel(tp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For internal RT device we need to report different synthetic devices
|
||||||
|
* for a single physical device, and thus can't report the actual dev_t.
|
||||||
|
*/
|
||||||
|
if (!mp->m_sb.sb_rtstart)
|
||||||
head->fmh_oflags = FMH_OF_DEV_T;
|
head->fmh_oflags = FMH_OF_DEV_T;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue