All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman
@ 2015-01-29 13:23 Dhruvesh Rathore
  2015-02-10  7:25 ` Dave Chinner
  0 siblings, 1 reply; 4+ messages in thread
From: Dhruvesh Rathore @ 2015-01-29 13:23 UTC (permalink / raw)
  To: xfs


The xfs_spaceman utility previously failed to account for AGFL blocks.
Old output (Before changes).

$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

As you can see the AGFL blocks were unaccounted (4 per AG, and there 
were 4 AGs in this filesystem).

This patch is concerned with adding a new function which will walk the free
extents in AGFL and account for these AGFL blocks, while file system scanning.

New output (After implementing this patch).

$ uname -a
Linux dhruv-MacBookAir 3.18.0-rc7+ #3 SMP Thu Dec 25 15:29:59 IST 2014 x86_64 x86_64 x86_64 GNU/Linux
$ sudo xfs_spaceman -V
xfs_spaceman version 3.2.2
$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
      1       1      16      16   0.00
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

-------------------------------------------------------------------------------------------

Signed-off-by: Dhruvesh Rathore <dhruvesh_r@outlook.com>
Signed-off-by: Amey Ruikar <ameyruikar@yahoo.com>
Signed-off-by: Somdeep Dey <somdeepdey10@gmail.com>
---
fs/xfs/libxfs/xfs_alloc.c | 69 ++++++++++++++++
1 file changed, 69 insertions(+)

--- a/fs/xfs/libxfs/xfs_alloc.c	2015-01-29 09:07:07.116439198 +0530
+++ b/fs/xfs/libxfs/xfs_alloc.c	2015-01-29 09:06:39.664440229 +0530

@@ -2698,6 +2698,71 @@
 }
 
 
+/*
+ * When we map free space we need to take into account the blocks
+ * that are indexed by the AGFL. They aren't found by walking the
+ * free space btrees, so we have to walk each AGFL to find them.
+ */
+static int
+xfs_alloc_agfl_freespace_map(
+	struct xfs_mount	*mp,
+	struct xfs_agf		*agf,
+	struct fiemap_extent_info *fieinfo,
+	xfs_agnumber_t		agno,
+	xfs_agblock_t		sagbno,
+	xfs_agblock_t		eagbno)
+{
+	xfs_buf_t		*agflbp;
+	__be32			*agfl_bno;
+	int			i;
+	int			error = 0;
+
+	error = xfs_alloc_read_agfl(mp, NULL, be32_to_cpu(agf->agf_seqno), &agflbp);
+
+	if (error)
+		return error;
+
+	agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
+
+	for(i = be32_to_cpu(agf->agf_flfirst);
+		i <= be32_to_cpu(agf->agf_fllast);) {
+
+		xfs_agblock_t	fbno;
+		xfs_extlen_t	flen;
+		xfs_daddr_t	dbno;
+		xfs_fileoff_t	dlen;	
+		int		flags = 0;
+
+		fbno = be32_to_cpu(agfl_bno[i]);
+		flen = 1;
+
+		/* range check - must be wholly withing requested range */
+		if (fbno < sagbno ||
+			(eagbno != NULLAGBLOCK && fbno + flen > eagbno)) {
+		xfs_warn(mp, "10: %d/%d, %d/%d", sagbno, eagbno, fbno, flen);
+			continue;
+		}
+
+		/*
+		 * Use daddr format for all range/len calculations as that is
+		 * the format the range/len variables are supplied in by
+		 * userspace.
+		 */
+
+		dbno = XFS_AGB_TO_DADDR(mp, agno, fbno);
+		dlen = XFS_FSB_TO_BB(mp, flen);
+
+		error = -fiemap_fill_next_extent(fieinfo,BBTOB(dbno),
+						BBTOB(dbno), BBTOB(dlen), flags);
+	
+		if (error)
+			break;
+		if (++i == XFS_AGFL_SIZE(mp))
+			i = 0;
+	}
+	xfs_buf_relse(agflbp);
+	return error;
+}
 
 /*
  * Map the freespace from the requested range in the requested order.
@@ -2804,6 +2869,10 @@
 		}
 		XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
 
+		/* Account for the free blocks in AGFL */
+		error = xfs_alloc_agfl_freespace_map(mp, XFS_BUF_TO_AGF(agbp), fieinfo, agno, sagbno,
+						agno == eagno ? eagbno : NULLAGBLOCK);
+
 		if (!bycnt) {
 			/*
 			 * if we are doing a bno ordered lookup, we can just

-------------------------------------------------------------------------------------------

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

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

* Re: [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman
  2015-01-29 13:23 [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman Dhruvesh Rathore
@ 2015-02-10  7:25 ` Dave Chinner
  2015-02-11 16:07   ` Dhruvesh Rathore
  0 siblings, 1 reply; 4+ messages in thread
From: Dave Chinner @ 2015-02-10  7:25 UTC (permalink / raw)
  To: Dhruvesh Rathore; +Cc: xfs

On Thu, Jan 29, 2015 at 06:53:01PM +0530, Dhruvesh Rathore wrote:
> 
> The xfs_spaceman utility previously failed to account for AGFL blocks.
> Old output (Before changes).
> 
> $ sudo xfs_spaceman -c "freesp" /media/xfs
>    from      to extents  blocks    pct
>    1024    2047       1    1262   0.04
>    4096    8191       1    5126   0.15
>    8192   16383       3   35344   1.05
>   32768   65535       1   43989   1.31
>  262144  524287       3 1334894  39.78
>  524288  967428       2 1934840  57.66
> 
> As you can see the AGFL blocks were unaccounted (4 per AG, and there 
> were 4 AGs in this filesystem).
> 
> This patch is concerned with adding a new function which will walk the free
> extents in AGFL and account for these AGFL blocks, while file system scanning.
> 
> New output (After implementing this patch).
> 
> $ uname -a
> Linux dhruv-MacBookAir 3.18.0-rc7+ #3 SMP Thu Dec 25 15:29:59 IST 2014 x86_64 x86_64 x86_64 GNU/Linux
> $ sudo xfs_spaceman -V
> xfs_spaceman version 3.2.2
> $ sudo xfs_spaceman -c "freesp" /media/xfs
>    from      to extents  blocks    pct
>       1       1      16      16   0.00
>    1024    2047       1    1262   0.04
>    4096    8191       1    5126   0.15
>    8192   16383       3   35344   1.05
>   32768   65535       1   43989   1.31
>  262144  524287       3 1334894  39.78
>  524288  967428       2 1934840  57.66
> 
Good description, but:

> -------------------------------------------------------------------------------------------

Tmhese lines confuse any utility that attempts to parse the patch.
Lines starting with "---" have have special meaning to patch. They
haven't come from diff or git, so you must have added them manually.

That makes me think you composed this email manually from a variety
of different sources.  Please, learn to use git to make your changes and
produce diffs that you send. git send-email is your friend - learn
to use it. There's a basic howto on the xfs web site:

http://xfs.org/index.php/XFS_git_howto

As such, I've hacked the patch into a format I can apply - I've
attached the patch generated from my git tree so you see how
different it looks.

> Signed-off-by: Dhruvesh Rathore <dhruvesh_r@outlook.com>
> Signed-off-by: Amey Ruikar <ameyruikar@yahoo.com>
> Signed-off-by: Somdeep Dey <somdeepdey10@gmail.com>
> ---
> fs/xfs/libxfs/xfs_alloc.c | 69 ++++++++++++++++
> 1 file changed, 69 insertions(+)
> 
> --- a/fs/xfs/libxfs/xfs_alloc.c	2015-01-29 09:07:07.116439198 +0530
> +++ b/fs/xfs/libxfs/xfs_alloc.c	2015-01-29 09:06:39.664440229 +0530
> 
> @@ -2698,6 +2698,71 @@
>  }
>  
>  
> +/*
> + * When we map free space we need to take into account the blocks
> + * that are indexed by the AGFL. They aren't found by walking the
> + * free space btrees, so we have to walk each AGFL to find them.
> + */
> +static int
> +xfs_alloc_agfl_freespace_map(
> +	struct xfs_mount	*mp,
> +	struct xfs_agf		*agf,
> +	struct fiemap_extent_info *fieinfo,
> +	xfs_agnumber_t		agno,
> +	xfs_agblock_t		sagbno,
> +	xfs_agblock_t		eagbno)
> +{
> +	xfs_buf_t		*agflbp;
> +	__be32			*agfl_bno;
> +	int			i;
> +	int			error = 0;
> +
> +	error = xfs_alloc_read_agfl(mp, NULL, be32_to_cpu(agf->agf_seqno), &agflbp);

Line longer than 80 columns, and the AG number we are working on is
passed as a parameter to the function so there is no need to read it
from the AGF.

> +

stray extra line.

> +	if (error)
> +		return error;
> +
> +	agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
> +
> +	for(i = be32_to_cpu(agf->agf_flfirst);
> +		i <= be32_to_cpu(agf->agf_fllast);) {

Whitespace after the "for" statement, and indentation of logic inside
for/if/while/etc needs to be aligned to the same column.

As it is, this code doesn't work. Hint: what happens when last wraps
around back to the start ofthe freelist array? last < first, and
hence i > last....

Yes, I know it the code is similar to what I suggested last time I
pointed out the iteration is wrong, but I'm often wrong, especially
about intricate details that I've just quickly pulled a solution for
off the top of my head.  IOWs, don't assume what I say is correct -
verifiy and test it, and then tell me I'm wrong.

So, perhaps a different loop structure is appropriate?

> +
> +		xfs_agblock_t	fbno;
> +		xfs_extlen_t	flen;
> +		xfs_daddr_t	dbno;
> +		xfs_fileoff_t	dlen;	

Trailing whitespace.

> +		int		flags = 0;
> +
> +		fbno = be32_to_cpu(agfl_bno[i]);
> +		flen = 1;
> +
> +		/* range check - must be wholly withing requested range */
> +		if (fbno < sagbno ||
> +			(eagbno != NULLAGBLOCK && fbno + flen > eagbno)) {
> +		xfs_warn(mp, "10: %d/%d, %d/%d", sagbno, eagbno, fbno, flen);
> +			continue;

Indentation:
		if (fbno < sagbno ||
		    (eagbno != NULLAGBLOCK && fbno + flen > eagbno)) {
			xfs_warn(mp, "10: %d/%d, %d/%d",
				 sagbno, eagbno, fbno, flen);

> +		}
> +
> +		/*
> +		 * Use daddr format for all range/len calculations as that is
> +		 * the format the range/len variables are supplied in by
> +		 * userspace.
> +		 */
> +
> +		dbno = XFS_AGB_TO_DADDR(mp, agno, fbno);
> +		dlen = XFS_FSB_TO_BB(mp, flen);
> +
> +		error = -fiemap_fill_next_extent(fieinfo,BBTOB(dbno),
> +						BBTOB(dbno), BBTOB(dlen), flags);

We don't need to negate the error any more, also whitespace after
fieinfo.

> +	

Stray whitespace in a stray line..

> +		if (error)
> +			break;
> +		if (++i == XFS_AGFL_SIZE(mp))
> +			i = 0;
> +	}
> +	xfs_buf_relse(agflbp);
> +	return error;
> +}
>  
>  /*
>   * Map the freespace from the requested range in the requested order.
> @@ -2804,6 +2869,10 @@
>  		}
>  		XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
>  
> +		/* Account for the free blocks in AGFL */
> +		error = xfs_alloc_agfl_freespace_map(mp, XFS_BUF_TO_AGF(agbp), fieinfo, agno, sagbno,
> +						agno == eagno ? eagbno : NULLAGBLOCK);
> +

Line is much longer than 80 columns. checkpatch will catch trivial
things like whitespace and line length....

Also, if there is an error, we need to handle it appropriately.

Patch as applied to my tree is below. Please apply it to your tree
and test it.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

xfs: Accounting for AGFL blocks in xfs_spaceman

From: Dhruvesh Rathore <adrscube@gmail.com>

The xfs_spaceman utility previously failed to account for AGFL
blocks.  Old output:

$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

As you can see the AGFL blocks were unaccounted (4 per AG, and there
were 4 AGs in this filesystem).  This patch adds a new function
which accounts for the the free extents tracked by the AGFL.

New output:

$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
      1       1      16      16   0.00
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

[dchinner: fixed whitespace issues, agfl iteration logic,
	   error handling]

Signed-off-by: Dhruvesh Rathore <dhruvesh_r@outlook.com>
Signed-off-by: Amey Ruikar <ameyruikar@yahoo.com>
Signed-off-by: Somdeep Dey <somdeepdey10@gmail.com>

---
 fs/xfs/libxfs/xfs_alloc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 1ae53ad..544c945 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2633,6 +2633,68 @@ error0:
 }
 
 /*
+ * When we map free space we need to take into account the blocks
+ * that are indexed by the AGFL. They aren't found by walking the
+ * free space btrees, so we have to walk each AGFL to find them.
+ */
+static int
+xfs_alloc_agfl_freespace_map(
+	struct xfs_mount	*mp,
+	struct xfs_agf		*agf,
+	struct fiemap_extent_info *fieinfo,
+	xfs_agnumber_t		agno,
+	xfs_agblock_t		sagbno,
+	xfs_agblock_t		eagbno)
+{
+	xfs_buf_t		*agflbp;
+	__be32			*agfl_bno;
+	int			i;
+	int			error = 0;
+
+	error = xfs_alloc_read_agfl(mp, NULL, agno, &agflbp);
+	if (error)
+		return error;
+
+	agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
+	for (i = be32_to_cpu(agf->agf_flfirst);;) {
+		xfs_agblock_t	fbno;
+		xfs_extlen_t	flen;
+		xfs_daddr_t	dbno;
+		xfs_fileoff_t	dlen;
+		int		flags = 0;
+
+		fbno = be32_to_cpu(agfl_bno[i]);
+		flen = 1;
+
+		/* range check - must be wholly withing requested range */
+		if (fbno < sagbno ||
+		    (eagbno != NULLAGBLOCK && fbno + flen > eagbno)) {
+			xfs_warn(mp, "10: %d/%d, %d/%d",
+				 sagbno, eagbno, fbno, flen);
+			continue;
+		}
+
+		/*
+		 * Use daddr format for all range/len calculations as that is
+		 * the format the range/len variables are supplied in by
+		 * userspace.
+		 */
+		dbno = XFS_AGB_TO_DADDR(mp, agno, fbno);
+		dlen = XFS_FSB_TO_BB(mp, flen);
+		error = fiemap_fill_next_extent(fieinfo, BBTOB(dbno),
+						BBTOB(dbno), BBTOB(dlen), flags);
+		if (error)
+			break;
+		if (i == be32_to_cpu(agf->agf_fllast))
+			break;
+		if (++i == XFS_AGFL_SIZE(mp))
+			i = 0;
+	}
+	xfs_buf_relse(agflbp);
+	return error;
+}
+
+/*
  * Walk the extents in the tree given by the cursor, and dump them all into the
  * fieinfo. At the last extent in the tree, set the FIEMAP_EXTENT_LAST flag so
  * that we return only free space from this tree in a given request.
@@ -2793,6 +2855,13 @@ xfs_alloc_freespace_map(
 			goto put_agbp;
 		}
 
+		/* Account for the free blocks in AGFL */
+		error = xfs_alloc_agfl_freespace_map(mp, XFS_BUF_TO_AGF(agbp),
+					fieinfo, agno, sagbno,
+					agno == eagno ? eagbno : NULLAGBLOCK);
+		if (error)
+			goto put_agbp;
+
 		cur = xfs_allocbt_init_cursor(mp, NULL, agbp, agno,
 					      XFS_BTNUM_BNO);
 		error = xfs_alloc_lookup_ge(cur, sagbno, 1, &i);

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

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

* Re: [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman
  2015-02-10  7:25 ` Dave Chinner
