
From: Rusty Russell <rusty@rustcorp.com.au>

Introduces __module_get for places where we know we already hold a reference
and ignoring the fact that the module is being "rmmod --wait"ed is simpler.



 fs/filesystems.c       |   12 +-----------
 include/linux/module.h |   19 +++++++++++++++++++
 kernel/module.c        |    3 ++-
 3 files changed, 22 insertions(+), 12 deletions(-)

diff -puN fs/filesystems.c~implement-__module_get fs/filesystems.c
--- 25/fs/filesystems.c~implement-__module_get	2003-04-29 20:51:29.000000000 -0700
+++ 25-akpm/fs/filesystems.c	2003-04-29 20:51:29.000000000 -0700
@@ -32,17 +32,7 @@ static rwlock_t file_systems_lock = RW_L
 /* WARNING: This can be used only if we _already_ own a reference */
 void get_filesystem(struct file_system_type *fs)
 {
-	if (!try_module_get(fs->owner)) {
-#ifdef CONFIG_MODULE_UNLOAD
-		unsigned int cpu = get_cpu();
-		local_inc(&fs->owner->ref[cpu].count);
-		put_cpu();
-#else
-		/* Getting filesystem while it's starting up?  We're
-                   already supposed to have a reference. */
-		BUG();
-#endif
-	}
+	__module_get(fs->owner);
 }
 
 void put_filesystem(struct file_system_type *fs)
diff -puN include/linux/module.h~implement-__module_get include/linux/module.h
--- 25/include/linux/module.h~implement-__module_get	2003-04-29 20:51:29.000000000 -0700
+++ 25-akpm/include/linux/module.h	2003-04-29 20:51:29.000000000 -0700
@@ -265,6 +265,7 @@ struct module *module_text_address(unsig
 
 #ifdef CONFIG_MODULE_UNLOAD
 
+unsigned int module_refcount(struct module *mod);
 void __symbol_put(const char *symbol);
 #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
 void symbol_put_addr(void *addr);
@@ -275,6 +276,17 @@ void symbol_put_addr(void *addr);
 #define local_dec(x) atomic_dec(x)
 #endif
 
+/* Sometimes we know we already have a refcount, and it's easier not
+   to handle the error case (which only happens with rmmod --wait). */
+static inline void __module_get(struct module *module)
+{
+	if (module) {
+		BUG_ON(module_refcount(module) == 0);
+		local_inc(&module->ref[get_cpu()].count);
+		put_cpu();
+	}
+}
+
 static inline int try_module_get(struct module *module)
 {
 	int ret = 1;
@@ -310,6 +322,9 @@ static inline int try_module_get(struct 
 static inline void module_put(struct module *module)
 {
 }
+static inline void __module_get(struct module *module)
+{
+}
 #define symbol_put(x) do { } while(0)
 #define symbol_put_addr(p) do { } while(0)
 
@@ -367,6 +382,10 @@ static inline struct module *module_text
 #define symbol_put(x) do { } while(0)
 #define symbol_put_addr(x) do { } while(0)
 
+static inline void __module_get(struct module *module)
+{
+}
+
 static inline int try_module_get(struct module *module)
 {
 	return 1;
diff -puN kernel/module.c~implement-__module_get kernel/module.c
--- 25/kernel/module.c~implement-__module_get	2003-04-29 20:51:29.000000000 -0700
+++ 25-akpm/kernel/module.c	2003-04-29 20:51:29.000000000 -0700
@@ -431,7 +431,7 @@ static inline void restart_refcounts(voi
 }
 #endif
 
-static unsigned int module_refcount(struct module *mod)
+unsigned int module_refcount(struct module *mod)
 {
 	unsigned int i, total = 0;
 
@@ -439,6 +439,7 @@ static unsigned int module_refcount(stru
 		total += atomic_read(&mod->ref[i].count);
 	return total;
 }
+EXPORT_SYMBOL(module_refcount);
 
 /* This exists whether we can unload or not */
 static void free_module(struct module *mod);

_
