diff options
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 36 |
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); |