From: Steve Dickson Here is a patch for the 2.6.1 kernel that fixes an oops that occurs when the sunrpc module is unloaded. The problem was the RPC cache_register() call was not saving entry pointers to the procfs entries it was creating. So when it came time to dismantle the entires, a BUG_ON() was tripped in remove_proc_entry() since the tree was not broken down completely. (acked by neilb) --- include/linux/sunrpc/cache.h | 2 ++ net/sunrpc/cache.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff -puN include/linux/sunrpc/cache.h~sunrpc-rmmod-oops-fix include/linux/sunrpc/cache.h --- 25/include/linux/sunrpc/cache.h~sunrpc-rmmod-oops-fix 2004-01-19 20:29:18.000000000 -0800 +++ 25-akpm/include/linux/sunrpc/cache.h 2004-01-19 20:29:18.000000000 -0800 @@ -94,6 +94,8 @@ struct cache_detail { /* fields for communication over channel */ struct list_head queue; struct proc_dir_entry *proc_ent; + struct proc_dir_entry *flush_ent, *channel_ent, *content_ent; + atomic_t readers; /* how many time is /chennel open */ time_t last_close; /* it no readers, when did last close */ }; diff -puN net/sunrpc/cache.c~sunrpc-rmmod-oops-fix net/sunrpc/cache.c --- 25/net/sunrpc/cache.c~sunrpc-rmmod-oops-fix 2004-01-19 20:29:18.000000000 -0800 +++ 25-akpm/net/sunrpc/cache.c 2004-01-19 20:29:18.000000000 -0800 @@ -175,9 +175,11 @@ void cache_register(struct cache_detail if (cd->proc_ent) { struct proc_dir_entry *p; cd->proc_ent->owner = THIS_MODULE; + cd->channel_ent = cd->content_ent = NULL; p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); + cd->flush_ent = p; if (p) { p->proc_fops = &cache_flush_operations; p->owner = THIS_MODULE; @@ -187,6 +189,7 @@ void cache_register(struct cache_detail if (cd->cache_request || cd->cache_parse) { p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); + cd->channel_ent = p; if (p) { p->proc_fops = &cache_file_operations; p->owner = THIS_MODULE; @@ -196,6 +199,7 @@ void cache_register(struct cache_detail if (cd->cache_show) { p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); + cd->content_ent = p; if (p) { p->proc_fops = &content_file_operations; p->owner = THIS_MODULE; @@ -233,6 +237,13 @@ int cache_unregister(struct cache_detail write_unlock(&cd->hash_lock); spin_unlock(&cache_list_lock); if (cd->proc_ent) { + if (cd->flush_ent) + remove_proc_entry("flush", cd->proc_ent); + if (cd->channel_ent) + remove_proc_entry("channel", cd->proc_ent); + if (cd->content_ent) + remove_proc_entry("content", cd->proc_ent); + cd->proc_ent = NULL; remove_proc_entry(cd->name, proc_net_rpc); } _