summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 11:15:54 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-17 18:55:11 -0700
commitb0a580dd65f1595d915a1612180c622d2461e2cd (patch)
treea0322992b2efada1b7604ae97c1753f48e2cd40b
parent780c94e0c7f4878574120b1e1d42ffc17a5d20a0 (diff)
xfs: use separate lock classes for realtime metadata inode ILOCKs
Realtime metadata files are not quite regular files because userspace can't access the realtime bitmap directly, and because we take the ILOCK of the rt bitmap file while holding the ILOCK of a realtime file. The double nature of inodes confuses lockdep, so up until now we've created lockdep subclasses to help lockdep keep things straight. We've gotten away with using lockdep subclasses because there's only two rt metadata files, but with the coming addition of realtime rmap and refcounting, we'd need two more subclasses, which is a lot of class bits to burn on a side feature. Therefore, switch to manually setting the lockdep class of the rt metadata ILOCKs. In the next patch we'll remove the rt-related ILOCK subclasses. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/xfs_rtalloc.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 689c127bdda5..0ef94f67ccbd 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1289,6 +1289,33 @@ xfs_rtmount_init(
}
/*
+ * Realtime metadata files are not quite regular files because userspace can't
+ * access the realtime bitmap directly, and because we take the ILOCK of the rt
+ * bitmap file while holding the ILOCK of a realtime file. The double nature
+ * of inodes confuses lockdep, so create different lockdep classes here to help
+ * it keep things straight.
+ */
+static struct lock_class_key xfs_rbmip_key;
+static struct lock_class_key xfs_rsumip_key;
+
+static inline int
+xfs_rt_iget(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ struct lock_class_key *lockdep_key,
+ struct xfs_inode **ipp)
+{
+ int error;
+
+ error = xfs_imeta_iget(mp, ino, XFS_DIR3_FT_REG_FILE, ipp);
+ if (error)
+ return error;
+
+ lockdep_set_class(&(*ipp)->i_lock.mr_lock, lockdep_key);
+ return 0;
+}
+
+/*
* Get the bitmap and summary inodes and the summary cache into the mount
* structure at mount time.
*/
@@ -1300,7 +1327,7 @@ xfs_rtmount_inodes(
xfs_sb_t *sbp;
sbp = &mp->m_sb;
- error = xfs_imeta_iget(mp, mp->m_sb.sb_rbmino, XFS_DIR3_FT_REG_FILE,
+ error = xfs_rt_iget(mp, mp->m_sb.sb_rbmino, &xfs_rbmip_key,
&mp->m_rbmip);
if (xfs_metadata_is_sick(error))
xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP);
@@ -1308,7 +1335,7 @@ xfs_rtmount_inodes(
return error;
ASSERT(mp->m_rbmip != NULL);
- error = xfs_imeta_iget(mp, mp->m_sb.sb_rsumino, XFS_DIR3_FT_REG_FILE,
+ error = xfs_rt_iget(mp, mp->m_sb.sb_rsumino, &xfs_rsumip_key,
&mp->m_rsumip);
if (xfs_metadata_is_sick(error))
xfs_rt_mark_sick(mp, XFS_SICK_RT_SUMMARY);