diff mbox series

[4/4] xfs: use accessor functions for summary info words

Message ID 169759504247.3396240.12544584850393209864.stgit@frogsfrogsfrogs (mailing list archive)
State Superseded, archived
Headers show
Series xfs: refactor rtbitmap/summary accessors | expand

Commit Message

Darrick J. Wong Oct. 18, 2023, 2:10 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Create get and set functions for rtsummary words so that we can redefine
the ondisk format with a specific endianness.  Note that this requires
the definition of a distinct type for ondisk summary info words so that
the compiler can perform proper typechecking.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_format.h   |    8 ++++++++
 fs/xfs/libxfs/xfs_rtbitmap.c |   15 ++++++++-------
 fs/xfs/libxfs/xfs_rtbitmap.h |   28 ++++++++++++++++++++++++++--
 fs/xfs/scrub/rtsummary.c     |   30 +++++++++++++++++++++---------
 fs/xfs/scrub/trace.c         |    1 +
 fs/xfs/scrub/trace.h         |   10 +++++-----
 fs/xfs/xfs_ondisk.h          |    1 +
 7 files changed, 70 insertions(+), 23 deletions(-)

Comments

Christoph Hellwig Oct. 18, 2023, 5:19 a.m. UTC | #1
On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> +static inline union xfs_suminfo_raw *
>  xfs_rsumblock_infoptr(
>  	struct xfs_buf		*bp,
>  	unsigned int		index)
>  {
> -	xfs_suminfo_t		*info = bp->b_addr;
> +	union xfs_suminfo_raw	*info = bp->b_addr;
>  
>  	return info + index;
>  }
>  
> +/* Get the current value of a summary counter. */
> +static inline xfs_suminfo_t
> +xfs_suminfo_get(
> +	struct xfs_buf		*bp,
> +	unsigned int		index)
> +{
> +	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(bp, index);
> +
> +	return info->old;
> +}

Same nitpick as for the bitmap version.

Otherwise this looks good:

Signed-off-by: Christoph Hellwig <hch@lst.de>


... to actually understand the mess in xfs_rtmodify_summary_int I had
to do the (untested) refactoring below.  I'll probably resubmit it after
the whole series which touches a lot of this:


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 2118c6f177a135..7b09caa747a720 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
  * Summary information is returned in *sum if specified.
  * If no delta is specified, returns summary only.
  */
-int
-xfs_rtmodify_summary_int(
+static int
+xfs_rtmodify_summary_find(
 	xfs_mount_t	*mp,		/* file system mount structure */
 	xfs_trans_t	*tp,		/* transaction pointer */
 	int		log,		/* log2 of extent size */
 	xfs_fileoff_t	bbno,		/* bitmap block number */
-	int		delta,		/* change to make to summary info */
 	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
 	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
-	xfs_suminfo_t	*sum)		/* out: summary info for this block */
+	unsigned int	*word)
 {
 	struct xfs_buf	*bp;		/* buffer for the summary block */
 	int		error;		/* error value */
-	xfs_fileoff_t	sb;		/* summary fsblock */
 	xfs_rtsumoff_t	so;		/* index into the summary file */
+	xfs_fileoff_t	sb;		/* summary fsblock */
 
 	/*
 	 * Compute entry number in the summary file.
 	 */
 	so = xfs_rtsumoffs(mp, log, bbno);
+
 	/*
 	 * Compute the block number in the summary file.
 	 */
 	sb = xfs_rtsumoffs_to_block(mp, so);
+
+	/*
+	 * Compute the word index into the summary.
+	 */
+	*word = xfs_rtsumoffs_to_infoword(mp, so);
+
 	/*
 	 * If we have an old buffer, and the block number matches, use that.
 	 */
 	if (*rbpp && *rsb == sb)
-		bp = *rbpp;
+		return 0;
+
 	/*
-	 * Otherwise we have to get the buffer.
+	 * Otherwise we have to get a new buffer.
+	 * If there was an old one, get rid of it first.
 	 */
-	else {
-		/*
-		 * If there was an old one, get rid of it first.
-		 */
-		if (*rbpp)
-			xfs_trans_brelse(tp, *rbpp);
-		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
-		if (error) {
-			return error;
-		}
-		/*
-		 * Remember this buffer and block for the next call.
-		 */
-		*rbpp = bp;
-		*rsb = sb;
-	}
+	if (*rbpp)
+		xfs_trans_brelse(tp, *rbpp);
+	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
+	if (error)
+		return error;
+
 	/*
-	 * Point to the summary information, modify/log it, and/or copy it out.
+	 * Remember this buffer and block for the next call.
 	 */
-	if (delta) {
-		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
-		xfs_suminfo_t	val = xfs_suminfo_add(bp, infoword, delta);
-
-		if (mp->m_rsum_cache) {
-			if (val == 0 && log == mp->m_rsum_cache[bbno])
-				mp->m_rsum_cache[bbno]++;
-			if (val != 0 && log < mp->m_rsum_cache[bbno])
-				mp->m_rsum_cache[bbno] = log;
-		}
-		xfs_trans_log_rtsummary(tp, bp, infoword);
-		if (sum)
-			*sum = val;
-	} else if (sum) {
-		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
-
-		*sum = xfs_suminfo_get(bp, infoword);
-	}
+	*rbpp = bp;
+	*rsb = sb;
 	return 0;
 }
 
