Sv: Re: [Users] Infinite loop in __d_lookup ?
Pavel Emelyanov
xemul at sw.ru
Wed May 21 07:46:11 EDT 2008
Jakob Goldbach wrote:
> Hi Pavel (and others)
>
> Loop is in __d_lookup as trace show. Any ideas ?
Well. It this really happens, then we have a corrupted
chain of dentries. Let's try to catch this corruption
early.
Here's the debugging patch that checks the chain to be
consistent when entries are added/removed from it.
Thanks for your help, Jakob :)
I've added a BUG with this issue - please, continue
communication via bugzilla since now:
http://bugzilla.openvz.org/show_bug.cgi?id=895
> /Jakob
>
>
> [76893.524305] __d_lookup: Abort on 5000 loop iteration in a chain
> [76893.525411]
> [76893.525412] Call Trace:
> [76893.526538] [<ffffffff8020ae20>] show_trace+0xae/0x360
> [76893.527619] [<ffffffff8020b0e7>] dump_stack+0x15/0x17
> [76893.528677] [<ffffffff8029b343>] __d_lookup+0x13a/0x187
> [76893.529779] [<ffffffff8029105d>] do_lookup+0x2c/0x193
> [76893.530846] [<ffffffff80293122>] __link_path_walk+0xb07/0x10ac
> [76893.532066] [<ffffffff8029374e>] link_path_walk+0x87/0x140
> [76893.533230] [<ffffffff80293c76>] do_path_lookup+0x2d3/0x2f8
> [76893.534404] [<ffffffff802945e2>] __user_walk_fd+0x41/0x62
> [76893.535559] [<ffffffff80282a09>] sys_faccessat+0xf4/0x1b5
> [76893.536705] [<ffffffff80282add>] sys_access+0x13/0x15
> [76893.537873] [<ffffffff80209902>] system_call+0x7e/0x83
> [76893.538898] DWARF2 unwinder stuck at system_call+0x7e/0x83
> [76893.539964] Leftover inexact backtrace:
> [76893.540768]
> [76893.541202] __d_lookup: Abort on 5000 loop iteration in a chain
-------------- next part --------------
--- ./fs/dcache.c.ddebug2 2008-05-21 14:52:15.000000000 +0400
+++ ./fs/dcache.c 2008-05-21 15:10:06.000000000 +0400
@@ -1350,6 +1350,18 @@ static void __d_rehash(struct dentry * e
{
entry->d_flags &= ~DCACHE_UNHASHED;
+ if (!spin_is_locked(&dcache_lock)) {
+ printk(KERN_ERR "Dcache lock is not taken on add\n");
+ dump_stack();
+ } else if (list->first != NULL &&
+ list->first->pprev != &list->first) {
+ printk(KERN_ERR "Dcache chain corruption:\n");
+ printk(KERN_ERR "Chain %p --next-> %p\n",
+ list, list->first);
+ printk(KERN_ERR "First %p <-pprev- %p\n",
+ list->first, list->first->pprev);
+ dump_stack();
+ }
hlist_add_head_rcu(&entry->d_hash, list);
}
@@ -1443,6 +1455,32 @@ static void switch_names(struct dentry *
* dcache entries should not be moved in this way.
*/
+void d_node_check(struct hlist_node *n)
+{
+ if (!spin_is_locked(&dcache_lock)) {
+ printk(KERN_ERR "Dcache lock is not taken on del\n");
+ dump_stack();
+ }
+
+ if (n->next != NULL &&
+ n->next->pprev != &n->next) {
+ printk(KERN_ERR "Dentry d_hash node corruption(m1):\n");
+ printk(KERN_ERR "Node %p --next-> %p\n",
+ n, n->next);
+ printk(KERN_ERR "Next %p <-pprev- %p\n",
+ n->next, n->next->pprev);
+ dump_stack();
+ }
+
+ if (*n->pprev != n) {
+ printk(KERN_ERR "Dentry d_hash node corruption(m2):\n");
+ printk(KERN_ERR "Node %p <-pprev- %p -> %p\n",
+ n, n->pprev, *n->pprev);
+ dump_stack();
+ }
+}
+EXPORT_SYMBOL(d_node_check);
+
void d_move(struct dentry * dentry, struct dentry * target)
{
struct hlist_head *list;
@@ -1467,6 +1505,7 @@ void d_move(struct dentry * dentry, stru
if (dentry->d_flags & DCACHE_UNHASHED)
goto already_unhashed;
+ d_node_check(&dentry->d_hash);
hlist_del_rcu(&dentry->d_hash);
already_unhashed:
--- ./include/linux/dcache.h.ddebug2 2008-05-21 14:50:31.000000000 +0400
+++ ./include/linux/dcache.h 2008-05-21 15:09:03.000000000 +0400
@@ -203,10 +203,13 @@ extern spinlock_t dcache_lock;
* __d_drop requires dentry->d_lock.
*/
+void d_node_check(struct hlist_node *n);
+
static inline void __d_drop(struct dentry *dentry)
{
if (!(dentry->d_flags & DCACHE_UNHASHED)) {
dentry->d_flags |= DCACHE_UNHASHED;
+ d_node_check(&dentry->d_hash);
hlist_del_rcu(&dentry->d_hash);
}
}
More information about the Users
mailing list