Skip to content

Commit c29237a

Browse files
author
Darrick J. Wong
committed
xfs: add a lockdep class key for rtgroup inodes
Add a dynamic lockdep class key for rtgroup inodes. This will enable lockdep to deduce inconsistencies in the rtgroup metadata ILOCK locking order. Each class can have 8 subclasses, and for now we will only have 2 inodes per group. This enables rtgroup order and inode order checks when nesting ILOCKs. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 0e4875b commit c29237a

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

fs/xfs/libxfs/xfs_rtgroup.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,55 @@ xfs_rtgroup_trans_join(
198198
if (rtglock_flags & XFS_RTGLOCK_BITMAP)
199199
xfs_rtbitmap_trans_join(tp);
200200
}
201+
202+
#ifdef CONFIG_PROVE_LOCKING
203+
static struct lock_class_key xfs_rtginode_lock_class;
204+
205+
static int
206+
xfs_rtginode_ilock_cmp_fn(
207+
const struct lockdep_map *m1,
208+
const struct lockdep_map *m2)
209+
{
210+
const struct xfs_inode *ip1 =
211+
container_of(m1, struct xfs_inode, i_lock.dep_map);
212+
const struct xfs_inode *ip2 =
213+
container_of(m2, struct xfs_inode, i_lock.dep_map);
214+
215+
if (ip1->i_projid < ip2->i_projid)
216+
return -1;
217+
if (ip1->i_projid > ip2->i_projid)
218+
return 1;
219+
return 0;
220+
}
221+
222+
static inline void
223+
xfs_rtginode_ilock_print_fn(
224+
const struct lockdep_map *m)
225+
{
226+
const struct xfs_inode *ip =
227+
container_of(m, struct xfs_inode, i_lock.dep_map);
228+
229+
printk(KERN_CONT " rgno=%u", ip->i_projid);
230+
}
231+
232+
/*
233+
* Most of the time each of the RTG inode locks are only taken one at a time.
234+
* But when committing deferred ops, more than one of a kind can be taken.
235+
* However, deferred rt ops will be committed in rgno order so there is no
236+
* potential for deadlocks. The code here is needed to tell lockdep about this
237+
* order.
238+
*/
239+
static inline void
240+
xfs_rtginode_lockdep_setup(
241+
struct xfs_inode *ip,
242+
xfs_rgnumber_t rgno,
243+
enum xfs_rtg_inodes type)
244+
{
245+
lockdep_set_class_and_subclass(&ip->i_lock, &xfs_rtginode_lock_class,
246+
type);
247+
lock_set_cmp_fn(&ip->i_lock, xfs_rtginode_ilock_cmp_fn,
248+
xfs_rtginode_ilock_print_fn);
249+
}
250+
#else
251+
#define xfs_rtginode_lockdep_setup(ip, rgno, type) do { } while (0)
252+
#endif /* CONFIG_PROVE_LOCKING */

0 commit comments

Comments
 (0)