+/*
+ * Read and/or modify the summary information for a given extent size,
+ * bitmap block combination.
+ * Keeps track of a current summary block, so we don't keep reading
+ * it from the buffer cache.
+ *
+ * Summary information is returned in *sum if specified.
+ * If no delta is specified, returns summary only.
+ */
 int
 xfs_rtmodify_summary(
 	xfs_mount_t	*mp,		/* file system mount structure */
@@ -515,8 +506,51 @@ xfs_rtmodify_summary(
 	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
 	xfs_fileoff_t	*rsb)		/* in/out: summary block number */
 {
-	return xfs_rtmodify_summary_int(mp, tp, log, bbno,
-					delta, rbpp, rsb, NULL);
+	int		error;
+	unsigned int	word;
+	xfs_suminfo_t	val;
+
+	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
+	if (error)
+		return error;
+
+	/*
+	 * Modify and log the summary information.
+	 */
+	val = xfs_suminfo_add(*rbpp, word, delta);
+	if (mp->m_rsum_cache) {
+		if (val == 0 && log == mp->m_rsum_cache[bbno])
+			mp->m_rsum_cache[bbno]++;
+		if (val != 0 && log < mp->m_rsum_cache[bbno])
+			mp->m_rsum_cache[bbno] = log;
+	}
+	xfs_trans_log_rtsummary(tp, *rbpp, word);
+	return 0;
+}
+
+/*
+ * Read and return the summary information for a given extent size,
+ * bitmap block combination.
+ * Keeps track of a current summary block, so we don't keep reading
+ * it from the buffer cache.
+ */
+int
+xfs_rtget_summary(
+	xfs_mount_t	*mp,		/* file system mount structure */
+	xfs_trans_t	*tp,		/* transaction pointer */
+	int		log,		/* log2 of extent size */
+	xfs_fileoff_t	bbno,		/* bitmap block number */
+	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
+	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
+	xfs_suminfo_t	*sum)		/* out: summary info for this block */
+{
+	int		error;
+	unsigned int	word;
+
+	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
+	if (!error)
+		*sum = xfs_suminfo_get(*rbpp, word);
+	return error;
 }
 
 /* Log rtbitmap block from the word @from to the byte before @next. */
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index fdfa98e0ee52f7..6d23a77def50dd 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
 		    xfs_rtxnum_t *rtblock);
 int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
 		       xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
-int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
-			     int log, xfs_fileoff_t bbno, int delta,
-			     struct xfs_buf **rbpp, xfs_fileoff_t *rsb,
-			     xfs_suminfo_t *sum);
 int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
 			 xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
 			 xfs_fileoff_t *rsb);
+int xfs_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
+		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
+		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
 int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
 		     xfs_rtxnum_t start, xfs_rtxlen_t len,
 		     struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 3be6bda2fd920c..22bc8b3b724a5b 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -21,25 +21,6 @@
 #include "xfs_sb.h"
 #include "xfs_rtbitmap.h"
 
-/*
- * Read and return the summary information for a given extent size,
- * bitmap block combination.
- * Keeps track of a current summary block, so we don't keep reading
- * it from the buffer cache.
- */
-static int
-xfs_rtget_summary(
-	xfs_mount_t	*mp,		/* file system mount structure */
-	xfs_trans_t	*tp,		/* transaction pointer */
-	int		log,		/* log2 of extent size */
-	xfs_fileoff_t	bbno,		/* bitmap block number */
-	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
-	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
-	xfs_suminfo_t	*sum)		/* out: summary info for this block */
-{
-	return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum);
-}
-
 /*
  * Return whether there are any free extents in the size range given
  * by low and high, for the bitmap block bbno.
Darrick J. Wong Oct. 18, 2023, 5:31 a.m. UTC | #2
On Wed, Oct 18, 2023 at 07:19:34AM +0200, Christoph Hellwig wrote:
> On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> > +static inline union xfs_suminfo_raw *
> >  xfs_rsumblock_infoptr(
> >  	struct xfs_buf		*bp,
> >  	unsigned int		index)
> >  {
> > -	xfs_suminfo_t		*info = bp->b_addr;
> > +	union xfs_suminfo_raw	*info = bp->b_addr;
> >  
> >  	return info + index;
> >  }
> >  
> > +/* Get the current value of a summary counter. */
> > +static inline xfs_suminfo_t
> > +xfs_suminfo_get(
> > +	struct xfs_buf		*bp,
> > +	unsigned int		index)
> > +{
> > +	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(bp, index);
> > +
> > +	return info->old;
> > +}
> 
> Same nitpick as for the bitmap version.
> 
> Otherwise this looks good:
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Assuming you also meant "Reviewed-by" here too? :)

