[v2] xfs: store rmapbt block count in the AGF
diff mbox

Message ID 20160803214613.GF8593@birch.djwong.org
State Accepted
Headers show

Commit Message

Darrick J. Wong Aug. 3, 2016, 9:46 p.m. UTC
Track the number of blocks used for the rmapbt in the AGF.  When we
get to the AG reservation code we need this counter to quickly
make our reservation during mount.

v2: Actually include growfs support.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_alloc.c      |    1 +
 fs/xfs/libxfs/xfs_format.h     |   11 ++++++++---
 fs/xfs/libxfs/xfs_rmap_btree.c |    6 ++++++
 fs/xfs/xfs_fsops.c             |    1 +
 4 files changed, 16 insertions(+), 3 deletions(-)

Comments

Christoph Hellwig Aug. 4, 2016, 3:44 p.m. UTC | #1
On Wed, Aug 03, 2016 at 02:46:13PM -0700, Darrick J. Wong wrote:
> Track the number of blocks used for the rmapbt in the AGF.  When we
> get to the AG reservation code we need this counter to quickly
> make our reservation during mount.
> 
> v2: Actually include growfs support.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_alloc.c      |    1 +
>  fs/xfs/libxfs/xfs_format.h     |   11 ++++++++---
>  fs/xfs/libxfs/xfs_rmap_btree.c |    6 ++++++
>  fs/xfs/xfs_fsops.c             |    1 +
>  4 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 776ae2f..af1a72e 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2264,6 +2264,7 @@ xfs_alloc_log_agf(
>  		offsetof(xfs_agf_t, agf_longest),
>  		offsetof(xfs_agf_t, agf_btreeblks),
>  		offsetof(xfs_agf_t, agf_uuid),
> +		offsetof(xfs_agf_t, agf_rmap_blocks),
>  		sizeof(xfs_agf_t)
>  	};
>  
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index f814d42..e6a8bea 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -640,12 +640,15 @@ typedef struct xfs_agf {
>  	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
>  	uuid_t		agf_uuid;	/* uuid of filesystem */
>  
> +	__be32		agf_rmap_blocks;	/* rmapbt blocks used */
> +	__be32		agf_padding;		/* padding */

Now _spare?  It could easily be used by the next new field.

Otherwise this looks fine to me:

Reviewed-by: Christoph Hellwig <hch@lst.de>
Darrick J. Wong Aug. 4, 2016, 3:50 p.m. UTC | #2
On Thu, Aug 04, 2016 at 08:44:39AM -0700, Christoph Hellwig wrote:
> On Wed, Aug 03, 2016 at 02:46:13PM -0700, Darrick J. Wong wrote:
> > Track the number of blocks used for the rmapbt in the AGF.  When we
> > get to the AG reservation code we need this counter to quickly
> > make our reservation during mount.
> > 
> > v2: Actually include growfs support.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/libxfs/xfs_alloc.c      |    1 +
> >  fs/xfs/libxfs/xfs_format.h     |   11 ++++++++---
> >  fs/xfs/libxfs/xfs_rmap_btree.c |    6 ++++++
> >  fs/xfs/xfs_fsops.c             |    1 +
> >  4 files changed, 16 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> > index 776ae2f..af1a72e 100644
> > --- a/fs/xfs/libxfs/xfs_alloc.c
> > +++ b/fs/xfs/libxfs/xfs_alloc.c
> > @@ -2264,6 +2264,7 @@ xfs_alloc_log_agf(
> >  		offsetof(xfs_agf_t, agf_longest),
> >  		offsetof(xfs_agf_t, agf_btreeblks),
> >  		offsetof(xfs_agf_t, agf_uuid),
> > +		offsetof(xfs_agf_t, agf_rmap_blocks),
> >  		sizeof(xfs_agf_t)
> >  	};
> >  
> > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> > index f814d42..e6a8bea 100644
> > --- a/fs/xfs/libxfs/xfs_format.h
> > +++ b/fs/xfs/libxfs/xfs_format.h
> > @@ -640,12 +640,15 @@ typedef struct xfs_agf {
> >  	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
> >  	uuid_t		agf_uuid;	/* uuid of filesystem */
> >  
> > +	__be32		agf_rmap_blocks;	/* rmapbt blocks used */
> > +	__be32		agf_padding;		/* padding */
> 
> Now _spare?  It could easily be used by the next new field.

The reflink patches will (almost immediately) consume agf_padding
and the next spare for refcount_{root,level,blocks}.

--D

> Otherwise this looks fine to me:
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>

Patch
diff mbox

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 776ae2f..af1a72e 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2264,6 +2264,7 @@  xfs_alloc_log_agf(
 		offsetof(xfs_agf_t, agf_longest),
 		offsetof(xfs_agf_t, agf_btreeblks),
 		offsetof(xfs_agf_t, agf_uuid),
+		offsetof(xfs_agf_t, agf_rmap_blocks),
 		sizeof(xfs_agf_t)
 	};
 
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index f814d42..e6a8bea 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -640,12 +640,15 @@  typedef struct xfs_agf {
 	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
 	uuid_t		agf_uuid;	/* uuid of filesystem */
 
+	__be32		agf_rmap_blocks;	/* rmapbt blocks used */
+	__be32		agf_padding;		/* padding */
+
 	/*
 	 * reserve some contiguous space for future logged fields before we add
 	 * the unlogged fields. This makes the range logging via flags and
 	 * structure offsets much simpler.
 	 */
-	__be64		agf_spare64[16];
+	__be64		agf_spare64[15];
 
 	/* unlogged fields, written during buffer writeback. */
 	__be64		agf_lsn;	/* last write sequence */
@@ -670,7 +673,8 @@  typedef struct xfs_agf {
 #define	XFS_AGF_LONGEST		0x00000400
 #define	XFS_AGF_BTREEBLKS	0x00000800
 #define	XFS_AGF_UUID		0x00001000
-#define	XFS_AGF_NUM_BITS	13
+#define	XFS_AGF_RMAP_BLOCKS	0x00002000
+#define	XFS_AGF_NUM_BITS	14
 #define	XFS_AGF_ALL_BITS	((1 << XFS_AGF_NUM_BITS) - 1)
 
 #define XFS_AGF_FLAGS \
@@ -686,7 +690,8 @@  typedef struct xfs_agf {
 	{ XFS_AGF_FREEBLKS,	"FREEBLKS" }, \
 	{ XFS_AGF_LONGEST,	"LONGEST" }, \
 	{ XFS_AGF_BTREEBLKS,	"BTREEBLKS" }, \
-	{ XFS_AGF_UUID,		"UUID" }
+	{ XFS_AGF_UUID,		"UUID" }, \
+	{ XFS_AGF_RMAP_BLOCKS,	"RMAP_BLOCKS" }
 
 /* disk block (xfs_daddr_t) in the AG */
 #define XFS_AGF_DADDR(mp)	((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index bc1faeb..17b8eeb 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -98,6 +98,8 @@  xfs_rmapbt_alloc_block(
 	union xfs_btree_ptr	*new,
 	int			*stat)
 {
+	struct xfs_buf		*agbp = cur->bc_private.a.agbp;
+	struct xfs_agf		*agf = XFS_BUF_TO_AGF(agbp);
 	int			error;
 	xfs_agblock_t		bno;
 
@@ -124,6 +126,8 @@  xfs_rmapbt_alloc_block(
 
 	xfs_trans_agbtree_delta(cur->bc_tp, 1);
 	new->s = cpu_to_be32(bno);
+	be32_add_cpu(&agf->agf_rmap_blocks, 1);
+	xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS);
 
 	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
 	*stat = 1;
@@ -143,6 +147,8 @@  xfs_rmapbt_free_block(
 	bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp));
 	trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno,
 			bno, 1);
+	be32_add_cpu(&agf->agf_rmap_blocks, -1);
+	xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS);
 	error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1);
 	if (error)
 		return error;
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 0f96847..0b7f986 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -248,6 +248,7 @@  xfs_growfs_data_private(
 			agf->agf_roots[XFS_BTNUM_RMAPi] =
 						cpu_to_be32(XFS_RMAP_BLOCK(mp));
 			agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
+			agf->agf_rmap_blocks = cpu_to_be32(1);
 		}
 
 		agf->agf_flfirst = cpu_to_be32(1);