[PATCH 17/25] xfs: scrub realtime bitmap/summary

"Darrick J. Wong" <[email protected]>
Newsgroups gmane.comp.file-systems.xfs.general
Message-ID <[email protected]>
Perform simple tests of the realtime bitmap and summary.

Signed-off-by: Darrick J. Wong <[email protected]>
---
 fs/xfs/libxfs/xfs_format.h   |    5 +++
 fs/xfs/libxfs/xfs_fs.h       |    4 ++
 fs/xfs/libxfs/xfs_rtbitmap.c |    2 +
 fs/xfs/xfs_rtalloc.h         |    3 ++
 fs/xfs/xfs_scrub.c           |   78 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 90 insertions(+), 2 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index a3aa5e9..5703b57 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -315,6 +315,11 @@ static inline bool xfs_sb_good_version(struct xfs_sb *sbp)
 	return false;
 }
 
+static inline bool xfs_sb_version_hasrealtime(struct xfs_sb *sbp)
+{
+	return sbp->sb_rblocks > 0;
+}
+
 /*
  * Detect a mismatched features2 field.  Older kernels read/wrote
  * this into the wrong slot, so to be safe we keep them in sync.
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index c688deb..211c874 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -549,7 +549,9 @@ struct xfs_scrub_metadata {
 #define XFS_SCRUB_TYPE_BMBTD	11	/* data fork block mapping */
 #define XFS_SCRUB_TYPE_BMBTA	12	/* attr fork block mapping */
 #define XFS_SCRUB_TYPE_BMBTC	13	/* CoW fork block mapping */
-#define XFS_SCRUB_TYPE_MAX	13
+#define XFS_SCRUB_TYPE_RTBITMAP	14	/* realtime bitmap */
+#define XFS_SCRUB_TYPE_RTSUM	15	/* realtime summary */
+#define XFS_SCRUB_TYPE_MAX	15
 
 #define XFS_SCRUB_FLAGS_ALL	0x0	/* no flags yet */
 
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index ea45584..f4b68c0 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -70,7 +70,7 @@ const struct xfs_buf_ops xfs_rtbuf_ops = {
  * Get a buffer for the bitmap or summary file block specified.
  * The buffer is returned read and locked.
  */
-static int
+int
 xfs_rtbuf_get(
 	xfs_mount_t	*mp,		/* file system mount structure */
 	xfs_trans_t	*tp,		/* transaction pointer */
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 355dd9e..91e48f9 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -98,6 +98,8 @@ xfs_growfs_rt(
 /*
  * From xfs_rtbitmap.c
  */
+int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
+		  xfs_rtblock_t block, int issum, struct xfs_buf **bpp);
 int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp,
 		      xfs_rtblock_t start, xfs_extlen_t len, int val,
 		      xfs_rtblock_t *new, int *stat);
@@ -126,6 +128,7 @@ int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
 # define xfs_rtfree_extent(t,b,l)                       (ENOSYS)
 # define xfs_rtpick_extent(m,t,l,rb)                    (ENOSYS)
 # define xfs_growfs_rt(mp,in)                           (ENOSYS)
+# define xfs_rtbuf_get(m,t,b,i,p)                       (ENOSYS)
 static inline int		/* error */
 xfs_rtmount_init(
 	xfs_mount_t	*mp)	/* file system mount structure */
diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index 573acd4..22ba07d 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -773,6 +773,7 @@ xfs_scrub_sb(
         XFS_SCRUB_SB_FEAT(metauuid);
         XFS_SCRUB_SB_FEAT(rmapbt);
         XFS_SCRUB_SB_FEAT(reflink);
+        XFS_SCRUB_SB_FEAT(realtime);
 #undef XFS_SCRUB_SB_FEAT
 
 out:
@@ -1674,6 +1675,81 @@ xfs_scrub_bmap_cow(
 	return xfs_scrub_bmap(ip, sm, XFS_COW_FORK);
 }
 
+/* Scrub the realtime bitmap. */
+STATIC int
+xfs_scrub_rtbitmap(
+	struct xfs_inode		*ip,
+	struct xfs_scrub_metadata	*sm)
+{
+	struct xfs_mount		*mp = ip->i_mount;
+	struct xfs_buf			*bp = NULL;
+	xfs_rtblock_t			rtstart;
+	xfs_rtblock_t			rtend;
+	xfs_rtblock_t			block;
+	xfs_rtblock_t			rem;
+	int				is_free;
+	int				error = 0;
+	int				err2 = 0;
+
+	if (sm->control || sm->flags)
+		return -EINVAL;
+
+	xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+
+	/* Iterate the bitmap, looking for discrepancies. */
+	rtstart = 0;
+	rem = mp->m_sb.sb_rblocks;
+	while (rem) {
+		if (xfs_scrub_should_terminate(&error))
+			break;
+
+		/* Is the first block free? */
+		err2 = xfs_rtcheck_range(mp, NULL, rtstart, 1, 1, &rtend,
+				&is_free);
+		if (err2)
+			goto out_unlock;
+
+		/* How long does the extent go for? */
+		err2 = xfs_rtfind_forw(mp, NULL, rtstart,
+				mp->m_sb.sb_rblocks - 1, &rtend);
+		if (err2)
+			goto out_unlock;
+
+		/* Find the buffer for error reporting. */
+		block = XFS_BITTOBLOCK(mp, rtstart);
+		err2 = xfs_rtbuf_get(mp, NULL, block, 0, &bp);
+		if (err2)
+			break;
+		XFS_SCRUB_CHECK(mp, bp, "rtbitmap", rtend >= rtstart);
+
+		xfs_buf_relse(bp);
+		bp = NULL;
+		rem -= rtend - rtstart + 1;
+		rtstart = rtend + 1;
+	}
+
+out_unlock:
+	if (bp)
+		xfs_buf_relse(bp);
+	xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+	if (!error && err2)
+		error = err2;
+	return error;
+}
+
+/* Scrub the realtime summary. */
+STATIC int
+xfs_scrub_rtsummary(
+	struct xfs_inode		*ip,
+	struct xfs_scrub_metadata	*sm)
+{
+	if (sm->control || sm->flags)
+		return -EINVAL;
+
+	/* XXX: implement this some day */
+	return -ENOENT;
+}
+
 /* Scrubbing dispatch. */
 
 struct xfs_scrub_meta_fns {
@@ -1696,6 +1772,8 @@ static const struct xfs_scrub_meta_fns meta_scrub_fns[] = {
 	{xfs_scrub_bmap_data,	NULL},
 	{xfs_scrub_bmap_attr,	NULL},
 	{xfs_scrub_bmap_cow,	NULL},
+	{xfs_scrub_rtbitmap,	xfs_sb_version_hasrealtime},
+	{xfs_scrub_rtsummary,	xfs_sb_version_hasrealtime},
 };
 
 /* Dispatch metadata scrubbing. */

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.