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

xfs: wrap ilock/iunlock operations on sc->ip



Scrub tracks the resources that it's holding onto in the xfs_scrub
structure.  This includes the inode being checked (if applicable) and
the inode lock state of that inode.  Replace the open-coded structure
manipulation with a trivial helper to eliminate sources of error.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 17308539
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -38,8 +38,7 @@ xchk_setup_inode_bmap(
	if (error)
		goto out;

	sc->ilock_flags = XFS_IOLOCK_EXCL;
	xfs_ilock(sc->ip, XFS_IOLOCK_EXCL);
	xchk_ilock(sc, XFS_IOLOCK_EXCL);

	/*
	 * We don't want any ephemeral data/cow fork updates sitting around
@@ -50,8 +49,7 @@ xchk_setup_inode_bmap(
	    sc->sm->sm_type != XFS_SCRUB_TYPE_BMBTA) {
		struct address_space	*mapping = VFS_I(sc->ip)->i_mapping;

		sc->ilock_flags |= XFS_MMAPLOCK_EXCL;
		xfs_ilock(sc->ip, XFS_MMAPLOCK_EXCL);
		xchk_ilock(sc, XFS_MMAPLOCK_EXCL);

		inode_dio_wait(VFS_I(sc->ip));

@@ -79,9 +77,8 @@ xchk_setup_inode_bmap(
	error = xchk_trans_alloc(sc, 0);
	if (error)
		goto out;
	sc->ilock_flags |= XFS_ILOCK_EXCL;
	xfs_ilock(sc->ip, XFS_ILOCK_EXCL);

	xchk_ilock(sc, XFS_ILOCK_EXCL);
out:
	/* scrub teardown will unlock and release the inode */
	return error;
+33 −5
Original line number Diff line number Diff line
@@ -1022,20 +1022,48 @@ xchk_setup_inode_contents(
		return error;

	/* Lock the inode so the VFS cannot touch this file. */
	sc->ilock_flags = XFS_IOLOCK_EXCL;
	xfs_ilock(sc->ip, sc->ilock_flags);
	xchk_ilock(sc, XFS_IOLOCK_EXCL);

	error = xchk_trans_alloc(sc, resblks);
	if (error)
		goto out;
	sc->ilock_flags |= XFS_ILOCK_EXCL;
	xfs_ilock(sc->ip, XFS_ILOCK_EXCL);

	xchk_ilock(sc, XFS_ILOCK_EXCL);
out:
	/* scrub teardown will unlock and release the inode for us */
	return error;
}

void
xchk_ilock(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{
	xfs_ilock(sc->ip, ilock_flags);
	sc->ilock_flags |= ilock_flags;
}

bool
xchk_ilock_nowait(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{
	if (xfs_ilock_nowait(sc->ip, ilock_flags)) {
		sc->ilock_flags |= ilock_flags;
		return true;
	}

	return false;
}

void
xchk_iunlock(
	struct xfs_scrub	*sc,
	unsigned int		ilock_flags)
{
	sc->ilock_flags &= ~ilock_flags;
	xfs_iunlock(sc->ip, ilock_flags);
}

/*
 * Predicate that decides if we need to evaluate the cross-reference check.
 * If there was an error accessing the cross-reference btree, just delete
+5 −0
Original line number Diff line number Diff line
@@ -138,6 +138,11 @@ 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_ilock(struct xfs_scrub *sc, unsigned int ilock_flags);
bool xchk_ilock_nowait(struct xfs_scrub *sc, unsigned int ilock_flags);
void xchk_iunlock(struct xfs_scrub *sc, unsigned int ilock_flags);

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);
+2 −4
Original line number Diff line number Diff line
@@ -32,15 +32,13 @@ xchk_prepare_iscrub(
{
	int			error;

	sc->ilock_flags = XFS_IOLOCK_EXCL;
	xfs_ilock(sc->ip, sc->ilock_flags);
	xchk_ilock(sc, XFS_IOLOCK_EXCL);

	error = xchk_trans_alloc(sc, 0);
	if (error)
		return error;

	sc->ilock_flags |= XFS_ILOCK_EXCL;
	xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
	xchk_ilock(sc, XFS_ILOCK_EXCL);
	return 0;
}

+2 −2
Original line number Diff line number Diff line
@@ -150,8 +150,8 @@ xchk_parent_validate(

	lock_mode = xchk_parent_ilock_dir(dp);
	if (!lock_mode) {
		xfs_iunlock(sc->ip, XFS_ILOCK_EXCL);
		xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
		xchk_iunlock(sc, XFS_ILOCK_EXCL);
		xchk_ilock(sc, XFS_ILOCK_EXCL);
		error = -EAGAIN;
		goto out_rele;
	}
Loading