summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-10-25 17:16:17 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-10-26 18:32:36 -0700
commit28b0e24a0a55b991cf5a6c4bbf6376669de5fb5a (patch)
treefef1241e2003ff817e04b14cb3d64c659103dcae
parente4cb194efbdb5d1ac8e285786f911c293a148525 (diff)
xfs: refactor realtime inode lockingrefactor-rt-locking_2020-10-26
Refactor realtime metadata inode locking so that we can get some sense here. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c7
-rw-r--r--fs/xfs/scrub/common.c7
-rw-r--r--fs/xfs/xfs_bmap_util.c5
-rw-r--r--fs/xfs/xfs_fsmap.c4
-rw-r--r--fs/xfs/xfs_rtalloc.c49
-rw-r--r--fs/xfs/xfs_rtalloc.h9
6 files changed, 58 insertions, 23 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index f267503485e1..b470f5d2053e 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5396,12 +5396,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_rtlock(tp, mp, XFS_RTLOCK_ALLOC);
}
extno = 0;
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 952dfb234bf2..971bc43d039c 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -27,6 +27,7 @@
#include "xfs_trans_priv.h"
#include "xfs_attr.h"
#include "xfs_reflink.h"
+#include "xfs_rtalloc.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -610,8 +611,7 @@ xchk_rt_init(
struct xfs_mount *mp = sc->mp;
memset(sr, 0, sizeof(*sr));
- xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
- xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+ xfs_rtlock(NULL, mp, XFS_RTLOCK_ALL);
sr->locked = true;
}
@@ -627,8 +627,7 @@ xchk_rt_unlock(
if (!sr->locked)
return;
- xfs_iunlock(sc->mp->m_rsumip, XFS_ILOCK_EXCL);
- xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_EXCL);
+ xfs_rtunlock(sc->mp, XFS_RTLOCK_ALL);
sr->locked = false;
}
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index b84226bba539..534c8657eeb5 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -118,10 +118,7 @@ xfs_bmap_rtalloc(
/*
* Lock out modifications to both the RT bitmap and summary inodes
*/
- 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_rtlock(ap->tp, mp, XFS_RTLOCK_ALLOC);
/*
* If it's an allocation to an empty file at offset 0,
diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c
index 9ce5e7d5bf8f..c8eb222a6e70 100644
--- a/fs/xfs/xfs_fsmap.c
+++ b/fs/xfs/xfs_fsmap.c
@@ -524,7 +524,7 @@ xfs_getfsmap_rtdev_rtbitmap_query(
struct xfs_rtalloc_rec ahigh = { 0 };
int error;
- xfs_ilock(tp->t_mountp->m_rbmip, XFS_ILOCK_SHARED);
+ xfs_rtlock(NULL, tp->t_mountp, XFS_RTLOCK_ALL);
alow.ar_startext = info->low.rm_startblock;
ahigh.ar_startext = info->high.rm_startblock;
@@ -542,7 +542,7 @@ xfs_getfsmap_rtdev_rtbitmap_query(
if (error)
goto err;
err:
- xfs_iunlock(tp->t_mountp->m_rbmip, XFS_ILOCK_SHARED);
+ xfs_rtunlock(tp->t_mountp, XFS_RTLOCK_ALL);
return error;
}
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 30d162643b6b..6b809a31eed2 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1025,10 +1025,10 @@ xfs_growfs_rt(
if (error)
break;
/*
- * 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_rtlock(tp, mp, XFS_RTLOCK_ALLOC);
/*
* Update the bitmap inode's size ondisk and incore. We need
* to update the incore size so that inode inactivation won't
@@ -1039,11 +1039,6 @@ xfs_growfs_rt(
i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_d.di_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
* thinks are "posteof" blocks.
@@ -1343,3 +1338,41 @@ xfs_rtpick_extent(
*pick = b;
return 0;
}
+
+/*
+ * Lock the metadata inodes for the realtime volume. If a transaction is
+ * given, the rt metadata inode will be joined to the transaction and the lock
+ * will be released on transaction commit.
+ */
+void
+xfs_rtlock(
+ struct xfs_trans *tp,
+ struct xfs_mount *mp,
+ unsigned int lock_flags)
+{
+ ASSERT(!(lock_flags & ~XFS_RTLOCK_ALL));
+
+ xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
+ if (tp)
+ xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
+
+ if (lock_flags & XFS_RTLOCK_ALLOC) {
+ xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+ if (tp)
+ xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
+ }
+}
+
+/* Unlock the realtime metadata inodes. */
+void
+xfs_rtunlock(
+ struct xfs_mount *mp,
+ unsigned int lock_flags)
+{
+ ASSERT(!(lock_flags & ~XFS_RTLOCK_ALL));
+
+ if (lock_flags & XFS_RTLOCK_ALLOC)
+ xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+
+ xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
+}
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 93e77b221355..8a22e0e74d65 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -135,6 +135,13 @@ bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
xfs_rtblock_t start, xfs_extlen_t len,
bool *is_free);
+
+#define XFS_RTLOCK_ALLOC (1 << 0) /* rt allocation */
+#define XFS_RTLOCK_ALL (XFS_RTLOCK_ALLOC)
+
+void xfs_rtlock(struct xfs_trans *tp, struct xfs_mount *mp,
+ unsigned int rtlock_flags);
+void xfs_rtunlock(struct xfs_mount *mp, unsigned int lock_flags);
#else
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS)
# define xfs_rtfree_extent(t,b,l) (ENOSYS)
@@ -157,6 +164,8 @@ xfs_rtmount_init(
}
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtunmount_inodes(m)
+# define xfs_rtlock(tp, mp, lock_flags)
+# define xfs_rtunlock(mp, lock_flags)
#endif /* CONFIG_XFS_RT */
#endif /* __XFS_RTALLOC_H__ */