Messages in this thread Patch in this message | | | Date | Mon, 05 Jan 1998 13:51:23 -0500 | From | Bill Hawes <> | Subject | Re: more info on dcache corruption in 2.1.76 |
| |
bwoodard@cisco.com wrote: > > Your dcache verify patch continues to catch cases where the dcache > gets corrupted. I had two cases where it caught it over the weekend. > > The first one is hard to pin down. My wife was running quicken in wabi > over an xsession and I was just messing around with files in the > kernel source directory. There was so much going on with this one I > don't think it yields very clean information. However, the second one > happened when the system was almost idle unfortunately. I was in kfm > and I requested a page from the web and it couldn't deal with it. So I > brought netscape up and looked at the page. It was swapped out and > right after that is when I saw that the dcache was corrupted. > > I will continue to monitor the situation to see if I can catch a more > clean example of when the dcache gets corrupted. The problem is that > it only seems to happen when I am activly working with the computer > and the kinds of things that I do with my computer are kind of random. > > BTW could you please mail me the patch again. I accidently lost the > original file and I would like to move to 2.1.77.
Hi Ben,
OK, glad to hear we're getting more info -- so far you're the only one who has been able to detect it with the patch. Hopefully a pattern will emerge to help focus the search.
Patch is attached ...
Regards, Bill--- fs/dcache.c.old Mon Dec 1 11:14:13 1997 +++ fs/dcache.c Sun Dec 14 19:32:27 1997 @@ -411,6 +411,63 @@ } /* + * Check that the unused dentry list is valid. + */ +void verify_list(void) +{ + struct list_head *tmp, *next, *prev; + struct dentry *dentry; + struct inode *inode; + unsigned long memstart = PAGE_OFFSET; + unsigned long memmax = PAGE_OFFSET + (num_physpages << PAGE_SHIFT); + unsigned long align_mask = ~0x3; + unsigned long addr; + + prev = &dentry_unused; + for (tmp = dentry_unused.next; tmp != &dentry_unused; tmp = next) { + + addr = (unsigned long) tmp; + if (addr < memstart || addr > memmax) + goto bad; + if ((addr & align_mask) != addr) + goto bad; + if (prev != tmp->prev) + goto bad_prev; + next = tmp->next; + prev = tmp; + dentry = list_entry(tmp, struct dentry, d_lru); + inode = dentry->d_inode; + if (!inode) + continue; + addr = (unsigned long) inode; + if (addr < memstart || addr > memmax) + goto bad_inode; + if ((addr & align_mask) != addr) + goto bad_inode; + if (inode->i_sb != dentry->d_sb) + goto bad_sb; + if (!inode->i_count || inode->i_count > 50) + goto bad_count; + } + return; +bad: + printk("VFS: dentry list corrupt, addr=%08lx\n", addr); + return; +bad_prev: + printk("VFS: bad prev pointer in dentry list, prev=%p\n", prev); + return; +bad_inode: + printk("VFS: dentry has bad inode pointer, addr=%08lx\n", addr); + return; +bad_sb: + printk("VFS: dentry superblock mismatch\n"); + return; +bad_count: + printk("VFS: bad count for in-use inode, count=%d\n", inode->i_count); + return; +} + +/* * This is called from do_try_to_free_page() to indicate * that we should reduce the dcache and inode cache memory. */ @@ -424,6 +481,13 @@ */ void check_dcache_memory() { + static unsigned long next_check = 0; + + if (jiffies > next_check) { + next_check = jiffies + 2*HZ; + verify_list(); + } + if (dentry_stat.want_pages) { unsigned int count, goal = 0; /* @@ -679,6 +743,8 @@ { if (!dentry->d_inode) printk(KERN_WARNING "VFS: moving negative dcache entry\n"); + if (list_empty(&target->d_hash)) + printk(KERN_WARNING "VFS: unhashed target\n"); /* Move the dentry to the target hash queue */ list_del(&dentry->d_hash); | |