summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-07-14 11:16:17 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-10-14 14:17:27 -0700
commit21a7ebc29db770dc8446a10d5ac93b5253bccc4d (patch)
tree1902ffd93134466ff633e65ab0a186eab37a5d89 /fs/xfs/xfs_super.c
parent83e52ec0caf61182e6a89bcad12f69a96e17c062 (diff)
xfs: support realtime reflink with an extent size that isn't a power of 2realtime-reflink-extsize_2022-10-14
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.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index ba35232dbfed..94c893d48bcd 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1656,17 +1656,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;