@ 2015-02-11 16:07   ` Dhruvesh Rathore
  0 siblings, 0 replies; 4+ messages in thread
From: Dhruvesh Rathore @ 2015-02-11 16:07 UTC (permalink / raw)
  To: xfs

>> +     if (error)
>> +             return error;
>> +
>> +     agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
>> +
>> +     for(i = be32_to_cpu(agf->agf_flfirst);
>> +             i <= be32_to_cpu(agf->agf_fllast);) {
>
> Whitespace after the "for" statement, and indentation of logic inside
> for/if/while/etc needs to be aligned to the same column.
>
> As it is, this code doesn't work. Hint: what happens when last wraps
> around back to the start ofthe freelist array? last < first, and
> hence i > last....
>
> Yes, I know it the code is similar to what I suggested last time I
> pointed out the iteration is wrong, but I'm often wrong, especially
> about intricate details that I've just quickly pulled a solution for
> off the top of my head.  IOWs, don't assume what I say is correct -
> verifiy and test it, and then tell me I'm wrong.
>
> So, perhaps a different loop structure is appropriate?

We had addressed this issue in the previous code version, but
changed it when a doubt was raised in the previous patch comments.
We will ensure that we verify and test the feedback we receive from
now on. :)

> Patch as applied to my tree is below. Please apply it to your tree
> and test it.
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com
>
> xfs: Accounting for AGFL blocks in xfs_spaceman
>
> From: Dhruvesh Rathore <adrscube@gmail.com>
>
> The xfs_spaceman utility previously failed to account for AGFL
> blocks.  Old output:
>
> $ sudo xfs_spaceman -c "freesp" /media/xfs
>    from      to extents  blocks    pct
>    1024    2047       1    1262   0.04
>    4096    8191       1    5126   0.15
>    8192   16383       3   35344   1.05
>   32768   65535       1   43989   1.31
>  262144  524287       3 1334894  39.78
>  524288  967428       2 1934840  57.66
>
> As you can see the AGFL blocks were unaccounted (4 per AG, and there
> were 4 AGs in this filesystem).  This patch adds a new function
> which accounts for the the free extents tracked by the AGFL.
>
> New output:
>
> $ sudo xfs_spaceman -c "freesp" /media/xfs
>    from      to extents  blocks    pct
>       1       1      16      16   0.00
>    1024    2047       1    1262   0.04
>    4096    8191       1    5126   0.15
>    8192   16383       3   35344   1.05
>   32768   65535       1   43989   1.31
>  262144  524287       3 1334894  39.78
>  524288  967428       2 1934840  57.66
>
> [dchinner: fixed whitespace issues, agfl iteration logic,
>            error handling]
>
> Signed-off-by: Dhruvesh Rathore <dhruvesh_r@outlook.com>
> Signed-off-by: Amey Ruikar <ameyruikar@yahoo.com>
> Signed-off-by: Somdeep Dey <somdeepdey10@gmail.com>
>
> ---
>  fs/xfs/libxfs/xfs_alloc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
>
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 1ae53ad..544c945 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2633,6 +2633,68 @@ error0:
>  }
>
>  /*
> + * When we map free space we need to take into account the blocks
> + * that are indexed by the AGFL. They aren't found by walking the
> + * free space btrees, so we have to walk each AGFL to find them.
> + */
> +static int
> +xfs_alloc_agfl_freespace_map(
> +       struct xfs_mount        *mp,
> +       struct xfs_agf          *agf,
> +       struct fiemap_extent_info *fieinfo,
> +       xfs_agnumber_t          agno,
> +       xfs_agblock_t           sagbno,
> +       xfs_agblock_t           eagbno)
> +{
> +       xfs_buf_t               *agflbp;
> +       __be32                  *agfl_bno;
> +       int                     i;
> +       int                     error = 0;
> +
> +       error = xfs_alloc_read_agfl(mp, NULL, agno, &agflbp);
> +       if (error)
> +               return error;
> +
> +       agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
> +       for (i = be32_to_cpu(agf->agf_flfirst);;) {
> +               xfs_agblock_t   fbno;
> +               xfs_extlen_t    flen;
> +               xfs_daddr_t     dbno;
> +               xfs_fileoff_t   dlen;
> +               int             flags = 0;
> +
> +               fbno = be32_to_cpu(agfl_bno[i]);
> +               flen = 1;
> +
> +               /* range check - must be wholly withing requested range */
> +               if (fbno < sagbno ||
> +                   (eagbno != NULLAGBLOCK && fbno + flen > eagbno)) {
> +                       xfs_warn(mp, "10: %d/%d, %d/%d",
> +                                sagbno, eagbno, fbno, flen);
> +                       continue;
> +               }
> +
> +               /*
> +                * Use daddr format for all range/len calculations as that is
> +                * the format the range/len variables are supplied in by
> +                * userspace.
> +                */
> +               dbno = XFS_AGB_TO_DADDR(mp, agno, fbno);
> +               dlen = XFS_FSB_TO_BB(mp, flen);
> +               error = fiemap_fill_next_extent(fieinfo, BBTOB(dbno),
> +                                               BBTOB(dbno), BBTOB(dlen), flags);
> +               if (error)
> +                       break;
> +               if (i == be32_to_cpu(agf->agf_fllast))
> +                       break;
> +               if (++i == XFS_AGFL_SIZE(mp))
> +                       i = 0;
> +       }
> +       xfs_buf_relse(agflbp);
> +       return error;
> +}
> +
> +/*
>   * Walk the extents in the tree given by the cursor, and dump them all into the
>   * fieinfo. At the last extent in the tree, set the FIEMAP_EXTENT_LAST flag so
>   * that we return only free space from this tree in a given request.
> @@ -2793,6 +2855,13 @@ xfs_alloc_freespace_map(
>                         goto put_agbp;
>                 }
>
> +               /* Account for the free blocks in AGFL */
> +               error = xfs_alloc_agfl_freespace_map(mp, XFS_BUF_TO_AGF(agbp),
> +                                       fieinfo, agno, sagbno,
> +                                       agno == eagno ? eagbno : NULLAGBLOCK);
> +               if (error)
> +                       goto put_agbp;
> +
>                 cur = xfs_allocbt_init_cursor(mp, NULL, agbp, agno,
>                                               XFS_BTNUM_BNO);
>                 error = xfs_alloc_lookup_ge(cur, sagbno, 1, &i);
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

We thank you for taking the time out and working on the patches. We will
apply the above reworked patch and test it, and get back to you.

Regards,
A-DRS

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

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

* [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman
@ 2015-01-28 14:33 Dhruvesh Rathore
  0 siblings, 0 replies; 4+ messages in thread
From: Dhruvesh Rathore @ 2015-01-28 14:33 UTC (permalink / raw)
  To: xfs


The xfs_spaceman utility previously failed to account for AGFL blocks.
Old output (Before changes).

$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

As you can see the AGFL blocks were unaccounted (4 per AG, and there 
were 4 AGs in this filesystem).

This patch is concerned with adding a new function which will walk the free
extents in AGFL and account for these AGFL blocks, while file system scanning.

New output (After implementing this patch).

$ uname -a
Linux dhruv-MacBookAir 3.18.0-rc7+ #3 SMP Thu Dec 25 15:29:59 IST 2014 x86_64 x86_64 x86_64 GNU/Linux
$ sudo xfs_spaceman -V
xfs_spaceman version 3.2.2
$ sudo xfs_spaceman -c "freesp" /media/xfs
   from      to extents  blocks    pct
      1       1      16      16   0.00
   1024    2047       1    1262   0.04
   4096    8191       1    5126   0.15
   8192   16383       3   35344   1.05
  32768   65535       1   43989   1.31
 262144  524287       3 1334894  39.78
 524288  967428       2 1934840  57.66

-------------------------------------------------------------------------------------------

Signed-off-by: Dhruvesh Rathore <dhruvesh_r@outlook.com>
Signed-off-by: Amey Ruikar <ameyruikar@yahoo.com>
Signed-off-by: Somdeep Dey <somdeepdey10@gmail.com>
---
fs/xfs/libxfs/xfs_alloc.c | 53 ++++++++++++++
1 file changed, 53 insertions(+)

--- a/fs/xfs/libxfs/xfs_alloc.c	2015-01-28 15:25:02.396172903 +0530
+++ b/fs/xfs/libxfs/xfs_alloc.c	2015-01-28 15:13:46.936198272 +0530

@@ -2697,6 +2697,56 @@
 
 }
 
+/*
+ * When we map free space we need to take into account the blocks
+ * that are indexed by the AGFL. They aren't found by walking the
+ * free space btrees, so we have to walk each AGFL to find them.
+ */
+static int
+xfs_alloc_agfl_freespace_map(
+	struct xfs_mount	*mp,
+	struct xfs_agf		*agf,
+	struct fiemap_extent_info *fieinfo,
+	xfs_agnumber_t		agno)
+{
+	xfs_buf_t		*agflbp;
+	__be32			*agfl_bno;
+	int			i;
+	int			error = 0;
+
+	error = xfs_alloc_read_agfl(mp, NULL, be32_to_cpu(agf->agf_seqno), &agflbp);
+
+	if (error)
+		return error;
+
+	agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
+
+	for(i = be32_to_cpu(agf->agf_flfirst);
+		i <= be32_to_cpu(agf->agf_fllast);) {
+
+		xfs_daddr_t	dbno;
+		xfs_fileoff_t	dlen;	
+		int		flags = 0;
+
+		/*
+		 * Use daddr format for all range/len calculations as that is
+		 * the format the range/len variables are supplied in by
+		 * userspace.
+		 */
+
+		dbno = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(agfl_bno[i]));
+		dlen = XFS_FSB_TO_BB(mp, 1);
+
+		error = -fiemap_fill_next_extent(fieinfo,BBTOB(dbno),
+						BBTOB(dbno), BBTOB(dlen), flags);
+		if (error)
+			break;
+		if (++i == XFS_AGFL_SIZE(mp))
+			i = 0;
+	}
+	xfs_buf_relse(agflbp);
+	return error;
+}
 
 /*
  * Map the freespace from the requested range in the requested order.
@@ -2803,6 +2853,9 @@
 		}
 		XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
 
+		/* Account for the free blocks in AGFL */
+		error = xfs_alloc_agfl_freespace_map(mp, XFS_BUF_TO_AGF(agbp), fieinfo, agno);
+
 		if (!bycnt) {
 			/*
 			 * if we are doing a bno ordered lookup, we can just

-------------------------------------------------------------------------------------------

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

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

end of thread, other threads:[~2015-02-11 16:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-29 13:23 [PATCH 1/4] xfs: Accounting for AGFL blocks in xfs_spaceman Dhruvesh Rathore
2015-02-10  7:25 ` Dave Chinner
2015-02-11 16:07   ` Dhruvesh Rathore
  -- strict thread matches above, loose matches on Subject: below --
2015-01-28 14:33 Dhruvesh Rathore

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.