On Tue, Jun 22, 1999 at 07:04:22PM +0200, Miklos Szeredi wrote:
>
> I'm not including the whole log of this, because that is very long,
> only the end. But if you need it I can send the whole log (36k
> compressed).
>
> Note, that the Oops is not produced by the 'ls' process, but by the
> venus-like client, doing a CODA_LOOKUP operation, and calling stat()
> for a normal file.
>
> I tried to investigate why this Oops happens, and here's where I got:
>
> coda_cnremove() is called with a NULL pointer from coda_cache_clear_inode()
>
> And I don't see how that can happen, unless the c_cnhead field is
> uninitialized, or the memory is corrupted. But I'm not an expert on
> kernel debugging (this is the first time I do this).
>
> Can this make any sense?
Yeah, I think I found the problem. Next time however, run the oops through
ksymoops which is in /usr/src/linux/tools/ksymoops, as it will decode the
Code: part and helps pinpointing the exact part of the code where the crash
occurs.
It seems to be the classic case of removing a listentry we need later on to
get to the next item, does the following patch help? (ps. I haven't tested
this myself, but then again, I haven't had such an oops yet).
Jan
--- cache.c.orig Tue Jun 22 14:39:03 1999
+++ cache.c Tue Jun 22 14:45:58 1999
@@ -151,8 +151,10 @@
cii = ITOC(inode);
lh = le = &cii->c_cnhead;
- while ( (le = le->next ) != lh ) {
+ le = le->next;
+ while ( le != lh ) {
cc = list_entry(le, struct coda_cache, cc_cnlist);
+ le = le->next;
coda_cnremove(cc);
coda_ccremove(cc);
CODA_FREE(cc, sizeof(*cc));
@@ -175,8 +177,10 @@
return;
lh = le = &sbi->sbi_cchead;
- while ( (le = le->next ) != lh ) {
+ le = le->next;
+ while ( le != lh ) {
cc = list_entry(le, struct coda_cache, cc_cclist);
+ le = le->next;
coda_cnremove(cc);
coda_ccremove(cc);
CODA_FREE(cc, sizeof(*cc));
@@ -199,8 +203,10 @@
return;
lh = le = &sbi->sbi_cchead;
- while ( (le = le->next ) != lh ) {
+ le = le->next;
+ while ( le != lh ) {
cc = list_entry(le, struct coda_cache, cc_cclist);
+ le = le->next;
if ( coda_cred_eq(&cc->cc_cred, cred)) {
coda_cnremove(cc);
coda_ccremove(cc);