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

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
...@@ -38,8 +38,7 @@ xchk_setup_inode_bmap( ...@@ -38,8 +38,7 @@ xchk_setup_inode_bmap(
if (error) if (error)
goto out; goto out;
sc->ilock_flags = XFS_IOLOCK_EXCL; xchk_ilock(sc, XFS_IOLOCK_EXCL);
xfs_ilock(sc->ip, XFS_IOLOCK_EXCL);
/* /*
* We don't want any ephemeral data/cow fork updates sitting around * We don't want any ephemeral data/cow fork updates sitting around
...@@ -50,8 +49,7 @@ xchk_setup_inode_bmap( ...@@ -50,8 +49,7 @@ xchk_setup_inode_bmap(
sc->sm->sm_type != XFS_SCRUB_TYPE_BMBTA) { sc->sm->sm_type != XFS_SCRUB_TYPE_BMBTA) {
struct address_space *mapping = VFS_I(sc->ip)->i_mapping; struct address_space *mapping = VFS_I(sc->ip)->i_mapping;
sc->ilock_flags |= XFS_MMAPLOCK_EXCL; xchk_ilock(sc, XFS_MMAPLOCK_EXCL);
xfs_ilock(sc->ip, XFS_MMAPLOCK_EXCL);
inode_dio_wait(VFS_I(sc->ip)); inode_dio_wait(VFS_I(sc->ip));
...@@ -79,9 +77,8 @@ xchk_setup_inode_bmap( ...@@ -79,9 +77,8 @@ xchk_setup_inode_bmap(
error = xchk_trans_alloc(sc, 0); error = xchk_trans_alloc(sc, 0);
if (error) if (error)
goto out; goto out;
sc->ilock_flags |= XFS_ILOCK_EXCL;
xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
xchk_ilock(sc, XFS_ILOCK_EXCL);
out: out:
/* scrub teardown will unlock and release the inode */ /* scrub teardown will unlock and release the inode */
return error; return error;
......
...@@ -1022,20 +1022,48 @@ xchk_setup_inode_contents( ...@@ -1022,20 +1022,48 @@ xchk_setup_inode_contents(
return error; return error;
/* Lock the inode so the VFS cannot touch this file. */ /* Lock the inode so the VFS cannot touch this file. */
sc->ilock_flags = XFS_IOLOCK_EXCL; xchk_ilock(sc, XFS_IOLOCK_EXCL);
xfs_ilock(sc->ip, sc->ilock_flags);
error = xchk_trans_alloc(sc, resblks); error = xchk_trans_alloc(sc, resblks);
if (error) if (error)
goto out; goto out;
sc->ilock_flags |= XFS_ILOCK_EXCL; xchk_ilock(sc, XFS_ILOCK_EXCL);
xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
out: out:
/* scrub teardown will unlock and release the inode for us */ /* scrub teardown will unlock and release the inode for us */
return error; 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. * Predicate that decides if we need to evaluate the cross-reference check.
* If there was an error accessing the cross-reference btree, just delete * If there was an error accessing the cross-reference btree, just delete
......
...@@ -138,6 +138,11 @@ int xchk_setup_ag_btree(struct xfs_scrub *sc, bool force_log); ...@@ -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_iget_for_scrubbing(struct xfs_scrub *sc);
int xchk_setup_inode_contents(struct xfs_scrub *sc, unsigned int resblks); 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); 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); 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); int xchk_iget(struct xfs_scrub *sc, xfs_ino_t inum, struct xfs_inode **ipp);
......
...@@ -32,15 +32,13 @@ xchk_prepare_iscrub( ...@@ -32,15 +32,13 @@ xchk_prepare_iscrub(
{ {
int error; int error;
sc->ilock_flags = XFS_IOLOCK_EXCL; xchk_ilock(sc, XFS_IOLOCK_EXCL);
xfs_ilock(sc->ip, sc->ilock_flags);
error = xchk_trans_alloc(sc, 0); error = xchk_trans_alloc(sc, 0);
if (error) if (error)
return error; return error;
sc->ilock_flags |= XFS_ILOCK_EXCL; xchk_ilock(sc, XFS_ILOCK_EXCL);
xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
return 0; return 0;
} }
......
...@@ -150,8 +150,8 @@ xchk_parent_validate( ...@@ -150,8 +150,8 @@ xchk_parent_validate(
lock_mode = xchk_parent_ilock_dir(dp); lock_mode = xchk_parent_ilock_dir(dp);
if (!lock_mode) { if (!lock_mode) {
xfs_iunlock(sc->ip, XFS_ILOCK_EXCL); xchk_iunlock(sc, XFS_ILOCK_EXCL);
xfs_ilock(sc->ip, XFS_ILOCK_EXCL); xchk_ilock(sc, XFS_ILOCK_EXCL);
error = -EAGAIN; error = -EAGAIN;
goto out_rele; goto out_rele;
} }
......
...@@ -64,8 +64,7 @@ xchk_setup_quota( ...@@ -64,8 +64,7 @@ xchk_setup_quota(
if (error) if (error)
return error; return error;
xfs_ilock(sc->ip, XFS_ILOCK_EXCL); xchk_ilock(sc, XFS_ILOCK_EXCL);
sc->ilock_flags = XFS_ILOCK_EXCL;
return 0; return 0;
} }
...@@ -239,13 +238,11 @@ xchk_quota( ...@@ -239,13 +238,11 @@ xchk_quota(
* data fork we have to drop ILOCK_EXCL to use the regular dquot * data fork we have to drop ILOCK_EXCL to use the regular dquot
* functions. * functions.
*/ */
xfs_iunlock(sc->ip, sc->ilock_flags); xchk_iunlock(sc, sc->ilock_flags);
sc->ilock_flags = 0;
sqi.sc = sc; sqi.sc = sc;
sqi.last_id = 0; sqi.last_id = 0;
error = xfs_qm_dqiterate(mp, dqtype, xchk_quota_item, &sqi); error = xfs_qm_dqiterate(mp, dqtype, xchk_quota_item, &sqi);
sc->ilock_flags = XFS_ILOCK_EXCL; xchk_ilock(sc, XFS_ILOCK_EXCL);
xfs_ilock(sc->ip, sc->ilock_flags);
if (error == -ECANCELED) if (error == -ECANCELED)
error = 0; error = 0;
if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, if (!xchk_fblock_process_error(sc, XFS_DATA_FORK,
......
...@@ -32,8 +32,7 @@ xchk_setup_rt( ...@@ -32,8 +32,7 @@ xchk_setup_rt(
if (error) if (error)
return error; return error;
sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP; xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
xfs_ilock(sc->ip, sc->ilock_flags);
return 0; return 0;
} }
...@@ -143,8 +142,8 @@ xchk_rtsummary( ...@@ -143,8 +142,8 @@ xchk_rtsummary(
* flags so that we don't mix up the inode state that @sc tracks. * flags so that we don't mix up the inode state that @sc tracks.
*/ */
sc->ip = rsumip; sc->ip = rsumip;
sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM; sc->ilock_flags = 0;
xfs_ilock(sc->ip, sc->ilock_flags); xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
/* Invoke the fork scrubber. */ /* Invoke the fork scrubber. */
error = xchk_metadata_inode_forks(sc); error = xchk_metadata_inode_forks(sc);
...@@ -155,7 +154,7 @@ xchk_rtsummary( ...@@ -155,7 +154,7 @@ xchk_rtsummary(
xchk_set_incomplete(sc); xchk_set_incomplete(sc);
out: out:
/* Switch back to the rtbitmap inode and lock flags. */ /* Switch back to the rtbitmap inode and lock flags. */
xfs_iunlock(sc->ip, sc->ilock_flags); xchk_iunlock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
sc->ilock_flags = old_ilock_flags; sc->ilock_flags = old_ilock_flags;
sc->ip = old_ip; sc->ip = old_ip;
return error; return error;
......
...@@ -177,7 +177,7 @@ xchk_teardown( ...@@ -177,7 +177,7 @@ xchk_teardown(
} }
if (sc->ip) { if (sc->ip) {
if (sc->ilock_flags) if (sc->ilock_flags)
xfs_iunlock(sc->ip, sc->ilock_flags); xchk_iunlock(sc, sc->ilock_flags);
xchk_irele(sc, sc->ip); xchk_irele(sc, sc->ip);
sc->ip = NULL; sc->ip = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment