Perform simple tests of the realtime bitmap and summary. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- 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 xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs