projects
/
project
/
netifd.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
5c0c0bb
)
bridge: fix cleanup path, avoid double free on hotplug device remove
author
Felix Fietkau
<nbd@openwrt.org>
Thu, 3 Nov 2011 23:47:40 +0000
(
00:47
+0100)
committer
Felix Fietkau
<nbd@openwrt.org>
Thu, 3 Nov 2011 23:47:40 +0000
(
00:47
+0100)
bridge.c
patch
|
blob
|
history
diff --git
a/bridge.c
b/bridge.c
index
54526f7
..
5ff7081
100644
(file)
--- a/
bridge.c
+++ b/
bridge.c
@@
-119,6
+119,23
@@
error:
}
static void
}
static void
+bridge_remove_member(struct bridge_member *bm)
+{
+ struct bridge_state *bst = bm->bst;
+
+ if (!bm->present)
+ return;
+
+ bm->present = false;
+ bm->bst->n_present--;
+ if (bst->dev.active)
+ bridge_disable_member(bm);
+
+ if (bst->n_present == 0)
+ device_set_present(&bst->dev, false);
+}
+
+static void
bridge_member_cb(struct device_user *dev, enum device_event ev)
{
struct bridge_member *bm = container_of(dev, struct bridge_member, dev);
bridge_member_cb(struct device_user *dev, enum device_event ev)
{
struct bridge_member *bm = container_of(dev, struct bridge_member, dev);
@@
-141,16
+158,11
@@
bridge_member_cb(struct device_user *dev, enum device_event ev)
if (!bm->present)
return;
if (!bm->present)
return;
- if (bst->dev.active)
- bridge_disable_member(bm);
-
- bm->present = false;
- bm->bst->n_present--;
- if (bst->n_present == 0)
- device_set_present(&bst->dev, false);
-
if (dev->hotplug)
bridge_free_member(bm);
if (dev->hotplug)
bridge_free_member(bm);
+ else
+ bridge_remove_member(bm);
+
break;
default:
return;
break;
default:
return;
@@
-235,15
+247,9
@@
bridge_create_member(struct bridge_state *bst, struct device *dev, bool hotplug)
static void
bridge_free_member(struct bridge_member *bm)
{
static void
bridge_free_member(struct bridge_member *bm)
{
- if (bm->present) {
- bridge_member_cb(&bm->dev, DEV_EVENT_REMOVE);
- bm->bst->n_present--;
- if (bm->bst->dev.active)
- bridge_disable_member(bm);
- }
-
- list_del(&bm->list);
+ bridge_remove_member(bm);
device_remove_user(&bm->dev);
device_remove_user(&bm->dev);
+ list_del(&bm->list);
free(bm);
}
free(bm);
}