diff options
author | Darrick J. Wong <djwong@kernel.org> | 2024-11-04 07:19:28 +0300 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2024-11-06 00:38:42 +0300 |
commit | b91afef724710e3dc7d65a28105ffd7a4e861d69 (patch) | |
tree | 94c2348a6421a4d6b2dc774453add53fc2a8aaff /fs/xfs | |
parent | 44e69c9af159e61d4f765ff4805dd5b55f241597 (diff) | |
download | linux-b91afef724710e3dc7d65a28105ffd7a4e861d69.tar.xz |
xfs: don't merge ioends across RTGs
Unlike AGs, RTGs don't always have metadata in their first blocks, and
thus we don't get automatic protection from merging I/O completions
across RTG boundaries. Add code to set the IOMAP_F_BOUNDARY flag for
ioends that start at the first block of a RTG so that they never get
merged into the previous ioend.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_rtgroup.h | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 13 |
2 files changed, 21 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index 026f34f984b3..2ddfac9a0182 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -188,6 +188,15 @@ xfs_rtb_to_rgbno( return __xfs_rtb_to_rgbno(mp, rtbno); } +/* Is rtbno the start of a RT group? */ +static inline bool +xfs_rtbno_is_group_start( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return (rtbno & mp->m_rgblkmask) == 0; +} + static inline xfs_daddr_t xfs_rtb_to_daddr( struct xfs_mount *mp, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index e810e901cd35..17e5c273e28c 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -24,6 +24,7 @@ #include "xfs_iomap.h" #include "xfs_trace.h" #include "xfs_quota.h" +#include "xfs_rtgroup.h" #include "xfs_dquot_item.h" #include "xfs_dquot.h" #include "xfs_reflink.h" @@ -115,7 +116,9 @@ xfs_bmbt_to_iomap( iomap->addr = IOMAP_NULL_ADDR; iomap->type = IOMAP_DELALLOC; } else { - iomap->addr = BBTOB(xfs_fsb_to_db(ip, imap->br_startblock)); + xfs_daddr_t daddr = xfs_fsb_to_db(ip, imap->br_startblock); + + iomap->addr = BBTOB(daddr); if (mapping_flags & IOMAP_DAX) iomap->addr += target->bt_dax_part_off; @@ -124,6 +127,14 @@ xfs_bmbt_to_iomap( else iomap->type = IOMAP_MAPPED; + /* + * Mark iomaps starting at the first sector of a RTG as merge + * boundary so that each I/O completions is contained to a + * single RTG. + */ + if (XFS_IS_REALTIME_INODE(ip) && xfs_has_rtgroups(mp) && + xfs_rtbno_is_group_start(mp, imap->br_startblock)) + iomap->flags |= IOMAP_F_BOUNDARY; } iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); |