]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: refactor realtime inode locking
authorChristoph Hellwig <hch@lst.de>
Mon, 22 Apr 2024 11:20:08 +0000 (13:20 +0200)
committerChandan Babu R <chandanbabu@kernel.org>
Mon, 22 Apr 2024 12:30:47 +0000 (18:00 +0530)
Create helper functions to deal with locking realtime metadata inodes.
This enables us to maintain correct locking order once we start adding
the realtime rmap and refcount btree inodes.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/libxfs/xfs_rtbitmap.h
fs/xfs/scrub/common.c
fs/xfs/scrub/fscounters.c
fs/xfs/xfs_fsmap.c
fs/xfs/xfs_rtalloc.c

index 59b8b9dc29ccff9f44ad301c987317ffadc3b38d..3e56173a8fe4db0388103fafaff0266d75d017f4 100644 (file)
@@ -5418,12 +5418,9 @@ __xfs_bunmapi(
 
        if (isrt) {
                /*
-                * Synchronize by locking the bitmap inode.
+                * Synchronize by locking the realtime bitmap.
                 */
-               xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
-               xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
-               xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
-               xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
+               xfs_rtbitmap_lock(tp, mp);
        }
 
        extno = 0;
index f246d6dbf4eca8f7ac6d89c1928b020efb9dfa47..386b672c505896b524c0a1dbf5bb5f93ae4a6d92 100644 (file)
@@ -1168,3 +1168,60 @@ xfs_rtsummary_wordcount(
        blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
        return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
 }
+
+/*
+ * Lock both realtime free space metadata inodes for a freespace update.  If a
+ * transaction is given, the inodes will be joined to the transaction and the
+ * ILOCKs will be released on transaction commit.
+ */
+void
+xfs_rtbitmap_lock(
+       struct xfs_trans        *tp,
+       struct xfs_mount        *mp)
+{
+       xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
+       if (tp)
+               xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
+
+       xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+       if (tp)
+               xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
+}
+
+/* Unlock both realtime free space metadata inodes after a freespace update. */
+void
+xfs_rtbitmap_unlock(
+       struct xfs_mount        *mp)
+{
+       xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+       xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
+}
+
+/*
+ * Lock the realtime free space metadata inodes for a freespace scan.  Callers
+ * must walk metadata blocks in order of increasing file offset.
+ */
+void
+xfs_rtbitmap_lock_shared(
+       struct xfs_mount        *mp,
+       unsigned int            rbmlock_flags)
+{
+       if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
+               xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+
+       if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
+               xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
+}
+
+/* Unlock the realtime free space metadata inodes after a freespace scan. */
+void
+xfs_rtbitmap_unlock_shared(
+       struct xfs_mount        *mp,
+       unsigned int            rbmlock_flags)
+{
+       if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
+               xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
+
+       if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
+               xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+}
index 152a66750af554d91a0641ae9a3ed1011ffb7386..6186585f2c376d97ba1d20b1a0666147d34c55b7 100644 (file)
@@ -360,6 +360,19 @@ xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
                unsigned int rsumlevels, xfs_extlen_t rbmblocks);
 unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
                unsigned int rsumlevels, xfs_extlen_t rbmblocks);
+
+void xfs_rtbitmap_lock(struct xfs_trans *tp, struct xfs_mount *mp);
+void xfs_rtbitmap_unlock(struct xfs_mount *mp);
+
+/* Lock the rt bitmap inode in shared mode */
+#define XFS_RBMLOCK_BITMAP     (1U << 0)
+/* Lock the rt summary inode in shared mode */
+#define XFS_RBMLOCK_SUMMARY    (1U << 1)
+
+void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
+               unsigned int rbmlock_flags);
+void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
+               unsigned int rbmlock_flags);
 #else /* CONFIG_XFS_RT */
 # define xfs_rtfree_extent(t,b,l)                      (-ENOSYS)
 # define xfs_rtfree_blocks(t,rb,rl)                    (-ENOSYS)
