Skip to content

Commit

Permalink
xfs: scrub inode btrees
Browse files Browse the repository at this point in the history
Check the records of the inode btrees to make sure that the values
make sense given the inode records themselves.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
  • Loading branch information
Darrick J. Wong committed Oct 26, 2017
1 parent efa7a99 commit 3daa664
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 2 deletions.
1 change: 1 addition & 0 deletions fs/xfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ xfs-y += $(addprefix scrub/, \
alloc.o \
btree.o \
common.o \
ialloc.o \
scrub.o \
)
endif
2 changes: 1 addition & 1 deletion fs/xfs/libxfs/xfs_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
(sbp->sb_features2 & XFS_SB_VERSION2_FTYPE));
}

static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
static inline bool xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
{
return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT);
Expand Down
4 changes: 3 additions & 1 deletion fs/xfs/libxfs/xfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,11 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_AGI 4 /* AG inode header */
#define XFS_SCRUB_TYPE_BNOBT 5 /* freesp by block btree */
#define XFS_SCRUB_TYPE_CNTBT 6 /* freesp by length btree */
#define XFS_SCRUB_TYPE_INOBT 7 /* inode btree */
#define XFS_SCRUB_TYPE_FINOBT 8 /* free inode btree */

/* Number of scrub subcommands. */
#define XFS_SCRUB_TYPE_NR 7
#define XFS_SCRUB_TYPE_NR 9

/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR (1 << 0)
Expand Down
29 changes: 29 additions & 0 deletions fs/xfs/scrub/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include "xfs_refcount_btree.h"
#include "xfs_rmap.h"
#include "xfs_rmap_btree.h"
#include "xfs_log.h"
#include "xfs_trans_priv.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
Expand Down Expand Up @@ -451,11 +453,38 @@ xfs_scrub_setup_ag_btree(
struct xfs_inode *ip,
bool force_log)
{
struct xfs_mount *mp = sc->mp;
int error;

/*
* If the caller asks us to checkpont the log, do so. This
* expensive operation should be performed infrequently and only
* as a last resort. Any caller that sets force_log should
* document why they need to do so.
*/
if (force_log) {
error = xfs_scrub_checkpoint_log(mp);
if (error)
return error;
}

error = xfs_scrub_setup_ag_header(sc, ip);
if (error)
return error;

return xfs_scrub_ag_init(sc, sc->sm->sm_agno, &sc->sa);
}

/* Push everything out of the log onto disk. */
int
xfs_scrub_checkpoint_log(
struct xfs_mount *mp)
{
int error;

error = _xfs_log_force(mp, XFS_LOG_SYNC, NULL);
if (error)
return error;
xfs_ail_push_all_sync(mp->m_ail);
return 0;
}
3 changes: 3 additions & 0 deletions fs/xfs/scrub/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,16 @@ void xfs_scrub_fblock_set_warning(struct xfs_scrub_context *sc, int whichfork,
xfs_fileoff_t offset);

void xfs_scrub_set_incomplete(struct xfs_scrub_context *sc);
int xfs_scrub_checkpoint_log(struct xfs_mount *mp);

/* Setup functions */
int xfs_scrub_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip);
int xfs_scrub_setup_ag_header(struct xfs_scrub_context *sc,
struct xfs_inode *ip);
int xfs_scrub_setup_ag_allocbt(struct xfs_scrub_context *sc,
struct xfs_inode *ip);
int xfs_scrub_setup_ag_iallocbt(struct xfs_scrub_context *sc,
struct xfs_inode *ip);


void xfs_scrub_ag_free(struct xfs_scrub_context *sc, struct xfs_scrub_ag *sa);
Expand Down
Loading

0 comments on commit 3daa664

Please sign in to comment.