public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb
@ 2014-11-24 19:06 Peter Watkins
  2014-11-25 13:49 ` Brian Foster
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Peter Watkins @ 2014-11-24 19:06 UTC (permalink / raw)
  To: xfs; +Cc: Peter Watkins

Someone else may have run into this already, if not please take
a look.

 Peter

If extsize is set and new_last_fsb is larger than 32 bits, the
roundup to extsize will overflow the align variable. Instead,
combine alignments by rounding extsize hint up to stripe size.

Signed-off-by: Peter Watkins <treestem@gmail.com>
Reviewed-by: Nathaniel W. Turner <nate@houseofnate.net>
---
 fs/xfs/xfs_iomap.c |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index afcf3c9..0c4abfe 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -52,7 +52,7 @@ xfs_iomap_eof_align_last_fsb(
 	xfs_extlen_t	extsize,
 	xfs_fileoff_t	*last_fsb)
 {
-	xfs_fileoff_t	new_last_fsb = 0;
+	xfs_fileoff_t	new_last_fsb;
 	xfs_extlen_t	align = 0;
 	int		eof, error;
 
@@ -70,23 +70,24 @@ xfs_iomap_eof_align_last_fsb(
 		else if (mp->m_dalign)
 			align = mp->m_dalign;
 
-		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
-			new_last_fsb = roundup_64(*last_fsb, align);
+		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
+			align = 0;
 	}
 
 	/*
-	 * Always round up the allocation request to an extent boundary
-	 * (when file on a real-time subvolume or has di_extsize hint).
+	 * Round up the allocation request to an extent boundary. If
+	 * already aligned to a stripe, round extsize up to a stripe
+	 * boundary.
 	 */
 	if (extsize) {
-		if (new_last_fsb)
-			align = roundup_64(new_last_fsb, extsize);
+		if (align)
+			align = roundup_64(extsize, align);
 		else
 			align = extsize;
-		new_last_fsb = roundup_64(*last_fsb, align);
 	}
 
-	if (new_last_fsb) {
+	if (align) {
+		new_last_fsb = roundup_64(*last_fsb, align);
 		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
 		if (error)
 			return error;
-- 
1.7.9.5

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb
  2014-11-24 19:06 [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb Peter Watkins
@ 2014-11-25 13:49 ` Brian Foster
  2014-11-25 23:18 ` Dave Chinner
  2014-12-01 22:45 ` [PATCH v2] " Peter Watkins
  2 siblings, 0 replies; 5+ messages in thread
From: Brian Foster @ 2014-11-25 13:49 UTC (permalink / raw)
  To: Peter Watkins; +Cc: xfs

On Mon, Nov 24, 2014 at 02:06:13PM -0500, Peter Watkins wrote:
> Someone else may have run into this already, if not please take
> a look.
> 
>  Peter
> 
> If extsize is set and new_last_fsb is larger than 32 bits, the
> roundup to extsize will overflow the align variable. Instead,
> combine alignments by rounding extsize hint up to stripe size.
> 
> Signed-off-by: Peter Watkins <treestem@gmail.com>
> Reviewed-by: Nathaniel W. Turner <nate@houseofnate.net>
> ---

So we basically assign a file offset value to an extent length variable.
Nice spot...

