From d0ab89f5a80c42b824494c61387757f043b73989 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 2 Mar 2003 09:15:46 -0800 Subject: [PATCH] [NETFILTER]: Switch over to new-style module refcounting, help from Christoph Hellwig. --- include/linux/netfilter_ipv4/ip_conntrack.h | 3 +- net/ipv4/netfilter/arp_tables.c | 29 ++++----- net/ipv4/netfilter/ip_conntrack_core.c | 4 -- net/ipv4/netfilter/ip_conntrack_standalone.c | 12 ++-- net/ipv4/netfilter/ip_nat_helper.c | 28 +++------ net/ipv4/netfilter/ip_nat_standalone.c | 10 +--- net/ipv4/netfilter/ip_tables.c | 57 +++++++----------- net/ipv4/netfilter/ipt_conntrack.c | 6 +- net/ipv4/netfilter/ipt_helper.c | 6 +- net/ipv4/netfilter/ipt_state.c | 6 +- net/ipv6/netfilter/ip6_tables.c | 62 ++++++++------------ 11 files changed, 77 insertions(+), 146 deletions(-) diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index efb5c3cece81a..b32550bfb69ce 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -229,7 +229,8 @@ ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple); /* decrement reference count on an expectation */ void ip_conntrack_expect_put(struct ip_conntrack_expect *exp); -extern struct module *ip_conntrack_module; +/* call to create an explicit dependency on ip_conntrack. */ +extern void need_ip_conntrack(void); extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, const struct ip_conntrack_tuple *orig); diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index b311d565b1522..e5943997b1d9b 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -539,8 +539,10 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i duprintf("check_entry: `%s' not found\n", t->u.user.name); goto out; } - if (target->me) - __MOD_INC_USE_COUNT(target->me); + if (!try_module_get((target->me))) { + ret = -ENOENT; + goto out_unlock; + } t->u.kernel.target = target; up(&arpt_mutex); @@ -554,8 +556,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i t->u.target_size - sizeof(*t), e->comefrom)) { - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); + module_put(t->u.kernel.target->me); duprintf("arp_tables: check failed for `%s'.\n", t->u.kernel.target->name); ret = -EINVAL; @@ -565,6 +566,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i (*i)++; return 0; +out_unlock: + up(&arpt_mutex); out: return ret; } @@ -622,9 +625,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) if (t->u.kernel.target->destroy) t->u.kernel.target->destroy(t->data, t->u.target_size - sizeof(*t)); - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); - + module_put(t->u.kernel.target->me); return 0; } @@ -1110,17 +1111,14 @@ int arpt_register_target(struct arpt_target *target) { int ret; - MOD_INC_USE_COUNT; ret = down_interruptible(&arpt_mutex); - if (ret != 0) { - MOD_DEC_USE_COUNT; + if (ret != 0) return ret; - } + if (!list_named_insert(&arpt_target, target)) { duprintf("arpt_register_target: `%s' already in list!\n", target->name); ret = -EINVAL; - MOD_DEC_USE_COUNT; } up(&arpt_mutex); return ret; @@ -1131,7 +1129,6 @@ void arpt_unregister_target(struct arpt_target *target) down(&arpt_mutex); LIST_DELETE(&arpt_target, target); up(&arpt_mutex); - MOD_DEC_USE_COUNT; } int arpt_register_table(struct arpt_table *table) @@ -1141,12 +1138,10 @@ int arpt_register_table(struct arpt_table *table) static struct arpt_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { } }; - MOD_INC_USE_COUNT; newinfo = vmalloc(sizeof(struct arpt_table_info) + SMP_ALIGN(table->table->size) * NR_CPUS); if (!newinfo) { ret = -ENOMEM; - MOD_DEC_USE_COUNT; return ret; } memcpy(newinfo->entries, table->table->entries, table->table->size); @@ -1159,14 +1154,12 @@ int arpt_register_table(struct arpt_table *table) duprintf("arpt_register_table: translate table gives %d\n", ret); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } ret = down_interruptible(&arpt_mutex); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } @@ -1196,7 +1189,6 @@ int arpt_register_table(struct arpt_table *table) free_unlock: vfree(newinfo); - MOD_DEC_USE_COUNT; goto unlock; } @@ -1210,7 +1202,6 @@ void arpt_unregister_table(struct arpt_table *table) ARPT_ENTRY_ITERATE(table->private->entries, table->private->size, cleanup_entry, NULL); vfree(table->private); - MOD_DEC_USE_COUNT; } /* The built-in targets: standard (NULL) and error. */ diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 3ca4c96796a03..ebb576ec62cec 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1128,8 +1128,6 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack, int ip_conntrack_helper_register(struct ip_conntrack_helper *me) { - MOD_INC_USE_COUNT; - WRITE_LOCK(&ip_conntrack_lock); list_prepend(&helpers, me); WRITE_UNLOCK(&ip_conntrack_lock); @@ -1166,8 +1164,6 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) /* Someone could be still looking at the helper in a bh. */ br_write_lock_bh(BR_NETPROTO_LOCK); br_write_unlock_bh(BR_NETPROTO_LOCK); - - MOD_DEC_USE_COUNT; } /* Refresh conntrack for this many jiffies. */ diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 49a48317f8ea7..f64800e8bc6d3 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -33,7 +33,6 @@ #define DEBUGP(format, args...) #endif -struct module *ip_conntrack_module = THIS_MODULE; MODULE_LICENSE("GPL"); static int kill_proto(const struct ip_conntrack *i, void *data) @@ -310,7 +309,6 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) } list_prepend(&protocol_list, proto); - MOD_INC_USE_COUNT; out: WRITE_UNLOCK(&ip_conntrack_lock); @@ -332,8 +330,6 @@ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) /* Remove all contrack entries for this protocol */ ip_ct_selective_cleanup(kill_proto, &proto->proto); - - MOD_DEC_USE_COUNT; } static int __init init(void) @@ -349,13 +345,19 @@ static void __exit fini(void) module_init(init); module_exit(fini); +/* Some modules need us, but don't depend directly on any symbol. + They should call this. */ +void need_ip_conntrack(void) +{ +} + EXPORT_SYMBOL(ip_conntrack_protocol_register); EXPORT_SYMBOL(ip_conntrack_protocol_unregister); EXPORT_SYMBOL(invert_tuplepr); EXPORT_SYMBOL(ip_conntrack_alter_reply); EXPORT_SYMBOL(ip_conntrack_destroyed); EXPORT_SYMBOL(ip_conntrack_get); -EXPORT_SYMBOL(ip_conntrack_module); +EXPORT_SYMBOL(need_ip_conntrack); EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_ct_selective_cleanup); diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 2a41d7d7d1f48..1618eecc35346 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c @@ -478,9 +478,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me) if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { struct ip_conntrack_helper *ct_helper; - if ((ct_helper = ip_ct_find_helper(&me->tuple)) - && ct_helper->me) { - __MOD_INC_USE_COUNT(ct_helper->me); + if ((ct_helper = ip_ct_find_helper(&me->tuple))) { + if (!try_module_get(ct_helper->me)) + return -EBUSY; } else { /* We are a NAT helper for protocol X. If we need * respective conntrack helper for protoccol X, compute @@ -498,9 +498,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me) sprintf(name, "ip_conntrack%s", tmp); #ifdef CONFIG_KMOD if (!request_module(name) - && (ct_helper = ip_ct_find_helper(&me->tuple)) - && ct_helper->me) { - __MOD_INC_USE_COUNT(ct_helper->me); + && (ct_helper = ip_ct_find_helper(&me->tuple))) { + if (!try_module_get(ct_helper->me)) + return -EBUSY; } else { printk("unable to load module %s\n", name); return -EBUSY; @@ -516,10 +516,8 @@ int ip_nat_helper_register(struct ip_nat_helper *me) WRITE_LOCK(&ip_nat_lock); if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) ret = -EBUSY; - else { + else list_prepend(&helpers, me); - MOD_INC_USE_COUNT; - } WRITE_UNLOCK(&ip_nat_lock); return ret; @@ -539,13 +537,10 @@ kill_helper(const struct ip_conntrack *i, void *helper) void ip_nat_helper_unregister(struct ip_nat_helper *me) { - int found = 0; - WRITE_LOCK(&ip_nat_lock); /* Autoloading conntrack helper might have failed */ if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) { LIST_DELETE(&helpers, me); - found = 1; } WRITE_UNLOCK(&ip_nat_lock); @@ -562,18 +557,13 @@ void ip_nat_helper_unregister(struct ip_nat_helper *me) worse. --RR */ ip_ct_selective_cleanup(kill_helper, me); - if (found) - MOD_DEC_USE_COUNT; - /* If we are no standalone NAT helper, we need to decrement usage count * on our conntrack helper */ if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { struct ip_conntrack_helper *ct_helper; - if ((ct_helper = ip_ct_find_helper(&me->tuple)) - && ct_helper->me) { - __MOD_DEC_USE_COUNT(ct_helper->me); - } + if ((ct_helper = ip_ct_find_helper(&me->tuple))) + module_put(ct_helper->me); #ifdef CONFIG_MODULES else printk("%s: unable to decrement usage count" diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 825fc43dd28ae..151f944a9837b 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -255,8 +255,6 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) } list_prepend(&protos, proto); - MOD_INC_USE_COUNT; - out: WRITE_UNLOCK(&ip_nat_lock); return ret; @@ -272,14 +270,14 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) /* Someone could be still looking at the proto in a bh. */ br_write_lock_bh(BR_NETPROTO_LOCK); br_write_unlock_bh(BR_NETPROTO_LOCK); - - MOD_DEC_USE_COUNT; } static int init_or_cleanup(int init) { int ret = 0; + need_ip_conntrack(); + if (!init) goto cleanup; ret = ip_nat_rule_init(); @@ -314,13 +312,9 @@ static int init_or_cleanup(int init) goto cleanup_localoutops; } #endif - if (ip_conntrack_module) - __MOD_INC_USE_COUNT(ip_conntrack_module); return ret; cleanup: - if (ip_conntrack_module) - __MOD_DEC_USE_COUNT(ip_conntrack_module); #ifdef CONFIG_IP_NF_NAT_LOCAL nf_unregister_hook(&ip_nat_local_in_ops); cleanup_localoutops: diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index dbbbbf3d4ebe8..7946307d2e5d6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -598,10 +598,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i) if (m->u.kernel.match->destroy) m->u.kernel.match->destroy(m->data, m->u.match_size - sizeof(*m)); - - if (m->u.kernel.match->me) - __MOD_DEC_USE_COUNT(m->u.kernel.match->me); - + module_put(m->u.kernel.match->me); return 0; } @@ -650,8 +647,10 @@ check_match(struct ipt_entry_match *m, duprintf("check_match: `%s' not found\n", m->u.user.name); return ret; } - if (match->me) - __MOD_INC_USE_COUNT(match->me); + if (!try_module_get(match->me)) { + up(&ipt_mutex); + return -ENOENT; + } m->u.kernel.match = match; up(&ipt_mutex); @@ -659,8 +658,7 @@ check_match(struct ipt_entry_match *m, && !m->u.kernel.match->checkentry(name, ip, m->data, m->u.match_size - sizeof(*m), hookmask)) { - if (m->u.kernel.match->me) - __MOD_DEC_USE_COUNT(m->u.kernel.match->me); + module_put(m->u.kernel.match->me); duprintf("ip_tables: check failed for `%s'.\n", m->u.kernel.match->name); return -EINVAL; @@ -697,8 +695,11 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, duprintf("check_entry: `%s' not found\n", t->u.user.name); goto cleanup_matches; } - if (target->me) - __MOD_INC_USE_COUNT(target->me); + if (!try_module_get(target->me)) { + up(&ipt_mutex); + ret = -ENOENT; + goto cleanup_matches; + } t->u.kernel.target = target; up(&ipt_mutex); @@ -712,8 +713,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, t->u.target_size - sizeof(*t), e->comefrom)) { - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); + module_put(t->u.kernel.target->me); duprintf("ip_tables: check failed for `%s'.\n", t->u.kernel.target->name); ret = -EINVAL; @@ -785,9 +785,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) if (t->u.kernel.target->destroy) t->u.kernel.target->destroy(t->data, t->u.target_size - sizeof(*t)); - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); - + module_put(t->u.kernel.target->me); return 0; } @@ -1319,17 +1317,14 @@ ipt_register_target(struct ipt_target *target) { int ret; - MOD_INC_USE_COUNT; ret = down_interruptible(&ipt_mutex); - if (ret != 0) { - MOD_DEC_USE_COUNT; + if (ret != 0) return ret; - } + if (!list_named_insert(&ipt_target, target)) { duprintf("ipt_register_target: `%s' already in list!\n", target->name); ret = -EINVAL; - MOD_DEC_USE_COUNT; } up(&ipt_mutex); return ret; @@ -1341,7 +1336,6 @@ ipt_unregister_target(struct ipt_target *target) down(&ipt_mutex); LIST_DELETE(&ipt_target, target); up(&ipt_mutex); - MOD_DEC_USE_COUNT; } int @@ -1349,16 +1343,13 @@ ipt_register_match(struct ipt_match *match) { int ret; - MOD_INC_USE_COUNT; ret = down_interruptible(&ipt_mutex); - if (ret != 0) { - MOD_DEC_USE_COUNT; + if (ret != 0) return ret; - } + if (!list_named_insert(&ipt_match, match)) { duprintf("ipt_register_match: `%s' already in list!\n", match->name); - MOD_DEC_USE_COUNT; ret = -EINVAL; } up(&ipt_mutex); @@ -1372,7 +1363,6 @@ ipt_unregister_match(struct ipt_match *match) down(&ipt_mutex); LIST_DELETE(&ipt_match, match); up(&ipt_mutex); - MOD_DEC_USE_COUNT; } int ipt_register_table(struct ipt_table *table) @@ -1382,14 +1372,11 @@ int ipt_register_table(struct ipt_table *table) static struct ipt_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { } }; - MOD_INC_USE_COUNT; newinfo = vmalloc(sizeof(struct ipt_table_info) + SMP_ALIGN(table->table->size) * NR_CPUS); - if (!newinfo) { - ret = -ENOMEM; - MOD_DEC_USE_COUNT; - return ret; - } + if (!newinfo) + return -ENOMEM; + memcpy(newinfo->entries, table->table->entries, table->table->size); ret = translate_table(table->name, table->valid_hooks, @@ -1399,14 +1386,12 @@ int ipt_register_table(struct ipt_table *table) table->table->underflow); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } ret = down_interruptible(&ipt_mutex); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } @@ -1436,7 +1421,6 @@ int ipt_register_table(struct ipt_table *table) free_unlock: vfree(newinfo); - MOD_DEC_USE_COUNT; goto unlock; } @@ -1450,7 +1434,6 @@ void ipt_unregister_table(struct ipt_table *table) IPT_ENTRY_ITERATE(table->private->entries, table->private->size, cleanup_entry, NULL); vfree(table->private); - MOD_DEC_USE_COUNT; } /* Returns 1 if the port is matched by the range, 0 otherwise */ diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c index 751ab2b86dcd9..be3ab8af2cd40 100644 --- a/net/ipv4/netfilter/ipt_conntrack.c +++ b/net/ipv4/netfilter/ipt_conntrack.c @@ -105,17 +105,13 @@ static struct ipt_match conntrack_match static int __init init(void) { - /* NULL if ip_conntrack not a module */ - if (ip_conntrack_module) - __MOD_INC_USE_COUNT(ip_conntrack_module); + need_ip_conntrack(); return ipt_register_match(&conntrack_match); } static void __exit fini(void) { ipt_unregister_match(&conntrack_match); - if (ip_conntrack_module) - __MOD_DEC_USE_COUNT(ip_conntrack_module); } module_init(init); diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c index 5dd136d90f0e2..b722f7c211e47 100644 --- a/net/ipv4/netfilter/ipt_helper.c +++ b/net/ipv4/netfilter/ipt_helper.c @@ -94,17 +94,13 @@ static struct ipt_match helper_match static int __init init(void) { - /* NULL if ip_conntrack not a module */ - if (ip_conntrack_module) - __MOD_INC_USE_COUNT(ip_conntrack_module); + need_ip_conntrack(); return ipt_register_match(&helper_match); } static void __exit fini(void) { ipt_unregister_match(&helper_match); - if (ip_conntrack_module) - __MOD_DEC_USE_COUNT(ip_conntrack_module); } module_init(init); diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c index 1a273138a1e57..1849bf882dcfc 100644 --- a/net/ipv4/netfilter/ipt_state.c +++ b/net/ipv4/netfilter/ipt_state.c @@ -46,17 +46,13 @@ static struct ipt_match state_match static int __init init(void) { - /* NULL if ip_conntrack not a module */ - if (ip_conntrack_module) - __MOD_INC_USE_COUNT(ip_conntrack_module); + need_ip_conntrack(); return ipt_register_match(&state_match); } static void __exit fini(void) { ipt_unregister_match(&state_match); - if (ip_conntrack_module) - __MOD_DEC_USE_COUNT(ip_conntrack_module); } module_init(init); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 2f2eda2287a61..4eb41575b63e1 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -671,10 +671,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i) if (m->u.kernel.match->destroy) m->u.kernel.match->destroy(m->data, m->u.match_size - sizeof(*m)); - - if (m->u.kernel.match->me) - __MOD_DEC_USE_COUNT(m->u.kernel.match->me); - + module_put(m->u.kernel.match->me); return 0; } @@ -723,8 +720,10 @@ check_match(struct ip6t_entry_match *m, // duprintf("check_match: `%s' not found\n", m->u.name); return ret; } - if (match->me) - __MOD_INC_USE_COUNT(match->me); + if (!try_module_get(match->me)) { + up(&ip6t_mutex); + return -ENOENT; + } m->u.kernel.match = match; up(&ip6t_mutex); @@ -732,8 +731,7 @@ check_match(struct ip6t_entry_match *m, && !m->u.kernel.match->checkentry(name, ipv6, m->data, m->u.match_size - sizeof(*m), hookmask)) { - if (m->u.kernel.match->me) - __MOD_DEC_USE_COUNT(m->u.kernel.match->me); + module_put(m->u.kernel.match->me); duprintf("ip_tables: check failed for `%s'.\n", m->u.kernel.match->name); return -EINVAL; @@ -770,11 +768,17 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, duprintf("check_entry: `%s' not found\n", t->u.user.name); goto cleanup_matches; } - if (target->me) - __MOD_INC_USE_COUNT(target->me); + if (!try_module_get(target->me)) { + up(&ip6t_mutex); + ret = -ENOENT; + goto cleanup_matches; + } t->u.kernel.target = target; up(&ip6t_mutex); - + if (!t->u.kernel.target) { + ret = -EBUSY; + goto cleanup_matches; + } if (t->u.kernel.target == &ip6t_standard_target) { if (!standard_check(t, size)) { ret = -EINVAL; @@ -785,8 +789,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, t->u.target_size - sizeof(*t), e->comefrom)) { - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); + module_put(t->u.kernel.target->me); duprintf("ip_tables: check failed for `%s'.\n", t->u.kernel.target->name); ret = -EINVAL; @@ -858,9 +861,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) if (t->u.kernel.target->destroy) t->u.kernel.target->destroy(t->data, t->u.target_size - sizeof(*t)); - if (t->u.kernel.target->me) - __MOD_DEC_USE_COUNT(t->u.kernel.target->me); - + module_put(t->u.kernel.target->me); return 0; } @@ -1388,17 +1389,14 @@ ip6t_register_target(struct ip6t_target *target) { int ret; - MOD_INC_USE_COUNT; ret = down_interruptible(&ip6t_mutex); - if (ret != 0) { - MOD_DEC_USE_COUNT; + if (ret != 0) return ret; - } + if (!list_named_insert(&ip6t_target, target)) { duprintf("ip6t_register_target: `%s' already in list!\n", target->name); ret = -EINVAL; - MOD_DEC_USE_COUNT; } up(&ip6t_mutex); return ret; @@ -1410,7 +1408,6 @@ ip6t_unregister_target(struct ip6t_target *target) down(&ip6t_mutex); LIST_DELETE(&ip6t_target, target); up(&ip6t_mutex); - MOD_DEC_USE_COUNT; } int @@ -1418,16 +1415,13 @@ ip6t_register_match(struct ip6t_match *match) { int ret; - MOD_INC_USE_COUNT; ret = down_interruptible(&ip6t_mutex); - if (ret != 0) { - MOD_DEC_USE_COUNT; + if (ret != 0) return ret; - } + if (!list_named_insert(&ip6t_match, match)) { duprintf("ip6t_register_match: `%s' already in list!\n", match->name); - MOD_DEC_USE_COUNT; ret = -EINVAL; } up(&ip6t_mutex); @@ -1441,7 +1435,6 @@ ip6t_unregister_match(struct ip6t_match *match) down(&ip6t_mutex); LIST_DELETE(&ip6t_match, match); up(&ip6t_mutex); - MOD_DEC_USE_COUNT; } int ip6t_register_table(struct ip6t_table *table) @@ -1451,14 +1444,11 @@ int ip6t_register_table(struct ip6t_table *table) static struct ip6t_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { }, { } }; - MOD_INC_USE_COUNT; newinfo = vmalloc(sizeof(struct ip6t_table_info) + SMP_ALIGN(table->table->size) * NR_CPUS); - if (!newinfo) { - ret = -ENOMEM; - MOD_DEC_USE_COUNT; - return ret; - } + if (!newinfo) + return -ENOMEM; + memcpy(newinfo->entries, table->table->entries, table->table->size); ret = translate_table(table->name, table->valid_hooks, @@ -1468,14 +1458,12 @@ int ip6t_register_table(struct ip6t_table *table) table->table->underflow); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } ret = down_interruptible(&ip6t_mutex); if (ret != 0) { vfree(newinfo); - MOD_DEC_USE_COUNT; return ret; } @@ -1505,7 +1493,6 @@ int ip6t_register_table(struct ip6t_table *table) free_unlock: vfree(newinfo); - MOD_DEC_USE_COUNT; goto unlock; } @@ -1519,7 +1506,6 @@ void ip6t_unregister_table(struct ip6t_table *table) IP6T_ENTRY_ITERATE(table->private->entries, table->private->size, cleanup_entry, NULL); vfree(table->private); - MOD_DEC_USE_COUNT; } /* Returns 1 if the port is matched by the range, 0 otherwise */ -- 2.53.0