@@ -378,6 +391,10 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
 # define xfs_rtbitmap_wordcount(mp, r)                 (0)
 # define xfs_rtsummary_blockcount(mp, l, b)            (0)
 # define xfs_rtsummary_wordcount(mp, l, b)             (0)
+# define xfs_rtbitmap_lock(tp, mp)             do { } while (0)
+# define xfs_rtbitmap_unlock(mp)               do { } while (0)
+# define xfs_rtbitmap_lock_shared(mp, lf)      do { } while (0)
+# define xfs_rtbitmap_unlock_shared(mp, lf)    do { } while (0)
 #endif /* CONFIG_XFS_RT */
 
 #endif /* __XFS_RTBITMAP_H__ */
index 48302532d10d136e099a05c7d2cf60987788d1f1..a7d3a22796620c4aa806278b0f8f6bbaef95aa96 100644 (file)
@@ -32,6 +32,7 @@
 #include "xfs_error.h"
 #include "xfs_quota.h"
 #include "xfs_exchmaps.h"
+#include "xfs_rtbitmap.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
 #include "scrub/trace.h"
index da2f6729699dd43571833be2326a1044986bda7e..67ac870052b16dbcb221d0115cea60b083da4d2d 100644 (file)
@@ -415,7 +415,7 @@ xchk_fscount_count_frextents(
        if (!xfs_has_realtime(mp))
                return 0;
 
-       xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_lock_shared(sc->mp, XFS_RBMLOCK_BITMAP);
        error = xfs_rtalloc_query_all(sc->mp, sc->tp,
                        xchk_fscount_add_frextent, fsc);
        if (error) {
@@ -424,7 +424,7 @@ xchk_fscount_count_frextents(
        }
 
 out_unlock:
-       xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_unlock_shared(sc->mp, XFS_RBMLOCK_BITMAP);
        return error;
 }
 #else
index de59eec747657559394d2911727b305c61d443ed..85dbb46452ca0be31b686e2c1e35e3a9287cef70 100644 (file)
@@ -533,7 +533,7 @@ xfs_getfsmap_rtdev_rtbitmap(
        trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb);
        trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb);
 
-       xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP);
 
        /*
         * Set up query parameters to return free rtextents covering the range
@@ -557,7 +557,7 @@ xfs_getfsmap_rtdev_rtbitmap(
        if (error)
                goto err;
 err:
-       xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP);
        return error;
 }
 #endif /* CONFIG_XFS_RT */
index e66f9bd5de5cff19f851f6b71655dd95f8af1a0d..86f928d30feda9f1a1dee6da4efd7e598ca52ebd 100644 (file)
@@ -957,10 +957,10 @@ xfs_growfs_rt(
                nargs.tp = tp;
 
                /*
-                * Lock out other callers by grabbing the bitmap inode lock.
+                * Lock out other callers by grabbing the bitmap and summary
+                * inode locks and joining them to the transaction.
                 */
-               xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
-               xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
+               xfs_rtbitmap_lock(tp, mp);
                /*
                 * Update the bitmap inode's size ondisk and incore.  We need
                 * to update the incore size so that inode inactivation won't
@@ -970,11 +970,6 @@ xfs_growfs_rt(
                        nsbp->sb_rbmblocks * nsbp->sb_blocksize;
                i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_disk_size);
                xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
-               /*
-                * Get the summary inode into the transaction.
-                */
-               xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
-               xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
                /*
                 * Update the summary inode's size.  We need to update the
                 * incore size so that inode inactivation won't punch what it
@@ -1142,10 +1137,10 @@ xfs_rtalloc_reinit_frextents(
        uint64_t                val = 0;
        int                     error;
 
-       xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP);
        error = xfs_rtalloc_query_all(mp, NULL, xfs_rtalloc_count_frextent,
                        &val);
-       xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP);
        if (error)
                return error;
 
@@ -1382,10 +1377,7 @@ retry:
         * Lock out modifications to both the RT bitmap and summary inodes
         */
        if (!rtlocked) {
-               xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
-               xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
-               xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
-               xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
+               xfs_rtbitmap_lock(ap->tp, mp);
                rtlocked = true;
        }