Skip to content

Commit

Permalink
xfs: scrub inodes
Browse files Browse the repository at this point in the history
Scrub the fields within an inode.

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 edc09b5 commit 80e4e12
Show file tree
Hide file tree
Showing 8 changed files with 693 additions and 3 deletions.
1 change: 1 addition & 0 deletions fs/xfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ xfs-y += $(addprefix scrub/, \
btree.o \
common.o \
ialloc.o \
inode.o \
refcount.o \
rmap.o \
scrub.o \
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/libxfs/xfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,10 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_FINOBT 8 /* free inode btree */
#define XFS_SCRUB_TYPE_RMAPBT 9 /* reverse mapping btree */
#define XFS_SCRUB_TYPE_REFCNTBT 10 /* reference count btree */
#define XFS_SCRUB_TYPE_INODE 11 /* inode record */

/* Number of scrub subcommands. */
#define XFS_SCRUB_TYPE_NR 11
#define XFS_SCRUB_TYPE_NR 12

/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR (1 << 0)
Expand Down
54 changes: 54 additions & 0 deletions fs/xfs/scrub/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_inode.h"
#include "xfs_icache.h"
#include "xfs_itable.h"
#include "xfs_alloc.h"
#include "xfs_alloc_btree.h"
#include "xfs_bmap.h"
Expand Down Expand Up @@ -488,3 +490,55 @@ xfs_scrub_checkpoint_log(
xfs_ail_push_all_sync(mp->m_ail);
return 0;
}

/*
* Given an inode and the scrub control structure, grab either the
* inode referenced in the control structure or the inode passed in.
* The inode is not locked.
*/
int
xfs_scrub_get_inode(
struct xfs_scrub_context *sc,
struct xfs_inode *ip_in)
{
struct xfs_mount *mp = sc->mp;
struct xfs_inode *ip = NULL;
int error;

/*
* If userspace passed us an AG number or a generation number
* without an inode number, they haven't got a clue so bail out
* immediately.
*/
if (sc->sm->sm_agno || (sc->sm->sm_gen && !sc->sm->sm_ino))
return -EINVAL;

/* We want to scan the inode we already had opened. */
if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
sc->ip = ip_in;
return 0;
}

/* Look up the inode, see if the generation number matches. */
if (xfs_internal_inum(mp, sc->sm->sm_ino))
return -ENOENT;
error = xfs_iget(mp, NULL, sc->sm->sm_ino,
XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE, 0, &ip);
if (error == -ENOENT || error == -EINVAL) {
/* inode doesn't exist... */
return -ENOENT;
} else if (error) {
trace_xfs_scrub_op_error(sc,
XFS_INO_TO_AGNO(mp, sc->sm->sm_ino),
XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino),
error, __return_address);
return error;
}
if (VFS_I(ip)->i_generation != sc->sm->sm_gen) {
iput(VFS_I(ip));
return -ENOENT;
}

sc->ip = ip;
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 @@ -87,6 +87,8 @@ int xfs_scrub_setup_ag_rmapbt(struct xfs_scrub_context *sc,
struct xfs_inode *ip);
int xfs_scrub_setup_ag_refcountbt(struct xfs_scrub_context *sc,
struct xfs_inode *ip);
int xfs_scrub_setup_inode(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 All @@ -105,5 +107,6 @@ int xfs_scrub_walk_agfl(struct xfs_scrub_context *sc,

int xfs_scrub_setup_ag_btree(struct xfs_scrub_context *sc,
struct xfs_inode *ip, bool force_log);
int xfs_scrub_get_inode(struct xfs_scrub_context *sc, struct xfs_inode *ip_in);

#endif /* __XFS_SCRUB_COMMON_H__ */
Loading

0 comments on commit 80e4e12

Please sign in to comment.