diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-18 17:56:43 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-18 17:56:43 -0800 |
| commit | 27cd7e0feb7d4e8ddc87296bf30ad0de3b19f4c0 (patch) | |
| tree | 43323e6369cc01fa82c09b97058c5e50a89e66a8 /net | |
| parent | f319c80942729320e8725e61272dcd290d30fef6 (diff) | |
| parent | c4620fd637bc33f0c2efabd43586de03675336cd (diff) | |
Merge http://linux-sound.bkbits.net/linux-sound
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/dev.c | 48 | ||||
| -rw-r--r-- | net/core/flow.c | 12 | ||||
| -rw-r--r-- | net/decnet/README | 2 | ||||
| -rw-r--r-- | net/key/af_key.c | 30 | ||||
| -rw-r--r-- | net/sched/Kconfig | 11 | ||||
| -rw-r--r-- | net/sched/Makefile | 1 | ||||
| -rw-r--r-- | net/sched/sch_delay.c | 269 | ||||
| -rw-r--r-- | net/sched/sch_hfsc.c | 77 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 4 |
9 files changed, 394 insertions, 60 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index b4418fb5eb25..201878db9853 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -76,6 +76,7 @@ #include <asm/system.h> #include <asm/bitops.h> #include <linux/config.h> +#include <linux/cpu.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -3131,6 +3132,52 @@ int unregister_netdevice(struct net_device *dev) return 0; } +#ifdef CONFIG_HOTPLUG_CPU +static int dev_cpu_callback(struct notifier_block *nfb, + unsigned long action, + void *ocpu) +{ + struct sk_buff **list_skb; + struct net_device **list_net; + struct sk_buff *skb; + unsigned int cpu, oldcpu = (unsigned long)ocpu; + struct softnet_data *sd, *oldsd; + + if (action != CPU_DEAD) + return NOTIFY_OK; + + local_irq_disable(); + cpu = smp_processor_id(); + sd = &per_cpu(softnet_data, cpu); + oldsd = &per_cpu(softnet_data, oldcpu); + + /* Find end of our completion_queue. */ + list_skb = &sd->completion_queue; + while (*list_skb) + list_skb = &(*list_skb)->next; + /* Append completion queue from offline CPU. */ + *list_skb = oldsd->completion_queue; + oldsd->completion_queue = NULL; + + /* Find end of our output_queue. */ + list_net = &sd->output_queue; + while (*list_net) + list_net = &(*list_net)->next_sched; + /* Append output queue from offline CPU. */ + *list_net = oldsd->output_queue; + oldsd->output_queue = NULL; + + raise_softirq_irqoff(NET_TX_SOFTIRQ); + local_irq_enable(); + + /* Process offline CPU's input_pkt_queue */ + while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) + netif_rx(skb); + + return NOTIFY_OK; +} +#endif /* CONFIG_HOTPLUG_CPU */ + /* * Initialize the DEV module. At boot time this walks the device list and @@ -3195,6 +3242,7 @@ static int __init net_dev_init(void) open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); + hotcpu_notifier(dev_cpu_callback, 0); dst_init(); dev_mcast_init(); rc = 0; diff --git a/net/core/flow.c b/net/core/flow.c index cef037afdf41..f289570b15a3 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -326,6 +326,17 @@ static void __devinit flow_cache_cpu_prepare(int cpu) tasklet_init(tasklet, flow_cache_flush_tasklet, 0); } +#ifdef CONFIG_HOTPLUG_CPU +static int flow_cache_cpu(struct notifier_block *nfb, + unsigned long action, + void *hcpu) +{ + if (action == CPU_DEAD) + __flow_cache_shrink((unsigned long)hcpu, 0); + return NOTIFY_OK; +} +#endif /* CONFIG_HOTPLUG_CPU */ + static int __init flow_cache_init(void) { int i; @@ -350,6 +361,7 @@ static int __init flow_cache_init(void) for_each_cpu(i) flow_cache_cpu_prepare(i); + hotcpu_notifier(flow_cache_cpu, 0); return 0; } diff --git a/net/decnet/README b/net/decnet/README index 4d0d235abbf5..60e7ec88c81f 100644 --- a/net/decnet/README +++ b/net/decnet/README @@ -2,7 +2,7 @@ ====================== The documentation for this kernel subsystem is available in the -Documentation/networking subdirctory of this distribution and also +Documentation/networking subdirectory of this distribution and also on line at http://www.chygwyn.com/DECnet/ Steve Whitehouse <SteveW@ACM.org> diff --git a/net/key/af_key.c b/net/key/af_key.c index 9f82962d1d93..2620f69143f9 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -901,6 +901,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, struct sadb_sa *sa; struct sadb_key *key; uint16_t proto; + int err; sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1]; @@ -922,6 +923,9 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, if (proto == 0) return ERR_PTR(-EINVAL); + /* default error is no buffer space */ + err = -ENOBUFS; + /* RFC2367: Only SADB_SASTATE_MATURE SAs may be submitted in an SADB_ADD message. @@ -980,8 +984,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, if (sa->sadb_sa_auth) { int keysize = 0; struct xfrm_algo_desc *a = xfrm_aalg_get_byid(sa->sadb_sa_auth); - if (!a) + if (!a) { + err = -ENOSYS; goto out; + } if (key) keysize = (key->sadb_key_bits + 7) / 8; x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL); @@ -999,8 +1005,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, if (sa->sadb_sa_encrypt) { if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt); - if (!a) + if (!a) { + err = -ENOSYS; goto out; + } x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL); if (!x->calg) goto out; @@ -1009,8 +1017,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, } else { int keysize = 0; struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt); - if (!a) + if (!a) { + err = -ENOSYS; goto out; + } key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; if (key) keysize = (key->sadb_key_bits + 7) / 8; @@ -1030,8 +1040,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], &x->props.saddr); - if (!x->props.family) + if (!x->props.family) { + err = -EAFNOSUPPORT; goto out; + } pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], &x->id.daddr); @@ -1076,10 +1088,14 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, } x->type = xfrm_get_type(proto, x->props.family); - if (x->type == NULL) + if (x->type == NULL) { + err = -ENOPROTOOPT; goto out; - if (x->type->init_state(x, NULL)) + } + if (x->type->init_state(x, NULL)) { + err = -EINVAL; goto out; + } x->km.seq = hdr->sadb_msg_seq; x->km.state = XFRM_STATE_VALID; return x; @@ -1087,7 +1103,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, out: x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); - return ERR_PTR(-ENOBUFS); + return ERR_PTR(err); } static int pfkey_reserved(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 076f576b3ee2..46dd1b7b5678 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -164,6 +164,17 @@ config NET_SCH_DSMARK To compile this code as a module, choose M here: the module will be called sch_dsmark. +config NET_SCH_DELAY + tristate "Delay simulator" + depends on NET_SCHED + help + Say Y if you want to delay packets by a fixed amount of + time. This is often useful to simulate network delay when + testing applications or protocols. + + To compile this driver as a module, choose M here: the module + will be called sch_delay. + config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_SCHED && NETFILTER diff --git a/net/sched/Makefile b/net/sched/Makefile index 525b9956c51e..af4a4f284d3a 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o +obj-$(CONFIG_NET_SCH_DELAY) += sch_delay.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o obj-$(CONFIG_NET_CLS_FW) += cls_fw.o diff --git a/net/sched/sch_delay.c b/net/sched/sch_delay.c new file mode 100644 index 000000000000..9c8a3ce6231e --- /dev/null +++ b/net/sched/sch_delay.c @@ -0,0 +1,269 @@ +/* + * net/sched/sch_delay.c Simple constant delay + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Stephen Hemminger <shemminger@osdl.org> + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> + +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/socket.h> +#include <linux/sockios.h> +#include <linux/in.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/if_ether.h> +#include <linux/inet.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/notifier.h> +#include <net/ip.h> +#include <net/route.h> +#include <linux/skbuff.h> +#include <net/sock.h> +#include <net/pkt_sched.h> + +/* Network delay simulator + This scheduler adds a fixed delay to all packets. + Similar to NISTnet and BSD Dummynet. + + It uses byte fifo underneath similar to TBF */ +struct dly_sched_data { + u32 latency; + u32 limit; + struct timer_list timer; + struct Qdisc *qdisc; +}; + +/* Time stamp put into socket buffer control block */ +struct dly_skb_cb { + psched_time_t queuetime; +}; + +/* Enqueue packets with underlying discipline (fifo) + * but mark them with current time first. + */ +static int dly_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb; + int ret; + + PSCHED_GET_TIME(cb->queuetime); + + /* Queue to underlying scheduler */ + ret = q->qdisc->enqueue(skb, q->qdisc); + if (ret) + sch->stats.drops++; + else { + sch->q.qlen++; + sch->stats.bytes += skb->len; + sch->stats.packets++; + } + return 0; +} + +/* Requeue packets but don't change time stamp */ +static int dly_requeue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + int ret; + + ret = q->qdisc->ops->requeue(skb, q->qdisc); + if (ret == 0) + sch->q.qlen++; + return ret; +} + +static unsigned int dly_drop(struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + unsigned int len; + + len = q->qdisc->ops->drop(q->qdisc); + if (len) { + sch->q.qlen--; + sch->stats.drops++; + } + return len; +} + +/* Dequeue packet. + * If packet needs to be held up, then stop the + * queue and set timer to wakeup later. + */ +static struct sk_buff *dly_dequeue(struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + struct sk_buff *skb = q->qdisc->dequeue(q->qdisc); + + if (skb) { + struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb; + psched_time_t now; + long diff; + + PSCHED_GET_TIME(now); + diff = q->latency - PSCHED_TDIFF(now, cb->queuetime); + + if (diff <= 0) { + sch->q.qlen--; + sch->flags &= ~TCQ_F_THROTTLED; + return skb; + } + + if (!netif_queue_stopped(sch->dev)) { + long delay = PSCHED_US2JIFFIE(diff); + if (delay <= 0) + delay = 1; + mod_timer(&q->timer, jiffies+delay); + } + + if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) { + sch->q.qlen--; + sch->stats.drops++; + } + sch->flags |= TCQ_F_THROTTLED; + } + return NULL; +} + +static void dly_reset(struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + + qdisc_reset(q->qdisc); + sch->q.qlen = 0; + sch->flags &= ~TCQ_F_THROTTLED; + del_timer(&q->timer); +} + +static void dly_timer(unsigned long arg) +{ + struct Qdisc *sch = (struct Qdisc *)arg; + + sch->flags &= ~TCQ_F_THROTTLED; + netif_schedule(sch->dev); +} + +/* Tell Fifo the new limit. */ +static int change_limit(struct Qdisc *q, u32 limit) +{ + struct rtattr *rta; + int ret; + + rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); + if (!rta) + return -ENOMEM; + + rta->rta_type = RTM_NEWQDISC; + ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit; + ret = q->ops->change(q, rta); + kfree(rta); + + return ret; +} + +/* Setup underlying FIFO discipline */ +static int dly_change(struct Qdisc *sch, struct rtattr *opt) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + struct tc_dly_qopt *qopt = RTA_DATA(opt); + int err; + + if (q->qdisc == &noop_qdisc) { + struct Qdisc *child + = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops); + if (!child) + return -EINVAL; + q->qdisc = child; + } + + err = change_limit(q->qdisc, qopt->limit); + if (err) { + qdisc_destroy(q->qdisc); + q->qdisc = &noop_qdisc; + } else { + q->latency = qopt->latency; + q->limit = qopt->limit; + } + return err; +} + +static int dly_init(struct Qdisc *sch, struct rtattr *opt) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + + if (!opt) + return -EINVAL; + + init_timer(&q->timer); + q->timer.function = dly_timer; + q->timer.data = (unsigned long) sch; + q->qdisc = &noop_qdisc; + + return dly_change(sch, opt); +} + +static void dly_destroy(struct Qdisc *sch) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + + del_timer(&q->timer); + qdisc_destroy(q->qdisc); + q->qdisc = &noop_qdisc; +} + +static int dly_dump(struct Qdisc *sch, struct sk_buff *skb) +{ + struct dly_sched_data *q = (struct dly_sched_data *)sch->data; + unsigned char *b = skb->tail; + struct tc_dly_qopt qopt; + + qopt.latency = q->latency; + qopt.limit = q->limit; + + RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); + + return skb->len; + +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +static struct Qdisc_ops dly_qdisc_ops = { + .id = "delay", + .priv_size = sizeof(struct dly_sched_data), + .enqueue = dly_enqueue, + .dequeue = dly_dequeue, + .requeue = dly_requeue, + .drop = dly_drop, + .init = dly_init, + .reset = dly_reset, + .destroy = dly_destroy, + .change = dly_change, + .dump = dly_dump, + .owner = THIS_MODULE, +}; + + +static int __init dly_module_init(void) +{ + return register_qdisc(&dly_qdisc_ops); +} +static void __exit dly_module_exit(void) +{ + unregister_qdisc(&dly_qdisc_ops); +} +module_init(dly_module_init) +module_exit(dly_module_exit) +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 1b09227a8831..46073c3f04bf 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -118,7 +118,7 @@ enum hfsc_class_flags struct hfsc_class { - u32 classid; /* class id */ + u32 classid; /* class id */ unsigned int refcnt; /* usage count */ struct tc_stats stats; /* generic statistics */ @@ -138,28 +138,28 @@ struct hfsc_class struct list_head hlist; /* hash list member */ struct list_head dlist; /* drop list member */ - u64 cl_total; /* total work in bytes */ - u64 cl_cumul; /* cumulative work in bytes done by + u64 cl_total; /* total work in bytes */ + u64 cl_cumul; /* cumulative work in bytes done by real-time criteria */ - u64 cl_d; /* deadline*/ - u64 cl_e; /* eligible time */ - u64 cl_vt; /* virtual time */ - u64 cl_f; /* time when this class will fit for + u64 cl_d; /* deadline*/ + u64 cl_e; /* eligible time */ + u64 cl_vt; /* virtual time */ + u64 cl_f; /* time when this class will fit for link-sharing, max(myf, cfmin) */ - u64 cl_myf; /* my fit-time (calculated from this + u64 cl_myf; /* my fit-time (calculated from this class's own upperlimit curve) */ - u64 cl_myfadj; /* my fit-time adjustment (to cancel + u64 cl_myfadj; /* my fit-time adjustment (to cancel history dependence) */ - u64 cl_cfmin; /* earliest children's fit-time (used + u64 cl_cfmin; /* earliest children's fit-time (used with cl_myf to obtain cl_f) */ - u64 cl_cvtmin; /* minimal virtual time among the + u64 cl_cvtmin; /* minimal virtual time among the children fit for link-sharing (monotonic within a period) */ - u64 cl_vtadj; /* intra-period cumulative vt + u64 cl_vtadj; /* intra-period cumulative vt adjustment */ - u64 cl_vtoff; /* inter-period cumulative vt offset */ - u64 cl_cvtmax; /* max child's vt in the last period */ + u64 cl_vtoff; /* inter-period cumulative vt offset */ + u64 cl_cvtmax; /* max child's vt in the last period */ struct internal_sc cl_rsc; /* internal real-time service curve */ struct internal_sc cl_fsc; /* internal fair service curve */ @@ -179,15 +179,13 @@ struct hfsc_class struct hfsc_sched { - u16 defcls; /* default class id */ - + u16 defcls; /* default class id */ struct hfsc_class root; /* root class */ - struct hfsc_class *last_xmit; /* class that transmitted last - packet (for requeueing) */ struct list_head clhash[HFSC_HSIZE]; /* class hash */ struct list_head eligible; /* eligible list */ struct list_head droplist; /* active leaf class list (for dropping) */ + struct sk_buff_head requeue; /* requeued packet */ struct timer_list wd_timer; /* watchdog timer */ }; @@ -566,8 +564,7 @@ sc2isc(struct tc_service_curve *sc, struct internal_sc *isc) * service curve starting at (x, y). */ static void -rtsc_init(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, - u64 y) +rtsc_init(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y) { rtsc->x = x; rtsc->y = y; @@ -626,8 +623,7 @@ rtsc_x2y(struct runtime_sc *rtsc, u64 x) * runtime service curve and the service curve starting at (x, y). */ static void -rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, - u64 y) +rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y) { u64 y1, y2, dx, dy; u32 dsm; @@ -1231,9 +1227,6 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg) list_del(&cl->siblings); hfsc_adjust_levels(cl->cl_parent); hfsc_purge_queue(sch, cl); - if (q->last_xmit == cl) - q->last_xmit = NULL; - if (--cl->refcnt == 0) hfsc_destroy_class(sch, cl); @@ -1541,6 +1534,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt) INIT_LIST_HEAD(&q->clhash[i]); INIT_LIST_HEAD(&q->eligible); INIT_LIST_HEAD(&q->droplist); + skb_queue_head_init(&q->requeue); q->root.refcnt = 1; q->root.classid = sch->handle; @@ -1619,10 +1613,9 @@ hfsc_reset_qdisc(struct Qdisc *sch) list_for_each_entry(cl, &q->clhash[i], hlist) hfsc_reset_class(cl); } - + __skb_queue_purge(&q->requeue); INIT_LIST_HEAD(&q->eligible); INIT_LIST_HEAD(&q->droplist); - q->last_xmit = NULL; del_timer(&q->wd_timer); sch->flags &= ~TCQ_F_THROTTLED; sch->q.qlen = 0; @@ -1639,7 +1632,7 @@ hfsc_destroy_qdisc(struct Qdisc *sch) list_for_each_entry_safe(cl, next, &q->clhash[i], hlist) hfsc_destroy_class(sch, cl); } - + __skb_queue_purge(&q->requeue); del_timer(&q->wd_timer); } @@ -1708,6 +1701,8 @@ hfsc_dequeue(struct Qdisc *sch) if (sch->q.qlen == 0) return NULL; + if ((skb = __skb_dequeue(&q->requeue))) + goto out; PSCHED_GET_TIME(cur_time); @@ -1757,7 +1752,7 @@ hfsc_dequeue(struct Qdisc *sch) set_passive(cl); } - q->last_xmit = cl; + out: sch->flags &= ~TCQ_F_THROTTLED; sch->q.qlen--; @@ -1768,28 +1763,10 @@ static int hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch) { struct hfsc_sched *q = (struct hfsc_sched *)sch->data; - struct hfsc_class *cl = q->last_xmit; - unsigned int len = skb->len; - int ret; - - if (cl == NULL) { - kfree_skb(skb); - sch->stats.drops++; - return NET_XMIT_DROP; - } - ret = cl->qdisc->ops->requeue(skb, cl->qdisc); - if (ret == NET_XMIT_SUCCESS) { - if (cl->qdisc->q.qlen == 1) - set_active(cl, len); - sch->q.qlen++; - } else { - cl->stats.drops++; - sch->stats.drops++; - } - q->last_xmit = NULL; - - return ret; + __skb_queue_head(&q->requeue, skb); + sch->q.qlen++; + return NET_XMIT_SUCCESS; } static unsigned int diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 69e641f1d00e..146a454032d8 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -691,7 +691,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len, goto put_fail; if (u->sk_type == type) - update_atime(nd.dentry->d_inode); + touch_atime(nd.mnt, nd.dentry); path_release(&nd); @@ -707,7 +707,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len, struct dentry *dentry; dentry = unix_sk(u)->dentry; if (dentry) - update_atime(dentry->d_inode); + touch_atime(unix_sk(u)->mnt, dentry); } else goto fail; } |
