summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_rtalloc.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 11c42ebfa0a5..674ca3dab72e 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -27,6 +27,16 @@
#include "xfs_rtbitmap.h"
/*
+ * 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 regular realtime file. This double
+ * locking 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;
+
+/*
* Read and return the summary information for a given extent size,
* bitmap block combination.
* Keeps track of a current summary block, so we don't keep reading
@@ -1342,6 +1352,28 @@ xfs_rtalloc_reinit_frextents(
return 0;
}
+static inline int
+__xfs_rt_iget(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ struct lock_class_key *lockdep_key,
+ const char *lockdep_key_name,
+ 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_and_name(&(*ipp)->i_lock.mr_lock, lockdep_key,
+ lockdep_key_name);
+ return 0;
+}
+
+#define xfs_rt_iget(mp, ino, lockdep_key, ipp) \
+ __xfs_rt_iget((mp), (ino), (lockdep_key), #lockdep_key, (ipp))
+
/*
* Read in the bmbt of an rt metadata inode so that we never have to load them
* at runtime. This enables the use of shared ILOCKs for rtbitmap scans. Use
@@ -1389,7 +1421,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);
@@ -1401,7 +1433,7 @@ xfs_rtmount_inodes(
if (error)
goto out_rele_bitmap;
- 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);