Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e56cfad1 authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller
Browse files

[NET_SCHED] cls_u32: refcounting fix for u32_delete()



Deleting of nonroot hnodes mostly doesn't work in u32_delete():
refcnt == 1 is expected, but such hnodes' refcnts are initialized
with 0 and charged only with "link" nodes. Now they'll start with
1 like usual. Thanks to Patrick McHardy for an improving suggestion.

Signed-off-by: default avatarJarek Poplawski <jarkao2@gmail.com>
Acked-by: default avatarJamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 028b0275
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -411,8 +411,10 @@ static void u32_destroy(struct tcf_proto *tp)
			}
		}

		for (ht=tp_c->hlist; ht; ht = ht->next)
		for (ht = tp_c->hlist; ht; ht = ht->next) {
			ht->refcnt--;
			u32_clear_hnode(tp, ht);
		}

		while ((ht = tp_c->hlist) != NULL) {
			tp_c->hlist = ht->next;
@@ -441,8 +443,12 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)
	if (tp->root == ht)
		return -EINVAL;

	if (--ht->refcnt == 0)
	if (ht->refcnt == 1) {
		ht->refcnt--;
		u32_destroy_hnode(tp, ht);
	} else {
		return -EBUSY;
	}

	return 0;
}
@@ -568,7 +574,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
		if (ht == NULL)
			return -ENOBUFS;
		ht->tp_c = tp_c;
		ht->refcnt = 0;
		ht->refcnt = 1;
		ht->divisor = divisor;
		ht->handle = handle;
		ht->prio = tp->prio;