mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
xfs: allow internal RT devices for zoned mode
Allow creating an RT subvolume on the same device as the main data device. This is mostly used for SMR HDDs where the conventional zones are used for the data device and the sequential write required zones for the zoned RT section. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
This commit is contained in:
parent
2167eaabe2
commit
bdc03eb5f9
8 changed files with 34 additions and 9 deletions
|
@ -107,9 +107,11 @@ xfs_gbno_to_daddr(
|
|||
xfs_agblock_t gbno)
|
||||
{
|
||||
struct xfs_mount *mp = xg->xg_mount;
|
||||
uint32_t blocks = mp->m_groups[xg->xg_type].blocks;
|
||||
struct xfs_groups *g = &mp->m_groups[xg->xg_type];
|
||||
xfs_fsblock_t fsbno;
|
||||
|
||||
return XFS_FSB_TO_BB(mp, (xfs_fsblock_t)xg->xg_gno * blocks + gbno);
|
||||
fsbno = (xfs_fsblock_t)xg->xg_gno * g->blocks + gbno;
|
||||
return XFS_FSB_TO_BB(mp, g->start_fsb + fsbno);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
|
|
|
@ -230,7 +230,8 @@ xfs_rtb_to_daddr(
|
|||
xfs_rgnumber_t rgno = xfs_rtb_to_rgno(mp, rtbno);
|
||||
uint64_t start_bno = (xfs_rtblock_t)rgno * g->blocks;
|
||||
|
||||
return XFS_FSB_TO_BB(mp, start_bno + (rtbno & g->blkmask));
|
||||
return XFS_FSB_TO_BB(mp,
|
||||
g->start_fsb + start_bno + (rtbno & g->blkmask));
|
||||
}
|
||||
|
||||
static inline xfs_rtblock_t
|
||||
|
@ -238,10 +239,11 @@ xfs_daddr_to_rtb(
|
|||
struct xfs_mount *mp,
|
||||
xfs_daddr_t daddr)
|
||||
{
|
||||
xfs_rfsblock_t bno = XFS_BB_TO_FSBT(mp, daddr);
|
||||
|
||||
if (xfs_has_rtgroups(mp)) {
|
||||
struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG];
|
||||
xfs_rfsblock_t bno;
|
||||
|
||||
bno = XFS_BB_TO_FSBT(mp, daddr) - g->start_fsb;
|
||||
if (xfs_has_rtgroups(mp)) {
|
||||
xfs_rgnumber_t rgno;
|
||||
uint32_t rgbno;
|
||||
|
||||
|
|
|
@ -1204,6 +1204,7 @@ xfs_sb_mount_rextsize(
|
|||
rgs->blocks = sbp->sb_rgextents * sbp->sb_rextsize;
|
||||
rgs->blklog = mp->m_sb.sb_rgblklog;
|
||||
rgs->blkmask = xfs_mask32lo(mp->m_sb.sb_rgblklog);
|
||||
rgs->start_fsb = mp->m_sb.sb_rtstart;
|
||||
} else {
|
||||
rgs->blocks = 0;
|
||||
rgs->blklog = 0;
|
||||
|
|
|
@ -150,7 +150,7 @@ xfs_file_fsync(
|
|||
* ensure newly written file data make it to disk before logging the new
|
||||
* inode size in case of an extending write.
|
||||
*/
|
||||
if (XFS_IS_REALTIME_INODE(ip))
|
||||
if (XFS_IS_REALTIME_INODE(ip) && mp->m_rtdev_targp != mp->m_ddev_targp)
|
||||
error = blkdev_issue_flush(mp->m_rtdev_targp->bt_bdev);
|
||||
else if (mp->m_logdev_targp != mp->m_ddev_targp)
|
||||
error = blkdev_issue_flush(mp->m_ddev_targp->bt_bdev);
|
||||
|
|
|
@ -308,6 +308,10 @@ xfs_growfs_data(
|
|||
if (!mutex_trylock(&mp->m_growlock))
|
||||
return -EWOULDBLOCK;
|
||||
|
||||
/* we can't grow the data section when an internal RT section exists */
|
||||
if (in->newblocks != mp->m_sb.sb_dblocks && mp->m_sb.sb_rtstart)
|
||||
return -EINVAL;
|
||||
|
||||
/* update imaxpct separately to the physical grow of the filesystem */
|
||||
if (in->imaxpct != mp->m_sb.sb_imax_pct) {
|
||||
error = xfs_growfs_imaxpct(mp, in->imaxpct);
|
||||
|
|
|
@ -103,6 +103,13 @@ struct xfs_groups {
|
|||
* rtgroup, so this mask must be 64-bit.
|
||||
*/
|
||||
uint64_t blkmask;
|
||||
|
||||
/*
|
||||
* Start of the first group in the device. This is used to support a
|
||||
* RT device following the data device on the same block device for
|
||||
* SMR hard drives.
|
||||
*/
|
||||
xfs_fsblock_t start_fsb;
|
||||
};
|
||||
|
||||
struct xfs_freecounter {
|
||||
|
|
|
@ -1266,7 +1266,8 @@ xfs_rt_check_size(
|
|||
return -EFBIG;
|
||||
}
|
||||
|
||||
error = xfs_buf_read_uncached(mp->m_rtdev_targp, daddr,
|
||||
error = xfs_buf_read_uncached(mp->m_rtdev_targp,
|
||||
XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart) + daddr,
|
||||
XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
|
||||
if (error)
|
||||
xfs_warn(mp, "cannot read last RT device sector (%lld)",
|
||||
|
|
|
@ -533,7 +533,15 @@ xfs_setup_devices(
|
|||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (mp->m_sb.sb_rtstart) {
|
||||
if (mp->m_rtdev_targp) {
|
||||
xfs_warn(mp,
|
||||
"can't use internal and external rtdev at the same time");
|
||||
return -EINVAL;
|
||||
}
|
||||
mp->m_rtdev_targp = mp->m_ddev_targp;
|
||||
} else if (mp->m_rtname) {
|
||||
error = xfs_setsize_buftarg(mp->m_rtdev_targp,
|
||||
mp->m_sb.sb_sectsize);
|
||||
if (error)
|
||||
|
@ -757,7 +765,7 @@ xfs_mount_free(
|
|||
{
|
||||
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
|
||||
xfs_free_buftarg(mp->m_logdev_targp);
|
||||
if (mp->m_rtdev_targp)
|
||||
if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp)
|
||||
xfs_free_buftarg(mp->m_rtdev_targp);
|
||||
if (mp->m_ddev_targp)
|
||||
xfs_free_buftarg(mp->m_ddev_targp);
|
||||
|
|
Loading…
Add table
Reference in a new issue