public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Alain Renaud <arenaud@sgi.com>
To: xfs@oss.sgi.com
Subject: [PATCH V3] xfs: prevent xfs_bmapi_write() to exceed maximum extent size.
Date: Thu, 23 Aug 2012 12:52:33 -0400	[thread overview]
Message-ID: <50365FD1.7000304@sgi.com> (raw)
In-Reply-To: <5009112D.4090106@sgi.com>


[-- Attachment #1.1: Type: text/plain, Size: 3021 bytes --]

xfs: prevent xfs_bmapi_write() to exceed maximum extent size.


When trying to do preallocation that exceed the the maximum size of
an extent, the extsize alignment can exceed the MAXEXTLEN.

We are already solving this issue for delay allocation but we
have the same with prealloc. So the Solution is to limit the bma.length
we send to xfs_bmapi_allocate() in xfs_bmapi_write().

We do have a simple test case to confirm that the problem exist.

# mkfs.xfs -f -b size=512 -d agcount=1,size=4294967296  /dev/sdb1
meta-data=/dev/sdb1              isize=256    agcount=1, agsize=8388608 blks
          =                       sectsz=512   attr=2, projid32bit=0
data     =                       bsize=512    blocks=8388608, imaxpct=25
          =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=512    blocks=20480, version=2
          =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
# mount /dev/sdb1 /xfs_dir
# cd/xfs_dir/
# xfs_io -c 'extsize 4m' .
# xfs_io -f -c 'resvsp 0 1g' test_file
XFS_IOC_RESVSP64: No space left on device

Signed-off-by: Alain Renaud<arenaud@sgi.com>

---
    This is the 3rd version of the patch. In the previous version we were
making the change in xfs_bmap_extsize_align() but like Dave mention
we were breaking the function definition.

    Limiting the length in xfs_bmapi_write() seem more logical and should
avoid any unexpected side effect.

  fs/xfs/xfs_bmap.c |   27 ++++++++++++++++-----------
  1 file changed, 16 insertions(+), 11 deletions(-)

Index: b/fs/xfs/xfs_bmap.c
===================================================================
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4915,22 +4915,27 @@ xfs_bmapi_write(
  		 * that we found, if any.
  		 */
  		if (inhole || wasdelay) {
+			xfs_extlen_t	extsz;
  			bma.eof = eof;
  			bma.conv = !!(flags & XFS_BMAPI_CONVERT);
  			bma.wasdel = wasdelay;
  			bma.offset = bno;
  
-			/*
-			 * There's a 32/64 bit type mismatch between the
-			 * allocation length request (which can be 64 bits in
-			 * length) and the bma length request, which is
-			 * xfs_extlen_t and therefore 32 bits. Hence we have to
-			 * check for 32-bit overflows and handle them here.
-			 */
-			if (len > (xfs_filblks_t)MAXEXTLEN)
-				bma.length = MAXEXTLEN;
-			else
-				bma.length = len;
+			/* Figure out the extent size, set bma.length */
+			extsz = xfs_get_extsz_hint(ip);
+			if (extsz) {
+				/*
+				 * Make sure we don't exceed the maximum extent
+				 * length when we align the extent.  Reduce the
+				 * length we are going to allocate by the
+				 * maximum adjustment extent size aligment may
+				 * require.
+				 */
+				bma.length = XFS_FILBLKS_MIN(len,
+					     MAXEXTLEN - (2 * extsz - 1));
+			} else {
+				bma.length = XFS_FILBLKS_MIN(len, MAXEXTLEN);
+			}
  
  			ASSERT(len > 0);
  			ASSERT(bma.length > 0);


Alain Renaud


[-- Attachment #1.2: Type: text/html, Size: 3523 bytes --]

[-- Attachment #2: xfs:avoid_bmap_len_overflow_xfs_bmap_extsize_align.patch --]
[-- Type: text/x-patch, Size: 2926 bytes --]

When trying to do preallocation that exceed the the maximum size of
an extent, the extsize alignment can exceed the MAXEXTLEN. 

We are already solving this issue for delay allocation but we
have the same with prealloc. So the Solution is to limit the bma.length
we send to xfs_bmapi_allocate() in xfs_bmapi_write().

We do have a simple test case to confirm that the problem exist.

# mkfs.xfs -f -b size=512 -d agcount=1,size=4294967296  /dev/sdb1
meta-data=/dev/sdb1              isize=256    agcount=1, agsize=8388608 blks
         =                       sectsz=512   attr=2, projid32bit=0
data     =                       bsize=512    blocks=8388608, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=512    blocks=20480, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
# mount /dev/sdb1 /xfs_dir
# cd /xfs_dir/
# xfs_io -c 'extsize 4m' .
# xfs_io -f -c 'resvsp 0 1g' test_file
XFS_IOC_RESVSP64: No space left on device

Signed-off-by: Alain Renaud <arenaud@sgi.com>

---
   This is the 3rd version of the patch. In the previous version we were
making the change in xfs_bmap_extsize_align() but like Dave mention
we were breaking the function definition.

   Limiting the length in xfs_bmapi_write() seem more logical and should
avoid any unexpected side effect.

 fs/xfs/xfs_bmap.c |   27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

Index: b/fs/xfs/xfs_bmap.c
===================================================================
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4915,22 +4915,27 @@ xfs_bmapi_write(
 		 * that we found, if any.
 		 */
 		if (inhole || wasdelay) {
+			xfs_extlen_t	extsz;
 			bma.eof = eof;
 			bma.conv = !!(flags & XFS_BMAPI_CONVERT);
 			bma.wasdel = wasdelay;
 			bma.offset = bno;
 
-			/*
-			 * There's a 32/64 bit type mismatch between the
-			 * allocation length request (which can be 64 bits in
-			 * length) and the bma length request, which is
-			 * xfs_extlen_t and therefore 32 bits. Hence we have to
-			 * check for 32-bit overflows and handle them here.
-			 */
-			if (len > (xfs_filblks_t)MAXEXTLEN)
-				bma.length = MAXEXTLEN;
-			else
-				bma.length = len;
+			/* Figure out the extent size, set bma.length */
+			extsz = xfs_get_extsz_hint(ip);
+			if (extsz) {
+				/*
+				 * Make sure we don't exceed the maximum extent
+				 * length when we align the extent.  Reduce the
+				 * length we are going to allocate by the
+				 * maximum adjustment extent size aligment may
+				 * require.
+				 */
+				bma.length = XFS_FILBLKS_MIN(len,
+					     MAXEXTLEN - (2 * extsz - 1));
+			} else {
+				bma.length = XFS_FILBLKS_MIN(len, MAXEXTLEN);
+			}
 
 			ASSERT(len > 0);
 			ASSERT(bma.length > 0);

[-- Attachment #3: Type: text/plain, Size: 121 bytes --]

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

      reply	other threads:[~2012-08-23 16:51 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20120712154554.377970666@sgi.com>
2012-07-13 10:09 ` [PATCH] xfs: prevent xfs_bmap_extsize_align() to exceed maximum extent size Alain Renaud
2012-07-17 16:35   ` [PATCH V2] " Alain Renaud
2012-07-19  3:30     ` Dave Chinner
2012-07-19  8:20       ` Alain Renaud
2012-07-20  1:44         ` Dave Chinner
2012-07-20  8:05           ` Alain Renaud
2012-08-23 16:52             ` Alain Renaud [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50365FD1.7000304@sgi.com \
    --to=arenaud@sgi.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox