mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02: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…
	
		Reference in a new issue