diff options
author | Roland Dreier <rdreier@cisco.com> | 2010-04-27 17:23:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-21 18:31:22 -0400 |
commit | 51ee049e771c14a29aaee8ecd6cbbe14db088f3a (patch) | |
tree | 594c6676eb50a59ce82625ee09fee73fd700a5ed | |
parent | cc9106247de92549e50abb0ba12d6b2fdbf0be55 (diff) |
vfs: add lockdep annotation to s_vfs_rename_key for ecryptfs
> =============================================
> [ INFO: possible recursive locking detected ]
> 2.6.31-2-generic #14~rbd3
> ---------------------------------------------
> firefox-3.5/4162 is trying to acquire lock:
> (&s->s_vfs_rename_mutex){+.+.+.}, at: [<ffffffff81139d31>] lock_rename+0x41/0xf0
>
> but task is already holding lock:
> (&s->s_vfs_rename_mutex){+.+.+.}, at: [<ffffffff81139d31>] lock_rename+0x41/0xf0
>
> other info that might help us debug this:
> 3 locks held by firefox-3.5/4162:
> #0: (&s->s_vfs_rename_mutex){+.+.+.}, at: [<ffffffff81139d31>] lock_rename+0x41/0xf0
> #1: (&sb->s_type->i_mutex_key#11/1){+.+.+.}, at: [<ffffffff81139d5a>] lock_rename+0x6a/0xf0
> #2: (&sb->s_type->i_mutex_key#11/2){+.+.+.}, at: [<ffffffff81139d6f>] lock_rename+0x7f/0xf0
>
> stack backtrace:
> Pid: 4162, comm: firefox-3.5 Tainted: G C 2.6.31-2-generic #14~rbd3
> Call Trace:
> [<ffffffff8108ae74>] print_deadlock_bug+0xf4/0x100
> [<ffffffff8108ce26>] validate_chain+0x4c6/0x750
> [<ffffffff8108d2e7>] __lock_acquire+0x237/0x430
> [<ffffffff8108d585>] lock_acquire+0xa5/0x150
> [<ffffffff81139d31>] ? lock_rename+0x41/0xf0
> [<ffffffff815526ad>] __mutex_lock_common+0x4d/0x3d0
> [<ffffffff81139d31>] ? lock_rename+0x41/0xf0
> [<ffffffff81139d31>] ? lock_rename+0x41/0xf0
> [<ffffffff8120eaf9>] ? ecryptfs_rename+0x99/0x170
> [<ffffffff81552b36>] mutex_lock_nested+0x46/0x60
> [<ffffffff81139d31>] lock_rename+0x41/0xf0
> [<ffffffff8120eb2a>] ecryptfs_rename+0xca/0x170
> [<ffffffff81139a9e>] vfs_rename_dir+0x13e/0x160
> [<ffffffff8113ac7e>] vfs_rename+0xee/0x290
> [<ffffffff8113c212>] ? __lookup_hash+0x102/0x160
> [<ffffffff8113d512>] sys_renameat+0x252/0x280
> [<ffffffff81133eb4>] ? cp_new_stat+0xe4/0x100
> [<ffffffff8101316a>] ? sysret_check+0x2e/0x69
> [<ffffffff8108c34d>] ? trace_hardirqs_on_caller+0x14d/0x190
> [<ffffffff8113d55b>] sys_rename+0x1b/0x20
> [<ffffffff81013132>] system_call_fastpath+0x16/0x1b
The trace above is totally reproducible by doing a cross-directory
rename on an ecryptfs directory.
The issue seems to be that sys_renameat() does lock_rename() then calls
into the filesystem; if the filesystem is ecryptfs, then
ecryptfs_rename() again does lock_rename() on the lower filesystem, and
lockdep can't tell that the two s_vfs_rename_mutexes are different. It
seems an annotation like the following is sufficient to fix this (it
does get rid of the lockdep trace in my simple tests); however I would
like to make sure I'm not misunderstanding the locking, hence the CC
list...
Signed-off-by: Roland Dreier <rdreier@cisco.com>
Cc: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Cc: Dustin Kirkland <kirkland@canonical.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/super.c | 1 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 2 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c index 89afca5055ab..69688b15f1fa 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -88,6 +88,7 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
88 | s->s_count = 1; | 88 | s->s_count = 1; |
89 | atomic_set(&s->s_active, 1); | 89 | atomic_set(&s->s_active, 1); |
90 | mutex_init(&s->s_vfs_rename_mutex); | 90 | mutex_init(&s->s_vfs_rename_mutex); |
91 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); | ||
91 | mutex_init(&s->s_dquot.dqio_mutex); | 92 | mutex_init(&s->s_dquot.dqio_mutex); |
92 | mutex_init(&s->s_dquot.dqonoff_mutex); | 93 | mutex_init(&s->s_dquot.dqonoff_mutex); |
93 | init_rwsem(&s->s_dquot.dqptr_sem); | 94 | init_rwsem(&s->s_dquot.dqptr_sem); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index f3e108314c93..9626c5fbb0e1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1741,6 +1741,7 @@ struct file_system_type { | |||
1741 | 1741 | ||
1742 | struct lock_class_key s_lock_key; | 1742 | struct lock_class_key s_lock_key; |
1743 | struct lock_class_key s_umount_key; | 1743 | struct lock_class_key s_umount_key; |
1744 | struct lock_class_key s_vfs_rename_key; | ||
1744 | 1745 | ||
1745 | struct lock_class_key i_lock_key; | 1746 | struct lock_class_key i_lock_key; |
1746 | struct lock_class_key i_mutex_key; | 1747 | struct lock_class_key i_mutex_key; |