> ... to actually understand the mess in xfs_rtmodify_summary_int I had
> to do the (untested) refactoring below.  I'll probably resubmit it after
> the whole series which touches a lot of this:

I'll take a look tomorrow, but yeah, xfs_rtmodify_summary_int is
confusing.

Annoyingly, I think there's a bug in new logging helpers, because all
the shutdown tests are falling all over themselves:

https://djwong.org/fstests/output/.c6b00f80b1e68bd5a3b17a7f7fbe97bab28dab740d7acf9e3fa879c3ae0c56c0/.02425ea8cdb6100e408b20dceac80a46f53f6fa1587fb4af7fba2810f2b8d0fd/?C=M;O=A

Will look at /that/ first thing...

--D

> 
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index 2118c6f177a135..7b09caa747a720 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
>   * Summary information is returned in *sum if specified.
>   * If no delta is specified, returns summary only.
>   */
> -int
> -xfs_rtmodify_summary_int(
> +static int
> +xfs_rtmodify_summary_find(
>  	xfs_mount_t	*mp,		/* file system mount structure */
>  	xfs_trans_t	*tp,		/* transaction pointer */
>  	int		log,		/* log2 of extent size */
>  	xfs_fileoff_t	bbno,		/* bitmap block number */
> -	int		delta,		/* change to make to summary info */
>  	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
>  	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> -	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> +	unsigned int	*word)
>  {
>  	struct xfs_buf	*bp;		/* buffer for the summary block */
>  	int		error;		/* error value */
> -	xfs_fileoff_t	sb;		/* summary fsblock */
>  	xfs_rtsumoff_t	so;		/* index into the summary file */
> +	xfs_fileoff_t	sb;		/* summary fsblock */
>  
>  	/*
>  	 * Compute entry number in the summary file.
>  	 */
>  	so = xfs_rtsumoffs(mp, log, bbno);
> +
>  	/*
>  	 * Compute the block number in the summary file.
>  	 */
>  	sb = xfs_rtsumoffs_to_block(mp, so);
> +
> +	/*
> +	 * Compute the word index into the summary.
> +	 */
> +	*word = xfs_rtsumoffs_to_infoword(mp, so);
> +
>  	/*
>  	 * If we have an old buffer, and the block number matches, use that.
>  	 */
>  	if (*rbpp && *rsb == sb)
> -		bp = *rbpp;
> +		return 0;
> +
>  	/*
> -	 * Otherwise we have to get the buffer.
> +	 * Otherwise we have to get a new buffer.
> +	 * If there was an old one, get rid of it first.
>  	 */
> -	else {
> -		/*
> -		 * If there was an old one, get rid of it first.
> -		 */
> -		if (*rbpp)
> -			xfs_trans_brelse(tp, *rbpp);
> -		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> -		if (error) {
> -			return error;
> -		}
> -		/*
> -		 * Remember this buffer and block for the next call.
> -		 */
> -		*rbpp = bp;
> -		*rsb = sb;
> -	}
> +	if (*rbpp)
> +		xfs_trans_brelse(tp, *rbpp);
> +	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> +	if (error)
> +		return error;
> +
>  	/*
> -	 * Point to the summary information, modify/log it, and/or copy it out.
> +	 * Remember this buffer and block for the next call.
>  	 */
> -	if (delta) {
> -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> -		xfs_suminfo_t	val = xfs_suminfo_add(bp, infoword, delta);
> -
> -		if (mp->m_rsum_cache) {
> -			if (val == 0 && log == mp->m_rsum_cache[bbno])
> -				mp->m_rsum_cache[bbno]++;
> -			if (val != 0 && log < mp->m_rsum_cache[bbno])
> -				mp->m_rsum_cache[bbno] = log;
> -		}
> -		xfs_trans_log_rtsummary(tp, bp, infoword);
> -		if (sum)
> -			*sum = val;
> -	} else if (sum) {
> -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> -
> -		*sum = xfs_suminfo_get(bp, infoword);
> -	}
> +	*rbpp = bp;
> +	*rsb = sb;
>  	return 0;
>  }
>  
> +/*
> + * Read and/or modify the summary information for a given extent size,
> + * bitmap block combination.
> + * Keeps track of a current summary block, so we don't keep reading
> + * it from the buffer cache.
> + *
> + * Summary information is returned in *sum if specified.
> + * If no delta is specified, returns summary only.
> + */
>  int
>  xfs_rtmodify_summary(
>  	xfs_mount_t	*mp,		/* file system mount structure */
> @@ -515,8 +506,51 @@ xfs_rtmodify_summary(
>  	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
>  	xfs_fileoff_t	*rsb)		/* in/out: summary block number */
>  {
> -	return xfs_rtmodify_summary_int(mp, tp, log, bbno,
> -					delta, rbpp, rsb, NULL);
> +	int		error;
> +	unsigned int	word;
> +	xfs_suminfo_t	val;
> +
> +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> +	if (error)
> +		return error;
> +
> +	/*
> +	 * Modify and log the summary information.
> +	 */
> +	val = xfs_suminfo_add(*rbpp, word, delta);
> +	if (mp->m_rsum_cache) {
> +		if (val == 0 && log == mp->m_rsum_cache[bbno])
> +			mp->m_rsum_cache[bbno]++;
> +		if (val != 0 && log < mp->m_rsum_cache[bbno])
> +			mp->m_rsum_cache[bbno] = log;
> +	}
> +	xfs_trans_log_rtsummary(tp, *rbpp, word);
> +	return 0;
> +}
> +
> +/*
> + * Read and return the summary information for a given extent size,
> + * bitmap block combination.
> + * Keeps track of a current summary block, so we don't keep reading
> + * it from the buffer cache.
> + */
> +int
> +xfs_rtget_summary(
> +	xfs_mount_t	*mp,		/* file system mount structure */
> +	xfs_trans_t	*tp,		/* transaction pointer */
> +	int		log,		/* log2 of extent size */
> +	xfs_fileoff_t	bbno,		/* bitmap block number */
> +	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> +	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> +	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> +{
> +	int		error;
> +	unsigned int	word;
> +
> +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> +	if (!error)
> +		*sum = xfs_suminfo_get(*rbpp, word);
> +	return error;
>  }
>  
>  /* Log rtbitmap block from the word @from to the byte before @next. */
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index fdfa98e0ee52f7..6d23a77def50dd 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
>  		    xfs_rtxnum_t *rtblock);
>  int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
>  		       xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
> -int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
> -			     int log, xfs_fileoff_t bbno, int delta,
> -			     struct xfs_buf **rbpp, xfs_fileoff_t *rsb,
> -			     xfs_suminfo_t *sum);
>  int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
>  			 xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
>  			 xfs_fileoff_t *rsb);
> +int xfs_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
> +		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
> +		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
>  int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
>  		     xfs_rtxnum_t start, xfs_rtxlen_t len,
>  		     struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
> diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> index 3be6bda2fd920c..22bc8b3b724a5b 100644
> --- a/fs/xfs/xfs_rtalloc.c
> +++ b/fs/xfs/xfs_rtalloc.c
> @@ -21,25 +21,6 @@
>  #include "xfs_sb.h"
>  #include "xfs_rtbitmap.h"
>  
> -/*
> - * Read and return the summary information for a given extent size,
> - * bitmap block combination.
> - * Keeps track of a current summary block, so we don't keep reading
> - * it from the buffer cache.
> - */
> -static int
> -xfs_rtget_summary(
> -	xfs_mount_t	*mp,		/* file system mount structure */
> -	xfs_trans_t	*tp,		/* transaction pointer */
> -	int		log,		/* log2 of extent size */
> -	xfs_fileoff_t	bbno,		/* bitmap block number */
> -	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> -	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> -	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> -{
> -	return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum);
> -}
> -
>  /*
>   * Return whether there are any free extents in the size range given
>   * by low and high, for the bitmap block bbno.
Christoph Hellwig Oct. 18, 2023, 5:35 a.m. UTC | #3
On Tue, Oct 17, 2023 at 10:31:27PM -0700, Darrick J. Wong wrote:
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Assuming you also meant "Reviewed-by" here too? :)

Yes:

Reviewed-by: Christoph Hellwig <hch@lst.de>
Darrick J. Wong Oct. 18, 2023, 6:16 a.m. UTC | #4
On Tue, Oct 17, 2023 at 10:31:27PM -0700, Darrick J. Wong wrote:
> On Wed, Oct 18, 2023 at 07:19:34AM +0200, Christoph Hellwig wrote:
> > On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> > > +static inline union xfs_suminfo_raw *
> > >  xfs_rsumblock_infoptr(
> > >  	struct xfs_buf		*bp,
> > >  	unsigned int		index)
> > >  {
> > > -	xfs_suminfo_t		*info = bp->b_addr;
> > > +	union xfs_suminfo_raw	*info = bp->b_addr;
> > >  
> > >  	return info + index;
> > >  }
> > >  
> > > +/* Get the current value of a summary counter. */
> > > +static inline xfs_suminfo_t
> > > +xfs_suminfo_get(
> > > +	struct xfs_buf		*bp,
> > > +	unsigned int		index)
> > > +{
> > > +	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(bp, index);
> > > +
> > > +	return info->old;
> > > +}
> > 
> > Same nitpick as for the bitmap version.
> > 
> > Otherwise this looks good:
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Assuming you also meant "Reviewed-by" here too? :)
> 
> > ... to actually understand the mess in xfs_rtmodify_summary_int I had
> > to do the (untested) refactoring below.  I'll probably resubmit it after
> > the whole series which touches a lot of this:
> 
> I'll take a look tomorrow, but yeah, xfs_rtmodify_summary_int is
> confusing.
> 
> Annoyingly, I think there's a bug in new logging helpers, because all
> the shutdown tests are falling all over themselves:
> 
> https://djwong.org/fstests/output/.c6b00f80b1e68bd5a3b17a7f7fbe97bab28dab740d7acf9e3fa879c3ae0c56c0/.02425ea8cdb6100e408b20dceac80a46f53f6fa1587fb4af7fba2810f2b8d0fd/?C=M;O=A
> 
> Will look at /that/ first thing...

