summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-10-21 14:50:45 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-10-22 16:40:35 -0700
commita5b239ba7855af0f34d899b223c0956f5b94a3ce (patch)
tree075e54ba27d9fddbdb26b367d7800edf51ea9556 /fs
parent0ace451a9ea336b2e2ea1bd10226ad87ca90dcc4 (diff)
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: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/scrub/bmap.c6
-rw-r--r--fs/xfs/scrub/common.c38
-rw-r--r--fs/xfs/scrub/common.h5
-rw-r--r--fs/xfs/scrub/dir.c3
-rw-r--r--fs/xfs/scrub/inode.c7
-rw-r--r--fs/xfs/scrub/parent.c9
-rw-r--r--fs/xfs/scrub/quota.c9
-rw-r--r--fs/xfs/scrub/rtbitmap.c9
-rw-r--r--fs/xfs/scrub/scrub.c2
9 files changed, 54 insertions, 34 deletions
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index 74003a893ef7..cd6ec11c5b24 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -35,8 +35,7 @@ xchk_setup_inode_bmap(
if (error)
goto out;
- sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ xchk_ilock(sc, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL);
/*
* We don't want any ephemeral data fork updates sitting around
@@ -73,9 +72,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;
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 51c9ab42d3ad..7c7894d56320 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -729,19 +729,47 @@ xchk_setup_inode_contents(
return error;
/* Got the inode, lock it and we're ready to go. */
- sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ xchk_ilock(sc, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_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)
+{
+ sc->ilock_flags |= ilock_flags;
+ xfs_ilock(sc->ip, 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)
+{
+ xfs_iunlock(sc->ip, ilock_flags);
+ sc->ilock_flags &= ~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
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index b7fcb4733e6a..62a1da870223 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -135,6 +135,11 @@ int xchk_setup_ag_btree(struct xfs_scrub *sc, bool force_log);
int xchk_get_inode(struct xfs_scrub *sc);
int xchk_setup_inode_contents(struct xfs_scrub *sc, unsigned int resblks);
int xchk_install_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);
/*
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 200a63f58fe7..8a0cdbc53b35 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -852,8 +852,7 @@ xchk_directory(
* _dir_lookup routines, which do their own ILOCK locking.
*/
oldpos = 0;
- sc->ilock_flags &= ~XFS_ILOCK_EXCL;
- xfs_iunlock(sc->ip, XFS_ILOCK_EXCL);
+ xchk_iunlock(sc, XFS_ILOCK_EXCL);
while (true) {
error = xfs_readdir(sc->tp, sc->ip, &sdc.dir_iter, bufsize);
if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0,
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index 2405b09d03d0..5c8076c3af72 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -48,14 +48,11 @@ xchk_setup_inode(
}
/* Got the inode, lock it and we're ready to go. */
- sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ xchk_ilock(sc, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL);
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 for us */
return error;
diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c
index 354f93e62149..9dbfa4585167 100644
--- a/fs/xfs/scrub/parent.c
+++ b/fs/xfs/scrub/parent.c
@@ -185,17 +185,15 @@ xchk_parent_validate(
* try to lock the alleged parent and trylock the child.
*/
if (!xfs_ilock_nowait(dp, XFS_IOLOCK_SHARED)) {
- xfs_iunlock(sc->ip, sc->ilock_flags);
- sc->ilock_flags = 0;
+ xchk_iunlock(sc, sc->ilock_flags);
while (true) {
if (xchk_should_terminate(sc, &error))
goto out_rele;
xfs_ilock(dp, XFS_IOLOCK_SHARED);
- if (xfs_ilock_nowait(sc->ip, XFS_IOLOCK_EXCL))
+ if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
break;
xfs_iunlock(dp, XFS_IOLOCK_SHARED);
}
- sc->ilock_flags = XFS_IOLOCK_EXCL;
/*
* Now that we've locked out updates to the child directory,
@@ -266,8 +264,7 @@ xchk_parent(
* getting a write lock on i_rwsem. Therefore, it is safe for us
* to drop the ILOCK here in order to do directory lookups.
*/
- sc->ilock_flags &= ~(XFS_ILOCK_EXCL | XFS_MMAPLOCK_EXCL);
- xfs_iunlock(sc->ip, XFS_ILOCK_EXCL | XFS_MMAPLOCK_EXCL);
+ xchk_iunlock(sc, XFS_ILOCK_EXCL | XFS_MMAPLOCK_EXCL);
/* Look up '..' */
error = xfs_dir_lookup(sc->tp, sc->ip, &xfs_name_dotdot, &parent_ino,
diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 9200fc2fdf31..742bcdc9d997 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -61,8 +61,7 @@ xchk_setup_quota(
if (error)
return error;
- xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
- sc->ilock_flags = XFS_ILOCK_EXCL;
+ xchk_ilock(sc, XFS_ILOCK_EXCL);
return 0;
}
@@ -236,13 +235,11 @@ xchk_quota(
* data fork we have to drop ILOCK_EXCL to use the regular dquot
* functions.
*/
- xfs_iunlock(sc->ip, sc->ilock_flags);
- sc->ilock_flags = 0;
+ xchk_iunlock(sc, sc->ilock_flags);
sqi.sc = sc;
sqi.last_id = 0;
error = xfs_qm_dqiterate(mp, dqtype, xchk_quota_item, &sqi);
- sc->ilock_flags = XFS_ILOCK_EXCL;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ xchk_ilock(sc, XFS_ILOCK_EXCL);
if (error == -ECANCELED)
error = 0;
if (!xchk_fblock_process_error(sc, XFS_DATA_FORK,
diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
index 907389236033..02320c36a8de 100644
--- a/fs/xfs/scrub/rtbitmap.c
+++ b/fs/xfs/scrub/rtbitmap.c
@@ -32,8 +32,7 @@ xchk_setup_rt(
if (error)
return error;
- sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
return 0;
}
@@ -142,8 +141,8 @@ xchk_rtsummary(
* flags so that we don't mix up the inode state that @sc tracks.
*/
sc->ip = rsumip;
- sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM;
- xfs_ilock(sc->ip, sc->ilock_flags);
+ sc->ilock_flags = 0;
+ xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
/* Invoke the fork scrubber. */
error = xchk_metadata_inode_forks(sc);
@@ -154,7 +153,7 @@ xchk_rtsummary(
xchk_set_incomplete(sc);
out:
/* 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->ip = old_ip;
return error;
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 31c848d15127..bf0fef90b475 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -163,7 +163,7 @@ xchk_teardown(
}
if (sc->ip) {
if (sc->ilock_flags)
- xfs_iunlock(sc->ip, sc->ilock_flags);
+ xchk_iunlock(sc, sc->ilock_flags);
xfs_irele(sc->ip);
sc->ip = NULL;
}