Commit 17308539 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: get our own reference to inodes that we want to scrub



When we want to scrub a file, get our own reference to the inode
unconditionally.  This will make disposal rules simpler in the long run.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent d7a74cad
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -831,6 +831,25 @@ xchk_install_handle_inode(
	return 0;
}

/*
 * Install an already-referenced inode for scrubbing.  Get our own reference to
 * the inode to make disposal simpler.  The inode must not be in I_FREEING or
 * I_WILL_FREE state!
 */
int
xchk_install_live_inode(
	struct xfs_scrub	*sc,
	struct xfs_inode	*ip)
{
	if (!igrab(VFS_I(ip))) {
		xchk_ino_set_corrupt(sc, ip->i_ino);
		return -EFSCORRUPTED;
	}

	sc->ip = ip;
	return 0;
}

/*
 * In preparation to scrub metadata structures that hang off of an inode,
 * grab either the inode referenced in the scrub control structure or the
@@ -854,10 +873,8 @@ xchk_iget_for_scrubbing(
	ASSERT(sc->tp == NULL);

	/* 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;
	}
	if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino)
		return xchk_install_live_inode(sc, ip_in);

	/* Reject internal metadata files and obviously bad inode numbers. */
	if (xfs_internal_inum(mp, sc->sm->sm_ino))
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
int xchk_setup_ag_btree(struct xfs_scrub *sc, bool force_log);
int xchk_iget_for_scrubbing(struct xfs_scrub *sc);
int xchk_setup_inode_contents(struct xfs_scrub *sc, unsigned int resblks);
int xchk_install_live_inode(struct xfs_scrub *sc, struct xfs_inode *ip);
void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);

int xchk_iget(struct xfs_scrub *sc, xfs_ino_t inum, struct xfs_inode **ipp);
+4 −1
Original line number Diff line number Diff line
@@ -83,7 +83,10 @@ xchk_setup_inode(

	/* We want to scan the opened inode, so lock it and exit. */
	if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
		sc->ip = ip_in;
		error = xchk_install_live_inode(sc, ip_in);
		if (error)
			return error;

		return xchk_prepare_iscrub(sc);
	}

+5 −1
Original line number Diff line number Diff line
@@ -59,7 +59,11 @@ xchk_setup_quota(
	error = xchk_setup_fs(sc);
	if (error)
		return error;
	sc->ip = xfs_quota_inode(sc->mp, dqtype);

	error = xchk_install_live_inode(sc, xfs_quota_inode(sc->mp, dqtype));
	if (error)
		return error;

	xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
	sc->ilock_flags = XFS_ILOCK_EXCL;
	return 0;
+4 −2
Original line number Diff line number Diff line
@@ -28,10 +28,12 @@ xchk_setup_rt(
	if (error)
		return error;

	error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
	if (error)
		return error;

	sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
	sc->ip = sc->mp->m_rbmip;
	xfs_ilock(sc->ip, sc->ilock_flags);

	return 0;
}

Loading