When I tried to run cachefilesd command, I found out below messages on
dmesg.
=========================================================
=============================================
[ INFO: possible recursive locking detected ]
2.6.18-1.2702.el5 #1
---------------------------------------------
cachefilesd/22494 is trying to acquire lock:
(&inode->i_mutex){--..}, at: [<0000000000248c1e>] mutex_lock+0x3e/0x4c
but task is already holding lock:
(&inode->i_mutex){--..}, at: [<0000000000248c1e>] mutex_lock+0x3e/0x4c
other info that might help us debug this:
1 lock held by cachefilesd/22494:
#0: (&inode->i_mutex){--..}, at: [<0000000000248c1e>] mutex_lock+0x3e/0x4c
stack backtrace:
000000000577f8f0 000000000577f980 0000000000000002 0000000000000000
000000000577fa20 000000000577f998 000000000577f998 000000000001663a
0000000000000000 0000000000000000 000000000000000a 000000000000000a
0000000000000000 000000000577f980 000000000577f980 000000000577f9f8
0000000000259d10 000000000001663a 000000000577f980 000000000577f9d8
Call Trace:
([<0000000000016586>] show_trace+0x122/0x13c)
[<0000000000016658>] show_stack+0xb8/0xc8
[<0000000000016696>] dump_stack+0x2e/0x3c
[<000000000005dc3c>] __lock_acquire+0xb3c/0xba0
[<000000000005e434>] lock_acquire+0x88/0xac
[<00000000002489f4>] __mutex_lock_slowpath+0x130/0x31c
[<0000000000248c1e>] mutex_lock+0x3e/0x4c
[<0000000020ec34ec>] cachefiles_get_directory+0x198/0x600 [cachefiles]
[<0000000020ebecac>] cachefiles_proc_bind+0x3f0/0x57c [cachefiles]
[<0000000020ec5270>] cachefiles_proc_write+0x290/0x2fc [cachefiles]
[<00000000000a9206>] vfs_write+0xd6/0x1b0
[<00000000000a98ea>] sys_write+0x56/0x84
[<000000000001fcec>] sysc_tracego+0xe/0x14
[<0000004efa6dd1f4>] 0x4efa6dd1f4
FS-Cache: Cache "mycache" added (type cachefiles)
CacheFiles: File cache on 5e:01 registered
=======================================================
Cause for this problem is 2 different inodes are getting locked recursively.
One is /proc/fs/cachefiles and other is /var/fscache.
cachefiles_proc_write() locks /proc/fs/cachefiles before writing and
cachefiles_proc_bind() locks /var/fscache directory to get dentry object
for cache and graveyard directories.
Another bug I could able to find out was in cachefiles_check_object_type()
where mutex being unlocked twice.
===================================================================
mutex_lock(&dentry->d_inode->i_mutex);
/* attempt to install a type label directly */
ret = dentry->d_inode->i_op->setxattr(dentry,
cachefiles_xattr_cache,
type, 2, XATTR_CREATE);
if (ret == 0) {
_debug("SET");
fsnotify_xattr(dentry);
mutex_unlock(&dentry->d_inode->i_mutex); ====> bug here
goto error;
}
.................................
....................................
error:
mutex_unlock(&dentry->d_inode->i_mutex); =======> happening
twice
_leave(" = %d", ret);
return ret;
=======================================================
I have developed the patch which solves these problem. Please let me
know your
comments on this patch.
Thanks
Srinivasa DS
IBM-LTC
cf-namei.c | 2 +-
cf-proc.c | 2 +-
cf-xattr.c | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
Index: linux-2.6.18.x86_64/fs/cachefiles/cf-proc.c
===================================================================
--- linux-2.6.18.x86_64.orig/fs/cachefiles/cf-proc.c 2006-10-26 11:41:13.000000000 +0530
+++ linux-2.6.18.x86_64/fs/cachefiles/cf-proc.c 2006-10-26 11:45:33.000000000 +0530
@@ -248,7 +248,7 @@
return ret;
found_command:
- mutex_lock(&file->f_dentry->d_inode->i_mutex);
+ mutex_lock_nested(&file->f_dentry->d_inode->i_mutex, I_MUTEX_PARENT);
ret = -EIO;
if (!test_bit(CACHEFILES_DEAD, &cache->flags))
Index: linux-2.6.18.x86_64/fs/cachefiles/cf-namei.c
===================================================================
--- linux-2.6.18.x86_64.orig/fs/cachefiles/cf-namei.c 2006-10-26 11:41:13.000000000 +0530
+++ linux-2.6.18.x86_64/fs/cachefiles/cf-namei.c 2006-10-26 11:46:24.000000000 +0530
@@ -581,7 +581,7 @@
current->fsuid = 0;
current->fsgid = 0;
- mutex_lock(&dir->d_inode->i_mutex);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_CHILD);
subdir = d_lookup(dir, &name);
if (!subdir) {
Index: linux-2.6.18.x86_64/fs/cachefiles/cf-xattr.c
===================================================================
--- linux-2.6.18.x86_64.orig/fs/cachefiles/cf-xattr.c 2006-10-26 11:41:13.000000000 +0530
+++ linux-2.6.18.x86_64/fs/cachefiles/cf-xattr.c 2006-10-26 11:48:25.000000000 +0530
@@ -52,7 +52,6 @@
if (ret == 0) {
_debug("SET");
fsnotify_xattr(dentry);
- mutex_unlock(&dentry->d_inode->i_mutex);
goto error;
}