diff options
author | Darrick J. Wong <djwong@kernel.org> | 2022-07-14 11:16:17 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-11-09 19:08:14 -0800 |
commit | 55e5e9fb6263f16f2a10d48dfea4403fbbbd65a7 (patch) | |
tree | 385d1c5cf31dcdaf408dbde2904a7d039412e8f4 /fs/xfs/xfs_super.c | |
parent | f8f4c5a32618472cbc740e4c5b21efa3027a60b0 (diff) |
xfs: support realtime reflink with an extent size that isn't a power of 2realtime-reflink-extsize_2022-11-09
Add the necessary alignment checking code to the reflink remap code to
ensure that remap requests are aligned to rt extent boundaries if the
realtime extent size isn't a power of two. The VFS helpers assume that
they can use the usual (blocksize - 1) masking to avoid slow 64-bit
division, but since XFS is special we won't make everyone pay that cost
for our weird edge case.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r-- | fs/xfs/xfs_super.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 2cb766b454fd..1dc6fbb85567 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1662,17 +1662,17 @@ xfs_fs_fill_super( * state. This means that we cannot dirty all the pages * backing an rt extent without dirtying the adjoining rt * extents. If those rt extents are shared and extend into - * other pages, this leads to crazy write amplification. The - * VFS remap_range checks assume power-of-two block sizes. + * other pages, this leads to crazy write amplification. * * Hence we only support rt extent sizes that are an integer - * power of two because we know those will align with the page - * size. + * power of two or an integer multiple of the page size because + * we know those will align with the page size. */ if (xfs_has_realtime(mp) && - !is_power_of_2(mp->m_sb.sb_rextsize)) { + !is_power_of_2(mp->m_sb.sb_rextsize) && + (XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) & ~PAGE_MASK)) { xfs_alert(mp, - "reflink not compatible with non-power-of-2 realtime extent size %u!", + "reflink not compatible with realtime extent size %u!", mp->m_sb.sb_rextsize); error = -EINVAL; goto out_filestream_unmount; |