summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_rtalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
-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);