summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-02-04 18:51:58 -0800
committerDarrick J. Wong <djwong@kernel.org>2021-08-25 22:25:52 -0700
commit7f70237c4828edb8e96da6a3f69cf943b8c773d6 (patch)
tree0f3267e1cce845eade2b98ee1f9044018193b9e0
parent18c6960dbb452bd154351c74483ee33f3037f993 (diff)
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: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/scrub/common.c24
-rw-r--r--fs/xfs/scrub/common.h1
-rw-r--r--fs/xfs/scrub/quota.c6
-rw-r--r--fs/xfs/scrub/rtbitmap.c6
-rw-r--r--fs/xfs/scrub/scrub.c6
5 files changed, 31 insertions, 12 deletions
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index d40a98507555..9bdd81bca382 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -633,6 +633,24 @@ xchk_checkpoint_log(
}
/*
+ * We want to scan the inode that was passed in. Get our own reference to the
+ * inode to make disposal simpler. The inode had better not be in I_FREEING
+ * or I_WILL_FREE state!
+ */
+int
+xchk_install_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;
+}
+
+/*
* 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.
@@ -648,10 +666,8 @@ xchk_get_inode(
int error;
/* 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_inode(sc, ip_in);
/* Look up the inode, see if the generation number matches. */
if (xfs_internal_inum(mp, sc->sm->sm_ino))
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index 454145db10e7..645e22b5d0b8 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -134,6 +134,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_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_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);
/*
diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 5ae515ffd0bf..175055131937 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -56,7 +56,11 @@ xchk_setup_quota(
error = xchk_setup_fs(sc);
if (error)
return error;
- sc->ip = xfs_quota_inode(sc->mp, dqtype);
+
+ error = xchk_install_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;
diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
index 8fa012057405..907389236033 100644
--- a/fs/xfs/scrub/rtbitmap.c
+++ b/fs/xfs/scrub/rtbitmap.c
@@ -28,10 +28,12 @@ xchk_setup_rt(
if (error)
return error;
+ error = xchk_install_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;
}
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 9c73951fc4d3..20a92bbb8af7 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -153,8 +153,6 @@ xchk_teardown(
struct xfs_scrub *sc,
int error)
{
- struct xfs_inode *ip_in = XFS_I(file_inode(sc->file));
-
xchk_ag_free(sc, &sc->sa);
if (sc->tp) {
if (error == 0 && (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR))
@@ -166,9 +164,7 @@ xchk_teardown(
if (sc->ip) {
if (sc->ilock_flags)
xfs_iunlock(sc->ip, sc->ilock_flags);
- if (sc->ip != ip_in &&
- !xfs_internal_inum(sc->mp, sc->ip->i_ino))
- xfs_irele(sc->ip);
+ xfs_irele(sc->ip);
sc->ip = NULL;
}
if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)