[1/2] xfs: rtbitmap scrubber should verify written extents
diff mbox series

Message ID 159353170100.2864648.5747092047346568608.stgit@magnolia
State Accepted
Headers show
Series
  • xfs: strengthen online checking
Related show

Commit Message

Darrick J. Wong June 30, 2020, 3:41 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Ensure that the realtime bitmap file is backed entirely by written
extents.  No holes, no unwritten blocks, etc.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/scrub/rtbitmap.c |   40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Comments

Allison Collins June 30, 2020, 9:05 p.m. UTC | #1
On 6/30/20 8:41 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Ensure that the realtime bitmap file is backed entirely by written
> extents.  No holes, no unwritten blocks, etc.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, makes sense to me
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/scrub/rtbitmap.c |   40 ++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 40 insertions(+)
> 
> 
> diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
> index c642bc206c41..c777c98c50c3 100644
> --- a/fs/xfs/scrub/rtbitmap.c
> +++ b/fs/xfs/scrub/rtbitmap.c
> @@ -13,6 +13,7 @@
>   #include "xfs_trans.h"
>   #include "xfs_rtalloc.h"
>   #include "xfs_inode.h"
> +#include "xfs_bmap.h"
>   #include "scrub/scrub.h"
>   #include "scrub/common.h"
>   
> @@ -58,6 +59,41 @@ xchk_rtbitmap_rec(
>   	return 0;
>   }
>   
> +/* Make sure the entire rtbitmap file is mapped with written extents. */
> +STATIC int
> +xchk_rtbitmap_check_extents(
> +	struct xfs_scrub	*sc)
> +{
> +	struct xfs_mount	*mp = sc->mp;
> +	struct xfs_bmbt_irec	map;
> +	xfs_rtblock_t		off;
> +	int			nmap;
> +	int			error = 0;
> +
> +	for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
> +		if (xchk_should_terminate(sc, &error) ||
> +		    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
> +			break;
> +
> +		/* Make sure we have a written extent. */
> +		nmap = 1;
> +		error = xfs_bmapi_read(mp->m_rbmip, off,
> +				mp->m_sb.sb_rbmblocks - off, &map, &nmap,
> +				XFS_DATA_FORK);
> +		if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
> +			break;
> +
> +		if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
> +			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
> +			break;
> +		}
> +
> +		off += map.br_blockcount;
> +	}
> +
> +	return error;
> +}
> +
>   /* Scrub the realtime bitmap. */
>   int
>   xchk_rtbitmap(
> @@ -70,6 +106,10 @@ xchk_rtbitmap(
>   	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
>   		return error;
>   
> +	error = xchk_rtbitmap_check_extents(sc);
> +	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
> +		return error;
> +
>   	error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc);
>   	if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
>   		goto out;
>

Patch
diff mbox series

diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
index c642bc206c41..c777c98c50c3 100644
--- a/fs/xfs/scrub/rtbitmap.c
+++ b/fs/xfs/scrub/rtbitmap.c
@@ -13,6 +13,7 @@ 
 #include "xfs_trans.h"
 #include "xfs_rtalloc.h"
 #include "xfs_inode.h"
+#include "xfs_bmap.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
 
@@ -58,6 +59,41 @@  xchk_rtbitmap_rec(
 	return 0;
 }
 
+/* Make sure the entire rtbitmap file is mapped with written extents. */
+STATIC int
+xchk_rtbitmap_check_extents(
+	struct xfs_scrub	*sc)
+{
+	struct xfs_mount	*mp = sc->mp;
+	struct xfs_bmbt_irec	map;
+	xfs_rtblock_t		off;
+	int			nmap;
+	int			error = 0;
+
+	for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
+		if (xchk_should_terminate(sc, &error) ||
+		    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
+			break;
+
+		/* Make sure we have a written extent. */
+		nmap = 1;
+		error = xfs_bmapi_read(mp->m_rbmip, off,
+				mp->m_sb.sb_rbmblocks - off, &map, &nmap,
+				XFS_DATA_FORK);
+		if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
+			break;
+
+		if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
+			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
+			break;
+		}
+
+		off += map.br_blockcount;
+	}
+
+	return error;
+}
+
 /* Scrub the realtime bitmap. */
 int
 xchk_rtbitmap(
@@ -70,6 +106,10 @@  xchk_rtbitmap(
 	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
 		return error;
 
+	error = xchk_rtbitmap_check_extents(sc);
+	if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
+		return error;
+
 	error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc);
 	if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
 		goto out;