summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c7
-rw-r--r--fs/xfs/scrub/common.c7
-rw-r--r--fs/xfs/scrub/fscounters.c4
-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
-rw-r--r--fs/xfs/xfs_trace.c1
8 files changed, 61 insertions, 25 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 1512fcae5c72..054abdefab3f 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5394,12 +5394,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 6575d5392d0d..615032d69078 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -28,6 +28,7 @@
#include "xfs_reflink.h"
#include "xfs_ag.h"
#include "xfs_error.h"
+#include "xfs_rtalloc.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -609,8 +610,7 @@ xchk_rt_init(
struct xfs_scrub *sc,
struct xchk_rt *sr)
{
- xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
- xfs_ilock(sc->mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
+ xfs_rtlock(NULL, sc->mp, XFS_RTLOCK_ALL);
sr->locked = true;
}
@@ -626,8 +626,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/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c
index d231aca7daa6..f7e7ae58b4a4 100644
--- a/fs/xfs/scrub/fscounters.c
+++ b/fs/xfs/scrub/fscounters.c
@@ -316,7 +316,7 @@ xchk_fscount_check_frextents(
}
fsc->frextents = 0;
- xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_EXCL);
+ xfs_rtlock(NULL, sc->mp, XFS_RTLOCK_ALL);
error = xfs_rtalloc_query_all(sc->tp, xchk_fscount_add_frextent, fsc);
if (error)
goto out_unlock;
@@ -335,7 +335,7 @@ xchk_fscount_check_frextents(
spin_unlock(&mp->m_sb_lock);
out_unlock:
- xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_EXCL);
+ xfs_rtunlock(sc->mp, XFS_RTLOCK_ALL);
return error;
}
#else
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index f43f1d434fe2..facddb293efa 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -133,10 +133,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_rtlock(ap->tp, mp, XFS_RTLOCK_ALLOC);
rtlocked = true;
}
diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c
index 48287caad28b..3775abe656cf 100644
--- a/fs/xfs/xfs_fsmap.c
+++ b/fs/xfs/xfs_fsmap.c
@@ -524,7 +524,7 @@ xfs_getfsmap_rtdev_rtbitmap_query(
struct xfs_mount *mp = tp->t_mountp;
int error;
- xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED);
+ xfs_rtlock(NULL, mp, XFS_RTLOCK_ALL);
/*
* Set up query parameters to return free rtextents covering the range
@@ -551,7 +551,7 @@ xfs_getfsmap_rtdev_rtbitmap_query(
if (error)
goto err;
err:
- xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED);
+ xfs_rtunlock(mp, XFS_RTLOCK_ALL);
return error;
}
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 49a006c9f1e3..061066c848de 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1055,10 +1055,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
@@ -1069,11 +1069,6 @@ xfs_growfs_rt(
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
* thinks are "posteof" blocks.
@@ -1538,3 +1533,41 @@ err:
xfs_trans_cancel(tp);
return ret;
}
+
+/*
+ * 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));
+
+ if (lock_flags & XFS_RTLOCK_ALLOC) {
+ 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 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 ca6ee2f13cbc..a0d0e161d804 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -140,6 +140,13 @@ int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
bool *is_free);
int xfs_rtfile_convert_unwritten(struct xfs_inode *ip, loff_t pos,
uint64_t len);
+
+#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)
@@ -164,6 +171,8 @@ xfs_rtmount_init(
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtunmount_inodes(m)
# define xfs_rtfile_convert_unwritten(ip, pos, len) (0)
+# define xfs_rtlock(tp, mp, lock_flags) do { } while (0)
+# define xfs_rtunlock(mp, lock_flags) do { } while (0)
#endif /* CONFIG_XFS_RT */
#endif /* __XFS_RTALLOC_H__ */
diff --git a/fs/xfs/xfs_trace.c b/fs/xfs/xfs_trace.c
index d1ea002903fa..5ba31c21ecb9 100644
--- a/fs/xfs/xfs_trace.c
+++ b/fs/xfs/xfs_trace.c
@@ -37,6 +37,7 @@
#include "xfs_bmap.h"
#include "xfs_swapext.h"
#include "xfs_xchgrange.h"
+#include "xfs_rtalloc.h"
/*
* We include this last to have the helpers above available for the trace