Oh rats, I forgot to adjust the xfs_trans_log_rtbitmap offsets for the
block headers added in the rtgroups patchset.

--D

> --D
> 
> > 
> > diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> > index 2118c6f177a135..7b09caa747a720 100644
> > --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> > +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> > @@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
> >   * Summary information is returned in *sum if specified.
> >   * If no delta is specified, returns summary only.
> >   */
> > -int
> > -xfs_rtmodify_summary_int(
> > +static int
> > +xfs_rtmodify_summary_find(
> >  	xfs_mount_t	*mp,		/* file system mount structure */
> >  	xfs_trans_t	*tp,		/* transaction pointer */
> >  	int		log,		/* log2 of extent size */
> >  	xfs_fileoff_t	bbno,		/* bitmap block number */
> > -	int		delta,		/* change to make to summary info */
> >  	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> >  	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> > -	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> > +	unsigned int	*word)
> >  {
> >  	struct xfs_buf	*bp;		/* buffer for the summary block */
> >  	int		error;		/* error value */
> > -	xfs_fileoff_t	sb;		/* summary fsblock */
> >  	xfs_rtsumoff_t	so;		/* index into the summary file */
> > +	xfs_fileoff_t	sb;		/* summary fsblock */
> >  
> >  	/*
> >  	 * Compute entry number in the summary file.
> >  	 */
> >  	so = xfs_rtsumoffs(mp, log, bbno);
> > +
> >  	/*
> >  	 * Compute the block number in the summary file.
> >  	 */
> >  	sb = xfs_rtsumoffs_to_block(mp, so);
> > +
> > +	/*
> > +	 * Compute the word index into the summary.
> > +	 */
> > +	*word = xfs_rtsumoffs_to_infoword(mp, so);
> > +
> >  	/*
> >  	 * If we have an old buffer, and the block number matches, use that.
> >  	 */
> >  	if (*rbpp && *rsb == sb)
> > -		bp = *rbpp;
> > +		return 0;
> > +
> >  	/*
> > -	 * Otherwise we have to get the buffer.
> > +	 * Otherwise we have to get a new buffer.
> > +	 * If there was an old one, get rid of it first.
> >  	 */
> > -	else {
> > -		/*
> > -		 * If there was an old one, get rid of it first.
> > -		 */
> > -		if (*rbpp)
> > -			xfs_trans_brelse(tp, *rbpp);
> > -		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> > -		if (error) {
> > -			return error;
> > -		}
> > -		/*
> > -		 * Remember this buffer and block for the next call.
> > -		 */
> > -		*rbpp = bp;
> > -		*rsb = sb;
> > -	}
> > +	if (*rbpp)
> > +		xfs_trans_brelse(tp, *rbpp);
> > +	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> > +	if (error)
> > +		return error;
> > +
> >  	/*
> > -	 * Point to the summary information, modify/log it, and/or copy it out.
> > +	 * Remember this buffer and block for the next call.
> >  	 */
> > -	if (delta) {
> > -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> > -		xfs_suminfo_t	val = xfs_suminfo_add(bp, infoword, delta);
> > -
> > -		if (mp->m_rsum_cache) {
> > -			if (val == 0 && log == mp->m_rsum_cache[bbno])
> > -				mp->m_rsum_cache[bbno]++;
> > -			if (val != 0 && log < mp->m_rsum_cache[bbno])
> > -				mp->m_rsum_cache[bbno] = log;
> > -		}
> > -		xfs_trans_log_rtsummary(tp, bp, infoword);
> > -		if (sum)
> > -			*sum = val;
> > -	} else if (sum) {
> > -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> > -
> > -		*sum = xfs_suminfo_get(bp, infoword);
> > -	}
> > +	*rbpp = bp;
> > +	*rsb = sb;
> >  	return 0;
> >  }
> >  
> > +/*
> > + * Read and/or modify the summary information for a given extent size,
> > + * bitmap block combination.
> > + * Keeps track of a current summary block, so we don't keep reading
> > + * it from the buffer cache.
> > + *
> > + * Summary information is returned in *sum if specified.
> > + * If no delta is specified, returns summary only.
> > + */
> >  int
> >  xfs_rtmodify_summary(
> >  	xfs_mount_t	*mp,		/* file system mount structure */
> > @@ -515,8 +506,51 @@ xfs_rtmodify_summary(
> >  	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> >  	xfs_fileoff_t	*rsb)		/* in/out: summary block number */
> >  {
> > -	return xfs_rtmodify_summary_int(mp, tp, log, bbno,
> > -					delta, rbpp, rsb, NULL);
> > +	int		error;
> > +	unsigned int	word;
> > +	xfs_suminfo_t	val;
> > +
> > +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> > +	if (error)
> > +		return error;
> > +
> > +	/*
> > +	 * Modify and log the summary information.
> > +	 */
> > +	val = xfs_suminfo_add(*rbpp, word, delta);
> > +	if (mp->m_rsum_cache) {
> > +		if (val == 0 && log == mp->m_rsum_cache[bbno])
> > +			mp->m_rsum_cache[bbno]++;
> > +		if (val != 0 && log < mp->m_rsum_cache[bbno])
> > +			mp->m_rsum_cache[bbno] = log;
> > +	}
> > +	xfs_trans_log_rtsummary(tp, *rbpp, word);
> > +	return 0;
> > +}
> > +
> > +/*
> > + * Read and return the summary information for a given extent size,
> > + * bitmap block combination.
> > + * Keeps track of a current summary block, so we don't keep reading
> > + * it from the buffer cache.
> > + */
> > +int
> > +xfs_rtget_summary(
> > +	xfs_mount_t	*mp,		/* file system mount structure */
> > +	xfs_trans_t	*tp,		/* transaction pointer */
> > +	int		log,		/* log2 of extent size */
> > +	xfs_fileoff_t	bbno,		/* bitmap block number */
> > +	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> > +	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> > +	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> > +{
> > +	int		error;
> > +	unsigned int	word;
> > +
> > +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> > +	if (!error)
> > +		*sum = xfs_suminfo_get(*rbpp, word);
> > +	return error;
> >  }
> >  
> >  /* Log rtbitmap block from the word @from to the byte before @next. */
> > diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> > index fdfa98e0ee52f7..6d23a77def50dd 100644
> > --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> > +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> > @@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
> >  		    xfs_rtxnum_t *rtblock);
> >  int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
> >  		       xfs_rtxnum_t start, xfs_rtxlen_t len, int val);
> > -int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
> > -			     int log, xfs_fileoff_t bbno, int delta,
> > -			     struct xfs_buf **rbpp, xfs_fileoff_t *rsb,
> > -			     xfs_suminfo_t *sum);
> >  int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
> >  			 xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp,
> >  			 xfs_fileoff_t *rsb);
> > +int xfs_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
> > +		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
> > +		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
> >  int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
> >  		     xfs_rtxnum_t start, xfs_rtxlen_t len,
> >  		     struct xfs_buf **rbpp, xfs_fileoff_t *rsb);
> > diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> > index 3be6bda2fd920c..22bc8b3b724a5b 100644
> > --- a/fs/xfs/xfs_rtalloc.c
> > +++ b/fs/xfs/xfs_rtalloc.c
> > @@ -21,25 +21,6 @@
> >  #include "xfs_sb.h"
> >  #include "xfs_rtbitmap.h"
> >  
> > -/*
> > - * Read and return the summary information for a given extent size,
> > - * bitmap block combination.
> > - * Keeps track of a current summary block, so we don't keep reading
> > - * it from the buffer cache.
> > - */
> > -static int
> > -xfs_rtget_summary(
> > -	xfs_mount_t	*mp,		/* file system mount structure */
> > -	xfs_trans_t	*tp,		/* transaction pointer */
> > -	int		log,		/* log2 of extent size */
> > -	xfs_fileoff_t	bbno,		/* bitmap block number */
> > -	struct xfs_buf	**rbpp,		/* in/out: summary block buffer */
> > -	xfs_fileoff_t	*rsb,		/* in/out: summary block number */
> > -	xfs_suminfo_t	*sum)		/* out: summary info for this block */
> > -{
> > -	return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum);
> > -}
> > -
> >  /*
> >   * Return whether there are any free extents in the size range given
> >   * by low and high, for the bitmap block bbno.
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 2af891d5d171..9a88aba1589f 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -698,6 +698,14 @@  union xfs_rtword_raw {
 	__u32		old;
 };
 
+/*
+ * Realtime summary counts are accessed by the word, which is currently
+ * stored in host-endian format.
+ */
+union xfs_suminfo_raw {
+	__u32		old;
+};
+
 /*
  * XFS Timestamps
  * ==============
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 4ef54bfbb3da..93de330e9cae 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -448,7 +448,6 @@  xfs_rtmodify_summary_int(
 	int		error;		/* error value */
 	xfs_fileoff_t	sb;		/* summary fsblock */
 	xfs_rtsumoff_t	so;		/* index into the summary file */
-	xfs_suminfo_t	*sp;		/* pointer to returned data */
 	unsigned int	infoword;
 
 	/*
@@ -487,19 +486,21 @@  xfs_rtmodify_summary_int(
 	 * Point to the summary information, modify/log it, and/or copy it out.
 	 */
 	infoword = xfs_rtsumoffs_to_infoword(mp, so);
-	sp = xfs_rsumblock_infoptr(bp, infoword);
 	if (delta) {
-		*sp += delta;
+		xfs_suminfo_t	val = xfs_suminfo_add(bp, infoword, delta);
+
 		if (mp->m_rsum_cache) {
-			if (*sp == 0 && log == mp->m_rsum_cache[bbno])
+			if (val == 0 && log == mp->m_rsum_cache[bbno])
 				mp->m_rsum_cache[bbno]++;
-			if (*sp != 0 && log < mp->m_rsum_cache[bbno])
+			if (val != 0 && log < mp->m_rsum_cache[bbno])
 				mp->m_rsum_cache[bbno] = log;
 		}
 		xfs_trans_log_rtsummary(tp, bp, infoword);
+		if (sum)
+			*sum = val;
+	} else if (sum) {
+		*sum = xfs_suminfo_get(bp, infoword);
 	}
-	if (sum)
-		*sum = *sp;
 	return 0;
 }
 
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index a3e8288bedea..fdfa98e0ee52 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -232,16 +232,40 @@  xfs_rtsumoffs_to_infoword(
 }
 
 /* Return a pointer to a summary info word within a rt summary block. */
-static inline xfs_suminfo_t *
+static inline union xfs_suminfo_raw *
 xfs_rsumblock_infoptr(
 	struct xfs_buf		*bp,
 	unsigned int		index)
 {
-	xfs_suminfo_t		*info = bp->b_addr;
+	union xfs_suminfo_raw	*info = bp->b_addr;
 
 	return info + index;
 }
 
+/* Get the current value of a summary counter. */
+static inline xfs_suminfo_t
+xfs_suminfo_get(
+	struct xfs_buf		*bp,
+	unsigned int		index)
+{
+	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(bp, index);
+
+	return info->old;
+}
+
+/* Add to the current value of a summary counter and return the new value. */
+static inline xfs_suminfo_t
+xfs_suminfo_add(
+	struct xfs_buf		*bp,
+	unsigned int		index,
+	int			delta)
+{
+	union xfs_suminfo_raw	*info = xfs_rsumblock_infoptr(bp, index);
+
+	info->old += delta;
+	return info->old;
+}
+
 /*
  * Functions for walking free space rtextents in the realtime bitmap.
  */
diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c
index ae51fb982808..6ef1fd7e086b 100644
--- a/fs/xfs/scrub/rtsummary.c
+++ b/fs/xfs/scrub/rtsummary.c
@@ -82,9 +82,10 @@  static inline int
 xfsum_load(
 	struct xfs_scrub	*sc,
 	xfs_rtsumoff_t		sumoff,
-	xfs_suminfo_t		*info)
+	union xfs_suminfo_raw	*rawinfo)
 {
-	return xfile_obj_load(sc->xfile, info, sizeof(xfs_suminfo_t),
+	return xfile_obj_load(sc->xfile, rawinfo,
+			sizeof(union xfs_suminfo_raw),
 			sumoff << XFS_WORDLOG);
 }
 
@@ -92,9 +93,10 @@  static inline int
 xfsum_store(
 	struct xfs_scrub	*sc,
 	xfs_rtsumoff_t		sumoff,
-	const xfs_suminfo_t	info)
+	const union xfs_suminfo_raw rawinfo)
 {
-	return xfile_obj_store(sc->xfile, &info, sizeof(xfs_suminfo_t),
+	return xfile_obj_store(sc->xfile, &rawinfo,
+			sizeof(union xfs_suminfo_raw),
 			sumoff << XFS_WORDLOG);
 }
 
@@ -102,13 +104,22 @@  static inline int
 xfsum_copyout(
 	struct xfs_scrub	*sc,
 	xfs_rtsumoff_t		sumoff,
-	xfs_suminfo_t		*info,
+	union xfs_suminfo_raw	*rawinfo,
 	unsigned int		nr_words)
 {
-	return xfile_obj_load(sc->xfile, info, nr_words << XFS_WORDLOG,
+	return xfile_obj_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG,
 			sumoff << XFS_WORDLOG);
 }
 
+static inline xfs_suminfo_t
+xchk_rtsum_inc(
+	struct xfs_mount	*mp,
+	union xfs_suminfo_raw	*v)
+{
+	v->old += 1;
+	return v->old;
+}
+
 /* Update the summary file to reflect the free extent that we've accumulated. */
 STATIC int
 xchk_rtsum_record_free(
@@ -123,7 +134,8 @@  xchk_rtsum_record_free(
 	xfs_filblks_t			rtlen;
 	xfs_rtsumoff_t			offs;
 	unsigned int			lenlog;
-	xfs_suminfo_t			v = 0;
+	union xfs_suminfo_raw		v;
+	xfs_suminfo_t			value;
 	int				error = 0;
 
 	if (xchk_should_terminate(sc, &error))
@@ -147,9 +159,9 @@  xchk_rtsum_record_free(
 	if (error)
 		return error;
 
-	v++;
+	value = xchk_rtsum_inc(sc->mp, &v);
 	trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount,
-			lenlog, offs, v);
+			lenlog, offs, value);
 
 	return xfsum_store(sc, offs, v);
 }
diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c
index 46249e7b17e0..29afa4851235 100644
--- a/fs/xfs/scrub/trace.c
+++ b/fs/xfs/scrub/trace.c
@@ -13,6 +13,7 @@ 
 #include "xfs_inode.h"
 #include "xfs_btree.h"
 #include "xfs_ag.h"
+#include "xfs_rtbitmap.h"
 #include "scrub/scrub.h"
 #include "scrub/xfile.h"
 #include "scrub/xfarray.h"
diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
index b0cf6757444f..4a8bc6f3c8f2 100644
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -1038,8 +1038,8 @@  TRACE_EVENT(xfarray_sort_stats,
 TRACE_EVENT(xchk_rtsum_record_free,
 	TP_PROTO(struct xfs_mount *mp, xfs_rtxnum_t start,
 		 xfs_rtbxlen_t len, unsigned int log, loff_t pos,
-		 xfs_suminfo_t v),
-	TP_ARGS(mp, start, len, log, pos, v),
+		 xfs_suminfo_t value),
+	TP_ARGS(mp, start, len, log, pos, value),
 	TP_STRUCT__entry(
 		__field(dev_t, dev)
 		__field(dev_t, rtdev)
@@ -1047,7 +1047,7 @@  TRACE_EVENT(xchk_rtsum_record_free,
 		__field(unsigned long long, len)
 		__field(unsigned int, log)
 		__field(loff_t, pos)
-		__field(xfs_suminfo_t, v)
+		__field(xfs_suminfo_t, value)
 	),
 	TP_fast_assign(
 		__entry->dev = mp->m_super->s_dev;
@@ -1056,7 +1056,7 @@  TRACE_EVENT(xchk_rtsum_record_free,
 		__entry->len = len;
 		__entry->log = log;
 		__entry->pos = pos;
-		__entry->v = v;
+		__entry->value = value;
 	),
 	TP_printk("dev %d:%d rtdev %d:%d rtx 0x%llx rtxcount 0x%llx log %u rsumpos 0x%llx sumcount %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1065,7 +1065,7 @@  TRACE_EVENT(xchk_rtsum_record_free,
 		  __entry->len,
 		  __entry->log,
 		  __entry->pos,
-		  __entry->v)
+		  __entry->value)
 );
 #endif /* CONFIG_XFS_RT */
 
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index 14d455f768d3..21a7e350b4c5 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -74,6 +74,7 @@  xfs_check_ondisk_structs(void)
 
 	/* realtime structures */
 	XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw,		4);
+	XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_raw,		4);
 
 	/*
 	 * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to