Skip to content

Commit 3daa664

Browse files
committed
xfs: scrub inode btrees
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>
1 parent efa7a99 commit 3daa664

File tree

8 files changed

+385
-2
lines changed

8 files changed

+385
-2
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ xfs-y += $(addprefix scrub/, \
147147
alloc.o \
148148
btree.o \
149149
common.o \
150+
ialloc.o \
150151
scrub.o \
151152
)
152153
endif

fs/xfs/libxfs/xfs_format.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
518518
(sbp->sb_features2 & XFS_SB_VERSION2_FTYPE));
519519
}
520520

521-
static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
521+
static inline bool xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
522522
{
523523
return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
524524
(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT);

fs/xfs/libxfs/xfs_fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,11 @@ struct xfs_scrub_metadata {
490490
#define XFS_SCRUB_TYPE_AGI 4 /* AG inode header */
491491
#define XFS_SCRUB_TYPE_BNOBT 5 /* freesp by block btree */
492492
#define XFS_SCRUB_TYPE_CNTBT 6 /* freesp by length btree */
493+
#define XFS_SCRUB_TYPE_INOBT 7 /* inode btree */
494+
#define XFS_SCRUB_TYPE_FINOBT 8 /* free inode btree */
493495

494496
/* Number of scrub subcommands. */
495-
#define XFS_SCRUB_TYPE_NR 7
497+
#define XFS_SCRUB_TYPE_NR 9
496498

497499
/* i: Repair this metadata. */
498500
#define XFS_SCRUB_IFLAG_REPAIR (1 << 0)

fs/xfs/scrub/common.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include "xfs_refcount_btree.h"
4141
#include "xfs_rmap.h"
4242
#include "xfs_rmap_btree.h"
43+
#include "xfs_log.h"
44+
#include "xfs_trans_priv.h"
4345
#include "scrub/xfs_scrub.h"
4446
#include "scrub/scrub.h"
4547
#include "scrub/common.h"
@@ -451,11 +453,38 @@ xfs_scrub_setup_ag_btree(
451453
struct xfs_inode *ip,
452454
bool force_log)
453455
{
456+
struct xfs_mount *mp = sc->mp;
454457
int error;
455458

459+
/*
460+
* If the caller asks us to checkpont the log, do so. This
461+
* expensive operation should be performed infrequently and only
462+
* as a last resort. Any caller that sets force_log should
463+
* document why they need to do so.
464+
*/
465+
if (force_log) {
466+
error = xfs_scrub_checkpoint_log(mp);
467+
if (error)
468+
return error;
469+
}
470+
456471
error = xfs_scrub_setup_ag_header(sc, ip);
457472
if (error)
458473
return error;
459474

460475
return xfs_scrub_ag_init(sc, sc->sm->sm_agno, &sc->sa);
461476
}
477+
478+
/* Push everything out of the log onto disk. */
479+
int
480+
xfs_scrub_checkpoint_log(
481+
struct xfs_mount *mp)
482+
{
483+
int error;
484+
485+
error = _xfs_log_force(mp, XFS_LOG_SYNC, NULL);
486+
if (error)
487+
return error;
488+
xfs_ail_push_all_sync(mp->m_ail);
489+
return 0;
490+
}

fs/xfs/scrub/common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,16 @@ void xfs_scrub_fblock_set_warning(struct xfs_scrub_context *sc, int whichfork,
7373
xfs_fileoff_t offset);
7474

7575
void xfs_scrub_set_incomplete(struct xfs_scrub_context *sc);
76+
int xfs_scrub_checkpoint_log(struct xfs_mount *mp);
7677

7778
/* Setup functions */
7879
int xfs_scrub_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip);
7980
int xfs_scrub_setup_ag_header(struct xfs_scrub_context *sc,
8081
struct xfs_inode *ip);
8182
int xfs_scrub_setup_ag_allocbt(struct xfs_scrub_context *sc,
8283
struct xfs_inode *ip);
84+
int xfs_scrub_setup_ag_iallocbt(struct xfs_scrub_context *sc,
85+
struct xfs_inode *ip);
8386

8487

8588
void xfs_scrub_ag_free(struct xfs_scrub_context *sc, struct xfs_scrub_ag *sa);

0 commit comments

Comments
 (0)