Re: autofs freezes in _dlookup? [Re: 2.1.51 Still Freezing]

Bill Hawes (whawes@star.net)
Tue, 19 Aug 1997 12:06:24 -0400


This is a multi-part message in MIME format.
--------------22D145C566936FDDE5CC3E2E
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Janos Farkas wrote:
> I've seen similar things since 2.1.49, 50, 51-pre1, and about to check
> 51. For me, it always happened when autofs tried to expire an ext2fs
> volume. EIP debugging output showed that the kernel is stuck inside
> __dlookup(), in the while(tmp != head) loop. I don't know why,
> it's probably impossible. Bill? :)

I looked at that section of code, and it should be impossible to get in
a loop. However, if a dentry was released while there was still a
reference to it, and then hashed, and then re-allocated as another
dentry, the initialization of the d_hash list head would create a loop.

If you think you can reproduce this problem, the attached patch might
detect a reference being added to a freed dentry. It's against 2.1.50
but I think will still apply to 2.1.51.

Regards,
Bill
--------------22D145C566936FDDE5CC3E2E
Content-Type: text/plain; charset=us-ascii; name="dcache_50-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dcache_50-patch"

--- linux-2.1.50/fs/dcache.c.old Thu Aug 14 18:44:06 1997
+++ linux-2.1.50/fs/dcache.c Sun Aug 17 14:36:07 1997
@@ -37,7 +37,23 @@
void d_free(struct dentry *dentry)
{
kfree(dentry->d_name.name);
+ /* poison the memory */
+ memset(dentry, 0xAB, sizeof(*dentry));
kfree(dentry);
+}
+
+struct dentry * dget(struct dentry *dentry)
+{
+ static int oopsed = 0;
+ if (dentry && dentry->d_count == 0xABABABAB) {
+ printk("dget: rereferencing dead dentry!\n");
+ if (!oopsed++)
+ *(int *) 0x12345678 = 0;
+ return NULL;
+ }
+ if (dentry)
+ dentry->d_count++;
+ return dentry;
}

/*
--- linux-2.1.50/include/linux/dcache.h.old Thu Aug 14 18:44:06 1997
+++ linux-2.1.50/include/linux/dcache.h Sun Aug 17 14:43:38 1997
@@ -124,6 +124,8 @@
/* write full pathname into buffer and return start of pathname */
extern char * d_path(struct dentry * entry, char * buf, int buflen);

+extern struct dentry * dget(struct dentry *dentry);
+#if 0
/* Allocation counts.. */
static inline struct dentry * dget(struct dentry *dentry)
{
@@ -131,6 +133,7 @@
dentry->d_count++;
return dentry;
}
+#endif

extern void dput(struct dentry *);

--------------22D145C566936FDDE5CC3E2E--