xfs: wrap ilock/iunlock operations on sc->ip
authorDarrick J. Wong <djwong@kernel.org>
Thu, 10 Aug 2023 14:48:08 +0000 (07:48 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 10 Aug 2023 14:48:08 +0000 (07:48 -0700)
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>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/scrub/bmap.c
fs/xfs/scrub/common.c
fs/xfs/scrub/common.h
fs/xfs/scrub/inode.c
fs/xfs/scrub/parent.c
fs/xfs/scrub/quota.c
fs/xfs/scrub/rtbitmap.c
fs/xfs/scrub/scrub.c

index 5bf4326..20ab5d4 100644 (file)
@@ -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;
index 6354cb4..82d2a85 100644 (file)
@@ -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
index 065d4bb..6495a39 100644 (file)
@@ -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);
index 1d8097f..59d7912 100644 (file)
@@ -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;
 }
 
index 58d5dfb..e6155d8 100644 (file)
@@ -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;
        }
index 19bf7f1..5671c81 100644 (file)
@@ -64,8 +64,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;
 }
 
@@ -239,13 +238,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,
index 3bd4d0a..d42e5fc 100644 (file)
@@ -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;
 }
 
@@ -143,8 +142,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);
@@ -155,7 +154,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;
index 91de2b5..2e87739 100644 (file)
@@ -177,7 +177,7 @@ xchk_teardown(
        }
        if (sc->ip) {
                if (sc->ilock_flags)
-                       xfs_iunlock(sc->ip, sc->ilock_flags);
+                       xchk_iunlock(sc, sc->ilock_flags);
                xchk_irele(sc, sc->ip);
                sc->ip = NULL;
        }