diff options
-rw-r--r-- | sys/netgraph/ng_base.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 8b14e90..78b4aaa 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -1142,11 +1142,11 @@ ng_newtype(struct ng_type *tp) return (EEXIST); } - tp->refs = 0; /* Link in new type */ mtx_enter(&ng_typelist_mtx, MTX_DEF); LIST_INSERT_HEAD(&ng_typelist, tp, types); + tp->refs = 1; /* first ref is linked list */ mtx_exit(&ng_typelist_mtx, MTX_DEF); return (0); } @@ -2678,7 +2678,7 @@ ng_generic_msg(node_p here, item_p item, hook_p lasthook) break; } strncpy(tp->type_name, type->name, NG_TYPELEN); - tp->numnodes = type->refs; + tp->numnodes = type->refs - 1; /* don't count list */ tl->numtypes++; } mtx_exit(&ng_typelist_mtx, MTX_DEF); @@ -2909,6 +2909,7 @@ ng_mod_event(module_t mod, int event, void *data) if (type->mod_event != NULL) if ((error = (*type->mod_event)(mod, event, data))) { mtx_enter(&ng_typelist_mtx, MTX_DEF); + type->refs--; /* undo it */ LIST_REMOVE(type, types); mtx_exit(&ng_typelist_mtx, MTX_DEF); } @@ -2917,9 +2918,14 @@ ng_mod_event(module_t mod, int event, void *data) case MOD_UNLOAD: s = splnet(); - if (type->refs != 0) /* make sure no nodes exist! */ + if (type->refs > 1) { /* make sure no nodes exist! */ error = EBUSY; - else { + } else { + if (type->refs == 0) { + /* failed load, nothing to undo */ + splx(s); + break; + } if (type->mod_event != NULL) { /* check with type */ error = (*type->mod_event)(mod, event, data); if (error != 0) { /* type refuses.. */ |