X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fcore%2Fdst.c;h=fe03266130b62f4950bac5ef4786755e88617a54;hb=63a16f90167850010864a9e8ebb71d216983090f;hp=5c6cfc4e7fdbe2bcaf393b9e1692834cfe3c0b74;hpb=5a3e55d68ec5baac578bf32ba67607088c763657;p=linux-2.6 diff --git a/net/core/dst.c b/net/core/dst.c index 5c6cfc4e7f..fe03266130 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -165,7 +165,7 @@ void * dst_alloc(struct dst_ops * ops) struct dst_entry * dst; if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { - if (ops->gc()) + if (ops->gc(ops)) return NULL; } dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC); @@ -259,6 +259,16 @@ again: return NULL; } +void dst_release(struct dst_entry *dst) +{ + if (dst) { + WARN_ON(atomic_read(&dst->__refcnt) < 1); + smp_mb__before_atomic_dec(); + atomic_dec(&dst->__refcnt); + } +} +EXPORT_SYMBOL(dst_release); + /* Dirty hack. We did it in 2.2 (in __dst_free), * we have _very_ good reasons not to repeat * this mistake in 2.3, but we have no choice @@ -279,13 +289,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, if (!unregister) { dst->input = dst->output = dst_discard; } else { - dst->dev = dst->dev->nd_net->loopback_dev; + dst->dev = dev_net(dst->dev)->loopback_dev; dev_hold(dst->dev); dev_put(dev); if (dst->neighbour && dst->neighbour->dev == dev) { dst->neighbour->dev = dst->dev; + dev_hold(dst->dev); dev_put(dev); - dev_hold(dst->neighbour->dev); } } } @@ -295,9 +305,6 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void struct net_device *dev = ptr; struct dst_entry *dst, *last = NULL; - if (dev->nd_net != &init_net) - return NOTIFY_DONE; - switch (event) { case NETDEV_UNREGISTER: case NETDEV_DOWN: