aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-07-03 03:25:05 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-03 18:27:06 -0400
commitf2eace23e924bd3f05aedea4fc505eb5508d2d93 (patch)
tree3e78dc1c4be979164a91665f56299e344fb6d6b6
parenta90b9c05df3c1e58eaedc28795d0f5abd896c098 (diff)
[PATCH] lockdep: annotate i_mutex
Teach special (recursive) locking code to the lock validator. Has no effect on non-lockdep kernels. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/usb/core/inode.c2
-rw-r--r--fs/namei.c20
-rw-r--r--include/linux/fs.h19
3 files changed, 30 insertions, 11 deletions
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index e47e3a8ed6e4..cf11196e012d 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -200,7 +200,7 @@ static void update_sb(struct super_block *sb)
200 if (!root) 200 if (!root)
201 return; 201 return;
202 202
203 mutex_lock(&root->d_inode->i_mutex); 203 mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
204 204
205 list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { 205 list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
206 if (bus->d_inode) { 206 if (bus->d_inode) {
diff --git a/fs/namei.c b/fs/namei.c
index c784e8bb57a3..c9750d755aff 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1423,7 +1423,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1423 struct dentry *p; 1423 struct dentry *p;
1424 1424
1425 if (p1 == p2) { 1425 if (p1 == p2) {
1426 mutex_lock(&p1->d_inode->i_mutex); 1426 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1427 return NULL; 1427 return NULL;
1428 } 1428 }
1429 1429
@@ -1431,22 +1431,22 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1431 1431
1432 for (p = p1; p->d_parent != p; p = p->d_parent) { 1432 for (p = p1; p->d_parent != p; p = p->d_parent) {
1433 if (p->d_parent == p2) { 1433 if (p->d_parent == p2) {
1434 mutex_lock(&p2->d_inode->i_mutex); 1434 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
1435 mutex_lock(&p1->d_inode->i_mutex); 1435 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
1436 return p; 1436 return p;
1437 } 1437 }
1438 } 1438 }
1439 1439
1440 for (p = p2; p->d_parent != p; p = p->d_parent) { 1440 for (p = p2; p->d_parent != p; p = p->d_parent) {
1441 if (p->d_parent == p1) { 1441 if (p->d_parent == p1) {
1442 mutex_lock(&p1->d_inode->i_mutex); 1442 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1443 mutex_lock(&p2->d_inode->i_mutex); 1443 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
1444 return p; 1444 return p;
1445 } 1445 }
1446 } 1446 }
1447 1447
1448 mutex_lock(&p1->d_inode->i_mutex); 1448 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1449 mutex_lock(&p2->d_inode->i_mutex); 1449 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
1450 return NULL; 1450 return NULL;
1451} 1451}
1452 1452
@@ -1751,7 +1751,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1751{ 1751{
1752 struct dentry *dentry = ERR_PTR(-EEXIST); 1752 struct dentry *dentry = ERR_PTR(-EEXIST);
1753 1753
1754 mutex_lock(&nd->dentry->d_inode->i_mutex); 1754 mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
1755 /* 1755 /*
1756 * Yucky last component or no last component at all? 1756 * Yucky last component or no last component at all?
1757 * (foo/., foo/.., /////) 1757 * (foo/., foo/.., /////)
@@ -2008,7 +2008,7 @@ static long do_rmdir(int dfd, const char __user *pathname)
2008 error = -EBUSY; 2008 error = -EBUSY;
2009 goto exit1; 2009 goto exit1;
2010 } 2010 }
2011 mutex_lock(&nd.dentry->d_inode->i_mutex); 2011 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
2012 dentry = lookup_hash(&nd); 2012 dentry = lookup_hash(&nd);
2013 error = PTR_ERR(dentry); 2013 error = PTR_ERR(dentry);
2014 if (!IS_ERR(dentry)) { 2014 if (!IS_ERR(dentry)) {
@@ -2082,7 +2082,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2082 error = -EISDIR; 2082 error = -EISDIR;
2083 if (nd.last_type != LAST_NORM) 2083 if (nd.last_type != LAST_NORM)
2084 goto exit1; 2084 goto exit1;
2085 mutex_lock(&nd.dentry->d_inode->i_mutex); 2085 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
2086 dentry = lookup_hash(&nd); 2086 dentry = lookup_hash(&nd);
2087 error = PTR_ERR(dentry); 2087 error = PTR_ERR(dentry);
2088 if (!IS_ERR(dentry)) { 2088 if (!IS_ERR(dentry)) {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e04a5cfe874f..05ded9e76b23 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -543,6 +543,25 @@ struct inode {
543}; 543};
544 544
545/* 545/*
546 * inode->i_mutex nesting subclasses for the lock validator:
547 *
548 * 0: the object of the current VFS operation
549 * 1: parent
550 * 2: child/target
551 * 3: quota file
552 *
553 * The locking order between these classes is
554 * parent -> child -> normal -> quota
555 */
556enum inode_i_mutex_lock_class
557{
558 I_MUTEX_NORMAL,
559 I_MUTEX_PARENT,
560 I_MUTEX_CHILD,
561 I_MUTEX_QUOTA
562};
563
564/*
546 * NOTE: in a 32bit arch with a preemptable kernel and 565 * NOTE: in a 32bit arch with a preemptable kernel and
547 * an UP compile the i_size_read/write must be atomic 566 * an UP compile the i_size_read/write must be atomic
548 * with respect to the local cpu (unlike with preempt disabled), 567 * with respect to the local cpu (unlike with preempt disabled),