>  fs/xfs/xfs_iomap.c |   19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index afcf3c9..0c4abfe 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -52,7 +52,7 @@ xfs_iomap_eof_align_last_fsb(
>  	xfs_extlen_t	extsize,
>  	xfs_fileoff_t	*last_fsb)
>  {
> -	xfs_fileoff_t	new_last_fsb = 0;
> +	xfs_fileoff_t	new_last_fsb;
>  	xfs_extlen_t	align = 0;
>  	int		eof, error;
>  
> @@ -70,23 +70,24 @@ xfs_iomap_eof_align_last_fsb(
>  		else if (mp->m_dalign)
>  			align = mp->m_dalign;
>  
> -		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
> -			new_last_fsb = roundup_64(*last_fsb, align);
> +		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
> +			align = 0;
>  	}
>  
>  	/*
> -	 * Always round up the allocation request to an extent boundary
> -	 * (when file on a real-time subvolume or has di_extsize hint).
> +	 * Round up the allocation request to an extent boundary. If
> +	 * already aligned to a stripe, round extsize up to a stripe
> +	 * boundary.
>  	 */
>  	if (extsize) {
> -		if (new_last_fsb)
> -			align = roundup_64(new_last_fsb, extsize);
> +		if (align)
> +			align = roundup_64(extsize, align);

I think the previous behavior would swap this around and round up the
alignment to the extsize. Because we aligned from the actual fsb, we'd
effectively use the stripe alignment as a min. alloc and always align to
the hint. Here we simply round up extsize to the stripe alignment. IOW,
the alignment was previously always to the hint, even if smaller than
the stripe alignment, and now we align to the larger of the hint or
stripe.

That said, it's kind of a weird scenario and it's not clear to me
whether it's important or even intended. If not, the patch seems Ok to
me...

Brian

>  		else
>  			align = extsize;
> -		new_last_fsb = roundup_64(*last_fsb, align);
>  	}
>  
> -	if (new_last_fsb) {
> +	if (align) {
> +		new_last_fsb = roundup_64(*last_fsb, align);
>  		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
>  		if (error)
>  			return error;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb
  2014-11-24 19:06 [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb Peter Watkins
  2014-11-25 13:49 ` Brian Foster
@ 2014-11-25 23:18 ` Dave Chinner
  2014-12-01 22:45 ` [PATCH v2] " Peter Watkins
  2 siblings, 0 replies; 5+ messages in thread
From: Dave Chinner @ 2014-11-25 23:18 UTC (permalink / raw)
  To: Peter Watkins; +Cc: xfs

On Mon, Nov 24, 2014 at 02:06:13PM -0500, Peter Watkins wrote:
> Someone else may have run into this already, if not please take
> a look.
> 
>  Peter
> 
> If extsize is set and new_last_fsb is larger than 32 bits, the
> roundup to extsize will overflow the align variable. Instead,
> combine alignments by rounding extsize hint up to stripe size.

Change of allocator behaviour that will cause significant problems
for applications that depend on deterministic behaviour from the
extent size hint.

i.e. The extsize hint is supposed to override all other alignments
that are made - extent size hints are effectively a "unit of
allocation".  Hence we round up to stripe unit/width, then apply the
extent size hint alignment so that extent sizes are always aligned
to the extent size hint....

....
> @@ -52,7 +52,7 @@ xfs_iomap_eof_align_last_fsb(
>  	xfs_extlen_t	extsize,
>  	xfs_fileoff_t	*last_fsb)
>  {
> -	xfs_fileoff_t	new_last_fsb = 0;
> +	xfs_fileoff_t	new_last_fsb;

That can be declared in the context that uses it now.

>  	xfs_extlen_t	align = 0;
>  	int		eof, error;
>  
> @@ -70,23 +70,24 @@ xfs_iomap_eof_align_last_fsb(
>  		else if (mp->m_dalign)
>  			align = mp->m_dalign;
>  
> -		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
> -			new_last_fsb = roundup_64(*last_fsb, align);
> +		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
> +			align = 0;
>  	}
>  
>  	/*
> -	 * Always round up the allocation request to an extent boundary
> -	 * (when file on a real-time subvolume or has di_extsize hint).
> +	 * Round up the allocation request to an extent boundary. If
> +	 * already aligned to a stripe, round extsize up to a stripe
> +	 * boundary.
>  	 */

Drop the comment change...

>  	if (extsize) {
> -		if (new_last_fsb)
> -			align = roundup_64(new_last_fsb, extsize);
> +		if (align)
> +			align = roundup_64(extsize, align);

			align = roundup(align, extsize);

>  		else
>  			align = extsize;
> -		new_last_fsb = roundup_64(*last_fsb, align);
>  	}
>  
> -	if (new_last_fsb) {
> +	if (align) {
> +		new_last_fsb = roundup_64(*last_fsb, align);

		xfs_fileoff_t	new_last_fsb = roundup_64(*last_fsb, align);

>  		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
>  		if (error)
>  			return error;

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] xfs: overflow in xfs_iomap_eof_align_last_fsb
  2014-11-24 19:06 [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb Peter Watkins
  2014-11-25 13:49 ` Brian Foster
  2014-11-25 23:18 ` Dave Chinner
@ 2014-12-01 22:45 ` Peter Watkins
  2014-12-02 16:24   ` Brian Foster
  2 siblings, 1 reply; 5+ messages in thread
From: Peter Watkins @ 2014-12-01 22:45 UTC (permalink / raw)
  To: xfs; +Cc: Peter Watkins

If extsize is set and new_last_fsb is larger than 32 bits, the
roundup to extsize will overflow the align variable. Instead,
combine alignments by rounding stripe size up to extsize.

Signed-off-by: Peter Watkins <treestem@gmail.com>
Reviewed-by: Nathaniel W. Turner <nate@houseofnate.net>
---
 fs/xfs/xfs_iomap.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index afcf3c9..3fad071 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -52,7 +52,6 @@ xfs_iomap_eof_align_last_fsb(
 	xfs_extlen_t	extsize,
 	xfs_fileoff_t	*last_fsb)
 {
-	xfs_fileoff_t	new_last_fsb = 0;
 	xfs_extlen_t	align = 0;
 	int		eof, error;
 
@@ -70,8 +69,8 @@ xfs_iomap_eof_align_last_fsb(
 		else if (mp->m_dalign)
 			align = mp->m_dalign;
 
-		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
-			new_last_fsb = roundup_64(*last_fsb, align);
+		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
+			align = 0;
 	}
 
 	/*
@@ -79,14 +78,14 @@ xfs_iomap_eof_align_last_fsb(
 	 * (when file on a real-time subvolume or has di_extsize hint).
 	 */
 	if (extsize) {
-		if (new_last_fsb)
-			align = roundup_64(new_last_fsb, extsize);
+		if (align)
+			align = roundup_64(align, extsize);
 		else
 			align = extsize;
-		new_last_fsb = roundup_64(*last_fsb, align);
 	}
 
-	if (new_last_fsb) {
+	if (align) {
+		xfs_fileoff_t	new_last_fsb = roundup_64(*last_fsb, align);
 		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
 		if (error)
 			return error;
-- 
1.7.9.5

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] xfs: overflow in xfs_iomap_eof_align_last_fsb
  2014-12-01 22:45 ` [PATCH v2] " Peter Watkins
@ 2014-12-02 16:24   ` Brian Foster
  0 siblings, 0 replies; 5+ messages in thread
From: Brian Foster @ 2014-12-02 16:24 UTC (permalink / raw)
  To: Peter Watkins; +Cc: xfs

On Mon, Dec 01, 2014 at 05:45:28PM -0500, Peter Watkins wrote:
> If extsize is set and new_last_fsb is larger than 32 bits, the
> roundup to extsize will overflow the align variable. Instead,
> combine alignments by rounding stripe size up to extsize.
> 
> Signed-off-by: Peter Watkins <treestem@gmail.com>
> Reviewed-by: Nathaniel W. Turner <nate@houseofnate.net>
> ---

Looks fine to me:

Reviewed-by: Brian Foster <bfoster@redhat.com>

>  fs/xfs/xfs_iomap.c |   13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index afcf3c9..3fad071 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -52,7 +52,6 @@ xfs_iomap_eof_align_last_fsb(
>  	xfs_extlen_t	extsize,
>  	xfs_fileoff_t	*last_fsb)
>  {
> -	xfs_fileoff_t	new_last_fsb = 0;
>  	xfs_extlen_t	align = 0;
>  	int		eof, error;
>  
> @@ -70,8 +69,8 @@ xfs_iomap_eof_align_last_fsb(
>  		else if (mp->m_dalign)
>  			align = mp->m_dalign;
>  
> -		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
> -			new_last_fsb = roundup_64(*last_fsb, align);
> +		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
> +			align = 0;
>  	}
>  
>  	/*
> @@ -79,14 +78,14 @@ xfs_iomap_eof_align_last_fsb(
>  	 * (when file on a real-time subvolume or has di_extsize hint).
>  	 */
>  	if (extsize) {
> -		if (new_last_fsb)
> -			align = roundup_64(new_last_fsb, extsize);
> +		if (align)
> +			align = roundup_64(align, extsize);
>  		else
>  			align = extsize;
> -		new_last_fsb = roundup_64(*last_fsb, align);
>  	}
>  
> -	if (new_last_fsb) {
> +	if (align) {
> +		xfs_fileoff_t	new_last_fsb = roundup_64(*last_fsb, align);
>  		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
>  		if (error)
>  			return error;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-12-02 16:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-24 19:06 [PATCH] xfs: overflow in xfs_iomap_eof_align_last_fsb Peter Watkins
2014-11-25 13:49 ` Brian Foster
2014-11-25 23:18 ` Dave Chinner
2014-12-01 22:45 ` [PATCH v2] " Peter Watkins
2014-12-02 16:24   ` Brian Foster

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox