diff mbox series

[v3,10/21] xfs: Update xfs_is_falloc_aligned() mask for forcealign

Message ID 20240429174746.2132161-11-john.g.garry@oracle.com (mailing list archive)
State New
Headers show
Series block atomic writes for XFS | expand

Commit Message

John Garry April 29, 2024, 5:47 p.m. UTC
For when forcealign is enabled, we want the alignment mask to cover an
aligned extent, similar to rtvol.

Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 fs/xfs/xfs_file.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Dave Chinner April 30, 2024, 11:35 p.m. UTC | #1
On Mon, Apr 29, 2024 at 05:47:35PM +0000, John Garry wrote:
> For when forcealign is enabled, we want the alignment mask to cover an
> aligned extent, similar to rtvol.
> 
> Signed-off-by: John Garry <john.g.garry@oracle.com>
> ---
>  fs/xfs/xfs_file.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 632653e00906..e81e01e6b22b 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -61,7 +61,10 @@ xfs_is_falloc_aligned(
>  		}
>  		mask = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) - 1;
>  	} else {
> -		mask = mp->m_sb.sb_blocksize - 1;
> +		if (xfs_inode_has_forcealign(ip) && ip->i_extsize > 1)
> +			mask = (mp->m_sb.sb_blocksize * ip->i_extsize) - 1;
> +		else
> +			mask = mp->m_sb.sb_blocksize - 1;
>  	}
>  
>  	return !((pos | len) & mask);

I think this whole function needs to be rewritten so that
non-power-of-2 extent sizes are supported on both devices properly.

	xfs_extlen_t	fsbs = 1;
	u64		bytes;
	u32		mod;

	if (xfs_inode_has_forcealign(ip))
		fsbs = ip->i_extsize;
	else if (XFS_IS_REALTIME_INODE(ip))
		fsbs = mp->m_sb.sb_rextsize;

	bytes = XFS_FSB_TO_B(mp, fsbs);
	if (is_power_of_2(fsbs))
		return !((pos | len) & (bytes - 1));

	div_u64_rem(pos, bytes, &mod);
	if (mod)
		return false;
	div_u64_rem(len, bytes, &mod);
	return mod == 0;

-Dave.
John Garry May 1, 2024, 10:48 a.m. UTC | #2
On 01/05/2024 00:35, Dave Chinner wrote:
>>   	return !((pos | len) & mask);
> I think this whole function needs to be rewritten so that
> non-power-of-2 extent sizes are supported on both devices properly.
> 
> 	xfs_extlen_t	fsbs = 1;
> 	u64		bytes;
> 	u32		mod;
> 
> 	if (xfs_inode_has_forcealign(ip))
> 		fsbs = ip->i_extsize;
> 	else if (XFS_IS_REALTIME_INODE(ip))
> 		fsbs = mp->m_sb.sb_rextsize;
> 
> 	bytes = XFS_FSB_TO_B(mp, fsbs);
> 	if (is_power_of_2(fsbs))
> 		return !((pos | len) & (bytes - 1));
> 
> 	div_u64_rem(pos, bytes, &mod);
> 	if (mod)
> 		return false;
> 	div_u64_rem(len, bytes, &mod);
> 	return mod == 0;

ok, but I still have a doubt about non-power-of-2 forcealign extsize 
support.

Thanks,
John
Darrick J. Wong May 1, 2024, 11:45 p.m. UTC | #3
On Wed, May 01, 2024 at 11:48:59AM +0100, John Garry wrote:
> On 01/05/2024 00:35, Dave Chinner wrote:
> > >   	return !((pos | len) & mask);
> > I think this whole function needs to be rewritten so that
> > non-power-of-2 extent sizes are supported on both devices properly.
> > 
> > 	xfs_extlen_t	fsbs = 1;
> > 	u64		bytes;
> > 	u32		mod;
> > 
> > 	if (xfs_inode_has_forcealign(ip))
> > 		fsbs = ip->i_extsize;
> > 	else if (XFS_IS_REALTIME_INODE(ip))
> > 		fsbs = mp->m_sb.sb_rextsize;
> > 
> > 	bytes = XFS_FSB_TO_B(mp, fsbs);
> > 	if (is_power_of_2(fsbs))
> > 		return !((pos | len) & (bytes - 1));
> > 
> > 	div_u64_rem(pos, bytes, &mod);
> > 	if (mod)
> > 		return false;
> > 	div_u64_rem(len, bytes, &mod);
> > 	return mod == 0;
> 
> ok, but I still have a doubt about non-power-of-2 forcealign extsize
> support.

The trouble is, non-power-of-2 extent size hints are supported for
regular and realtime files for funny cases like trying to align
allocations to RAID stripes.  I think it would be hard to drop support
for this, given that means that old filesystems can't ever get upgraded
to forcealign.

--D

> Thanks,
> John
>
diff mbox series

Patch

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 632653e00906..e81e01e6b22b 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -61,7 +61,10 @@  xfs_is_falloc_aligned(
 		}
 		mask = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) - 1;
 	} else {
-		mask = mp->m_sb.sb_blocksize - 1;
+		if (xfs_inode_has_forcealign(ip) && ip->i_extsize > 1)
+			mask = (mp->m_sb.sb_blocksize * ip->i_extsize) - 1;
+		else
+			mask = mp->m_sb.sb_blocksize - 1;
 	}
 
 	return !((pos | len) & mask);