diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /net | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'net')
-rw-r--r-- | net/802/Makefile | 2 | ||||
-rw-r--r-- | net/802/cl2llc.c | 2 | ||||
-rw-r--r-- | net/802/cl2llc.pre | 2 | ||||
-rw-r--r-- | net/802/fddi.c | 33 | ||||
-rw-r--r-- | net/802/llc_macinit.c | 13 | ||||
-rw-r--r-- | net/802/llc_sendpdu.c | 3 | ||||
-rw-r--r-- | net/Config.in | 3 | ||||
-rw-r--r-- | net/appletalk/aarp.c | 29 | ||||
-rw-r--r-- | net/appletalk/ddp.c | 149 | ||||
-rw-r--r-- | net/ax25/af_ax25.c | 4 | ||||
-rw-r--r-- | net/core/datagram.c | 2 | ||||
-rw-r--r-- | net/core/sock.c | 2 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 4 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 12 | ||||
-rw-r--r-- | net/ipx/af_ipx.c | 60 | ||||
-rw-r--r-- | net/netlink.c | 14 | ||||
-rw-r--r-- | net/netrom/af_netrom.c | 4 | ||||
-rw-r--r-- | net/netsyms.c | 1 | ||||
-rw-r--r-- | net/rose/af_rose.c | 4 | ||||
-rw-r--r-- | net/socket.c | 32 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 71 | ||||
-rw-r--r-- | net/sunrpc/pmap_clnt.c | 15 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 122 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 40 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 8 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 24 | ||||
-rw-r--r-- | net/unix/af_unix.c | 6 | ||||
-rw-r--r-- | net/x25/af_x25.c | 4 |
29 files changed, 390 insertions, 278 deletions
diff --git a/net/802/Makefile b/net/802/Makefile index a8d25f77e..cea2410d8 100644 --- a/net/802/Makefile +++ b/net/802/Makefile @@ -17,7 +17,7 @@ endif ifeq ($(CONFIG_LLC),y) SUB_DIRS += transit O_OBJS += llc_sendpdu.o llc_utility.o cl2llc.o -OX_OBJS += llc_macinit.o +OX_OBJS += llc_macinit.o p8022.o psnap.o p8022tr.o endif ifdef CONFIG_TR diff --git a/net/802/cl2llc.c b/net/802/cl2llc.c index 5e1d12837..8d236b4c4 100644 --- a/net/802/cl2llc.c +++ b/net/802/cl2llc.c @@ -196,7 +196,7 @@ void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, switch(pseudo_code[pc]) { case 9: - if ((type != I_CMD) || (fr->i_hdr.i_pflag =0)) + if ((type != I_CMD) || (fr->i_hdr.i_pflag == 0)) break; case 1: lp->remote_busy = 0; diff --git a/net/802/cl2llc.pre b/net/802/cl2llc.pre index 8e10cf32a..023c2b45c 100644 --- a/net/802/cl2llc.pre +++ b/net/802/cl2llc.pre @@ -196,7 +196,7 @@ void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, switch(pseudo_code[pc]) { case IF_F=1_CLEAR_REMOTE_BUSY: - if ((type != I_CMD) || (fr->i_hdr.i_pflag =0)) + if ((type != I_CMD) || (fr->i_hdr.i_pflag == 0)) break; case CLEAR_REMOTE_BUSY: lp->remote_busy = 0; diff --git a/net/802/fddi.c b/net/802/fddi.c index c57a967d1..a282cc386 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -56,11 +56,11 @@ int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type, int hl = FDDI_K_SNAP_HLEN; struct fddihdr *fddi; - if(type!=htons(ETH_P_IP)) + if(type != ETH_P_IP && type != ETH_P_ARP) hl=FDDI_K_8022_HLEN-3; fddi = (struct fddihdr *)skb_push(skb, hl); fddi->fc = FDDI_FC_K_ASYNC_LLC_DEF; - if(type==htons(ETH_P_IP)) + if(type == ETH_P_IP || type == ETH_P_ARP) { fddi->hdr.llc_snap.dsap = FDDI_EXTENDED_SAP; fddi->hdr.llc_snap.ssap = FDDI_EXTENDED_SAP; @@ -68,7 +68,7 @@ int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type, fddi->hdr.llc_snap.oui[0] = 0x00; fddi->hdr.llc_snap.oui[1] = 0x00; fddi->hdr.llc_snap.oui[2] = 0x00; - fddi->hdr.llc_snap.ethertype = htons(type); + fddi->hdr.llc_snap.ethertype = htons(type); } /* Set the source and destination hardware addresses */ @@ -83,6 +83,7 @@ int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type, memcpy(fddi->daddr, daddr, dev->addr_len); return(hl); } + return(-hl); } @@ -96,18 +97,29 @@ int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type, int fddi_rebuild_header(struct sk_buff *skb) { struct fddihdr *fddi = (struct fddihdr *)skb->data; +#if 0 + struct neighbour *neigh = NULL; - /* Only ARP/IP is currently supported */ - - if (fddi->hdr.llc_snap.ethertype != htons(ETH_P_IP)) + if (skb->dst) + neigh = skb->dst->neighbour; + + if (neigh) + return neigh->ops->resolve(fddi->daddr, skb); +#endif + /* + * Only ARP/IP is currently supported + */ + + if (fddi->hdr.llc_snap.ethertype != __constant_htons(ETH_P_IP)) { - printk("fddi_rebuild_header: Don't know how to resolve type %04X addresses?\n", (unsigned int)htons(fddi->hdr.llc_snap.ethertype)); + printk("%s: Don't know how to resolve type %02X addresses.\n", + skb->dev->name, htons(fddi->hdr.llc_snap.ethertype)); return(0); } /* Try to get ARP to resolve the header and fill destination address */ - return arp_find(fddi->daddr, skb) ? 1 : 0; + return arp_find(fddi->daddr, skb); } /* @@ -127,12 +139,12 @@ unsigned short fddi_type_trans(struct sk_buff *skb, struct device *dev) * to start of packet data. Assume 802.2 SNAP frames for now. */ - skb->mac.raw = skb->data; /* point to frame control (FC) */ + skb->mac.raw = skb->data; /* point to frame control (FC) */ if(fddi->hdr.llc_8022_1.dsap==0xe0) { skb_pull(skb, FDDI_K_8022_HLEN-3); - type=htons(ETH_P_802_2); + type = __constant_htons(ETH_P_802_2); } else { @@ -159,5 +171,4 @@ unsigned short fddi_type_trans(struct sk_buff *skb, struct device *dev) /* Assume 802.2 SNAP frames, for now */ return(type); - } diff --git a/net/802/llc_macinit.c b/net/802/llc_macinit.c index c72be3d4d..198230c36 100644 --- a/net/802/llc_macinit.c +++ b/net/802/llc_macinit.c @@ -36,15 +36,14 @@ /* * All incoming frames pass thru mac_data_indicate(). - * Here an llc structure is associated with an skb depending on the source - * MAC address in the pdu. + * On entry the llc structure related to the frame is passed as parameter. * The received sk_buffs with pdus other than I_CMD and I_RSP * are freed by mac_data_indicate() after processing, * the I pdu buffers are freed by the cl2llc client when it no longer needs * the skb. */ -int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb, struct device *dev, struct packet_type *pt) +int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb) { int ll; /* logical length == 802.3 length field */ unsigned char p_flag; @@ -142,7 +141,7 @@ int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb, struct device *dev, st if(lp->llc_callbacks) { - lp->llc_event(lp); + if ( lp->llc_event != NULL ) lp->llc_event(lp); lp->llc_callbacks=0; } return 0; @@ -173,8 +172,7 @@ int register_cl2llc_client(llcptr lp, const char *device, void (*event)(llcptr), lp->timer_interval[BUSY_TIMER] = HZ*2; lp->local_sap = ssap; lp->llc_event = event; - lp->remote_mac_len = lp->dev->addr_len; - memcpy(lp->remote_mac, rmac, lp->remote_mac_len); + memcpy(lp->remote_mac, rmac, sizeof(lp->remote_mac)); lp->state = 0; lp->llc_mode = MODE_ADM; lp->remote_sap = dsap; @@ -199,7 +197,8 @@ EXPORT_SYMBOL(llc_data_request); EXPORT_SYMBOL(llc_unit_data_request); EXPORT_SYMBOL(llc_test_request); EXPORT_SYMBOL(llc_xid_request); - +EXPORT_SYMBOL(llc_mac_data_indicate); +EXPORT_SYMBOL(llc_cancel_timers); #define ALL_TYPES_8022 0 diff --git a/net/802/llc_sendpdu.c b/net/802/llc_sendpdu.c index 436ddb9c7..5aeaecfbe 100644 --- a/net/802/llc_sendpdu.c +++ b/net/802/llc_sendpdu.c @@ -162,7 +162,6 @@ void llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data) lp->dev->hard_header(skb, lp->dev, ETH_P_802_3, lp->remote_mac, NULL, fl); skb->arp = 1; - skb->priority=SOPRI_NORMAL; skb->dev=lp->dev; dev_queue_xmit(skb); } @@ -220,7 +219,6 @@ void llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb) if(tmp!=NULL) { tmp->dev=lp->dev; - tmp->priority=SOPRI_NORMAL; dev_queue_xmit(tmp); } } @@ -288,7 +286,6 @@ int llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p) { tmp->arp = 1; tmp->dev = lp->dev; - tmp->priority = SOPRI_NORMAL; dev_queue_xmit(skb); } resend_count++; diff --git a/net/Config.in b/net/Config.in index f5a06935a..b57dc9e3d 100644 --- a/net/Config.in +++ b/net/Config.in @@ -26,9 +26,6 @@ comment ' ' tristate 'The IPX protocol' CONFIG_IPX if [ "$CONFIG_IPX" != "n" ]; then bool 'Full internal IPX network' CONFIG_IPX_INTERN - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'IPX Type 20 Routing' CONFIG_IPX_PPROP_ROUTING - fi fi tristate 'Appletalk DDP' CONFIG_ATALK tristate 'Amateur Radio AX.25 Level 2' CONFIG_AX25 diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 2cb6f3888..c02f0d5cb 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -157,7 +157,6 @@ static void aarp_send_query(struct aarp_entry *a) * Send it. */ - skb->priority = SOPRI_NORMAL; dev_queue_xmit(skb); /* @@ -219,7 +218,6 @@ static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_ad /* * Send it. */ - skb->priority = SOPRI_NORMAL; dev_queue_xmit(skb); } @@ -279,7 +277,6 @@ void aarp_send_probe(struct device *dev, struct at_addr *us) /* * Send it. */ - skb->priority = SOPRI_NORMAL; dev_queue_xmit(skb); } @@ -433,10 +430,13 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo struct aarp_entry *a; unsigned long flags; + skb->nh.raw=skb->data; + /* * Check for localtalk first */ + if(dev->type==ARPHRD_LOCALTLK) { struct at_addr *at=atalk_find_dev_addr(dev); @@ -472,9 +472,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo skb->data[1]=at->s_node; skb->data[2]=ft; - if(skb->sk==NULL) - skb->priority = SOPRI_NORMAL; - else + if(skb->sk) skb->priority = skb->sk->priority; skb->dev = dev; dev_queue_xmit(skb); @@ -487,9 +485,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo if(dev->type==ARPHRD_PPP) { skb->protocol = htons(ETH_P_PPPTALK); - if(skb->sk==NULL) - skb->priority = SOPRI_NORMAL; - else + if(skb->sk) skb->priority = skb->sk->priority; skb->dev = dev; dev_queue_xmit(skb); @@ -519,9 +515,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo if(sa->s_node==ATADDR_BCAST) { ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast); - if(skb->sk==NULL) - skb->priority = SOPRI_NORMAL; - else + if(skb->sk) skb->priority = skb->sk->priority; dev_queue_xmit(skb); restore_flags(flags); @@ -536,9 +530,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo a->expires_at=jiffies+sysctl_aarp_expiry_time*10; ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr); - if(skb->sk==NULL) - skb->priority = SOPRI_NORMAL; - else + if(skb->sk) skb->priority = skb->sk->priority; dev_queue_xmit(skb); restore_flags(flags); @@ -644,9 +636,7 @@ static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int ha { a->expires_at=jiffies+sysctl_aarp_expiry_time*10; ddp_dl->datalink_header(ddp_dl,skb,a->hwaddr); - if(skb->sk==NULL) - skb->priority = SOPRI_NORMAL; - else + if(skb->sk) skb->priority = skb->sk->priority; dev_queue_xmit(skb); } @@ -828,11 +818,9 @@ __initfunc(void aarp_proto_init(void)) } -#ifdef MODULE /* * Remove the AARP entries associated with a device. - * Called from cleanup_module() in ddp.c. */ void aarp_device_down(struct device *dev) { @@ -847,6 +835,7 @@ void aarp_device_down(struct device *dev) return; } +#ifdef MODULE /* * General module cleanup. Called from cleanup_module() in ddp.c. */ diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 5f070e903..9574da96c 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -54,10 +54,11 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/if_ether.h> -#include <linux/route.h> -#include <linux/inet.h> #include <linux/notifier.h> #include <linux/netdevice.h> +/*#include <linux/inetdevice.h> -- coming soon */ +#include <linux/route.h> +#include <linux/inet.h> #include <linux/etherdevice.h> #include <linux/if_arp.h> #include <linux/skbuff.h> @@ -268,12 +269,12 @@ static void atif_drop_device(struct device *dev) *iface = tmp->next; kfree_s(tmp, sizeof(struct atalk_iface)); dev->atalk_ptr=NULL; + MOD_DEC_USE_COUNT; } else iface = &tmp->next; } - MOD_DEC_USE_COUNT; } static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa) @@ -301,49 +302,42 @@ static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *s } /* + * Probe a Phase 1 device or a device that requires its Net:Node to + * be set via an ioctl. + */ +void atif_send_probe_phase1(struct atalk_iface *iface) +{ + struct ifreq atreq; + struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; + + sa->sat_addr.s_node = iface->address.s_node; + sa->sat_addr.s_net = ntohs(iface->address.s_net); + + /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ + if(!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) + { + (void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR); + if((iface->address.s_net != htons(sa->sat_addr.s_net)) + || (iface->address.s_node != sa->sat_addr.s_node)) + iface->status |= ATIF_PROBE_FAIL; + + iface->address.s_net = htons(sa->sat_addr.s_net); + iface->address.s_node = sa->sat_addr.s_node; + } + + return; +} + +/* * Perform phase 2 AARP probing on our tentative address. */ static int atif_probe_device(struct atalk_iface *atif) { - int ct; int netrange=ntohs(atif->nets.nr_lastnet)-ntohs(atif->nets.nr_firstnet)+1; int probe_net=ntohs(atif->address.s_net); int probe_node=atif->address.s_node; - int netct; - int nodect; - - struct ifreq atreq; - struct sockaddr_at *sa; - int err; + int ct, netct, nodect; -/* - * THIS IS A HACK: Farallon cards want to do their own picking of - * addresses. This needs tidying up when someone does localtalk - * drivers - */ - - if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) - && atif->dev->do_ioctl) - { - /* fake up the request and pass it down */ - sa = (struct sockaddr_at*)&atreq.ifr_addr; - sa->sat_addr.s_node = probe_node; - sa->sat_addr.s_net = probe_net; - if(!(err=atif->dev->do_ioctl(atif->dev,&atreq,SIOCSIFADDR))) - { - (void)atif->dev->do_ioctl(atif->dev,&atreq,SIOCGIFADDR); - atif->address.s_net=htons(sa->sat_addr.s_net); - atif->address.s_node=sa->sat_addr.s_node; - return (0); - } - /* - * If it didn't like our faked request then fail: - * This should check against -ENOIOCTLCMD and fall - * through. That needs us to fix all the devices up - * properly. We can then also dump the localtalk test. - */ - return (err); - } /* * Offset the network we start probing with. */ @@ -378,17 +372,23 @@ static int atif_probe_device(struct atalk_iface *atif) /* * Probe a proposed address. */ - for(ct = 0; ct < AARP_RETRANSMIT_LIMIT; ct++) - { - aarp_send_probe(atif->dev, &atif->address); - /* - * Defer 1/10th - */ - current->timeout = jiffies + (HZ/10); - current->state = TASK_INTERRUPTIBLE; - schedule(); - if(atif->status & ATIF_PROBE_FAIL) - break; + + if(atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) + atif_send_probe_phase1(atif); + else + { + for(ct = 0; ct < AARP_RETRANSMIT_LIMIT; ct++) + { + aarp_send_probe(atif->dev, &atif->address); + /* + * Defer 1/10th + */ + current->timeout = jiffies + (HZ/10); + current->state = TASK_INTERRUPTIBLE; + schedule(); + if(atif->status & ATIF_PROBE_FAIL) + break; + } } if(!(atif->status & ATIF_PROBE_FAIL)) return (0); @@ -664,6 +664,16 @@ void atrtr_device_down(struct device *dev) } /* + * Actually down the interface. + */ +static inline void atalk_dev_down(struct device *dev) +{ + atrtr_device_down(dev); /* Remove all routes for the device */ + aarp_device_down(dev); /* Remove AARP entries for the device */ + atif_drop_device(dev); /* Remove the device */ +} + +/* * A device event has occurred. Watch for devices going down and * delete our use of them (iface and route). */ @@ -672,8 +682,7 @@ static int ddp_device_event(struct notifier_block *this, unsigned long event, vo if(event == NETDEV_DOWN) { /* Discard any use of this */ - atrtr_device_down((struct device *)ptr); - atif_drop_device((struct device *)ptr); + atalk_dev_down((struct device *) ptr); } return (NOTIFY_DONE); @@ -820,14 +829,12 @@ int atif_ioctl(int cmd, void *arg) break; case SIOCATALKDIFADDR: + case SIOCDIFADDR: if(!suser()) return (-EPERM); if(sa->sat_family != AF_APPLETALK) return (-EINVAL); - if(atif == NULL) - return (-EADDRNOTAVAIL); - atrtr_device_down(atif->dev); - atif_drop_device(atif->dev); + atalk_dev_down(dev); break; } @@ -1431,6 +1438,7 @@ static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type skb_pull(skb, 13); skb->dev = dev; skb->h.raw = skb->data; + skb->nh.raw = skb->data; /* printk("passing up ipddp, 0x%02x better be 45\n",skb->data[0]); * printk("tot_len %d, skb->len %d\n", @@ -1821,6 +1829,7 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCSIFADDR: case SIOCGIFBRDADDR: case SIOCATALKDIFADDR: + case SIOCDIFADDR: return (atif_ioctl(cmd,(void *)arg)); /* @@ -1834,10 +1843,12 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCGIFMTU: case SIOCGIFCONF: case SIOCADDMULTI: - case SIOCDELMULTI: + case SIOCDELMULTI: case SIOCGIFCOUNT: - case SIOGIFINDEX: - case SIOGIFNAME: +#if 0 /* Also coming in the IP merge */ + case SIOCGIFINDEX: +#endif + case SIOCGIFNAME: return ((dev_ioctl(cmd,(void *) arg))); case SIOCSIFMETRIC: @@ -1984,18 +1995,6 @@ int init_module(void) } /* - * Actually down the interface. - */ -static void atalk_iface_down(struct atalk_iface *iface) -{ - atrtr_device_down(iface->dev); /* Remove all routes for the device */ - aarp_device_down(iface->dev); /* Remove AARP entries for the device */ - atif_drop_device(iface->dev); /* Remove the device */ - - return; -} - -/* * Note on MOD_{INC,DEC}_USE_COUNT: * * Use counts are incremented/decremented when @@ -2010,16 +2009,6 @@ static void atalk_iface_down(struct atalk_iface *iface) void cleanup_module(void) { - struct atalk_iface *ifaces = atalk_iface_list, *tmp; - - while(ifaces != NULL) - { - tmp = ifaces->next; - ifaces->dev->atalk_ptr = NULL; - atalk_iface_down(ifaces); - ifaces = tmp; - } - #ifdef CONFIG_SYSCTL atalk_unregister_sysctl(); #endif /* CONFIG_SYSCTL */ diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index baa5bb40e..2fa92c4ad 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1174,7 +1174,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le /* A DM or timeout will go to closed, a UA will go to ABM */ while (sk->state == TCP_SYN_SENT) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } @@ -1227,7 +1227,7 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) return -EWOULDBLOCK; } interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } diff --git a/net/core/datagram.c b/net/core/datagram.c index 70c939dbd..cd6e95000 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -114,7 +114,7 @@ restart: /* handle signals */ error = -ERESTARTSYS; - if (current->signal & ~current->blocked) + if (signal_pending(current)) goto no_packet; /* User doesn't want to wait */ diff --git a/net/core/sock.c b/net/core/sock.c index 0d4109e20..65cee3b62 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -674,7 +674,7 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigne { sk->socket->flags &= ~SO_NOSPACE; interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) + if (signal_pending(current)) { sti(); *errcode = -ERESTARTSYS; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f789f398d..4bf4bf166 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -605,7 +605,7 @@ int inet_stream_connect(struct socket *sock, struct sockaddr * uaddr, cli(); while(sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return(-ERESTARTSYS); } @@ -670,7 +670,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) cli(); while (sk2->state == TCP_SYN_RECV) { interruptible_sleep_on(sk2->sleep); - if (current->signal & ~current->blocked) + if (signal_pending(current)) goto do_interrupted; } sti(); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 71bdea02e..5edcb4a9c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -14,6 +14,7 @@ * Alan Cox : Split from ip.c , see ip_input.c for history. * David S. Miller : Begin massive cleanup... * Andi Kleen : Add sysctls. + * xxxx : Overlapfrag bug. */ #include <linux/types.h> @@ -339,7 +340,7 @@ static struct sk_buff *ip_glue(struct ipq *qp) /* Copy the data portions of all fragments into the new buffer. */ fp = qp->fragments; while(fp) { - if(count+fp->len > skb->len) { + if (fp->len < 0 || count+fp->len > skb->len) { NETDEBUG(printk(KERN_ERR "Invalid fragment list: " "Fragment over size.\n")); ip_free(qp); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2c28ab611..b62035e3b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -724,7 +724,7 @@ static void wait_for_tcp_memory(struct sock * sk) sk->socket->flags &= ~SO_NOSPACE; add_wait_queue(sk->sleep, &wait); for (;;) { - if (current->signal & ~current->blocked) + if (signal_pending(current)) break; current->state = TASK_INTERRUPTIBLE; if (tcp_memory_free(sk)) @@ -792,7 +792,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) if (flags&MSG_DONTWAIT) return -EAGAIN; - if (current->signal & ~current->blocked) + if (signal_pending(current)) return -ERESTARTSYS; wait_for_tcp_connect(sk); @@ -915,7 +915,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) return -EAGAIN; } - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { if (copied) return copied; return -ERESTARTSYS; @@ -1155,7 +1155,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, * handling. FIXME: Need to check this doesnt impact 1003.1g * and move it down to the bottom of the loop */ - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { if (copied) break; copied = -ERESTARTSYS; @@ -1473,7 +1473,7 @@ void tcp_close(struct sock *sk, unsigned long timeout) current->timeout = timeout; while(closing(sk) && current->timeout) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) + if (signal_pending(current)) break; } current->timeout=0; @@ -1518,7 +1518,7 @@ static struct open_request * wait_for_connect(struct sock * sk, req = tcp_find_established(&(sk->tp_pinfo.af_tcp), pprev); if (req) break; - if (current->signal & ~current->blocked) + if (signal_pending(current)) break; } remove_wait_queue(sk->sleep, &wait); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index bf660cf0b..13d9528e6 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -221,7 +221,7 @@ static void ipx_destroy_socket(struct sock *sk) * IPX interface is defined by a physical device and a frame type. */ -static ipx_route * ipxrtr_lookup(unsigned long); +static ipx_route * ipxrtr_lookup(__u32); static void ipxitf_clear_primary_net(void) { @@ -242,11 +242,11 @@ static ipx_interface *ipxitf_find_using_phys(struct device *dev, unsigned short return i; } -static ipx_interface *ipxitf_find_using_net(unsigned long net) +static ipx_interface *ipxitf_find_using_net(__u32 net) { ipx_interface *i; - if (net == 0L) + if (!net) return ipx_primary_net; for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next) @@ -699,7 +699,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) return 0; } -static int ipxrtr_add_route(unsigned long, ipx_interface *, unsigned char *); +static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); static int ipxitf_add_local_route(ipx_interface *intrfc) { @@ -726,9 +726,9 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } /* See if we should update our network number */ - if ((intrfc->if_netnum == 0L) && - (ipx->ipx_source.net == ipx->ipx_dest.net) && - (ipx->ipx_source.net != 0L)) + if ( !intrfc->if_netnum && /* net number of intrfc not known yet (== 0) */ + (ipx->ipx_source.net == ipx->ipx_dest.net) && /* intra-net packet */ + ipx->ipx_source.net) /* source net number of packet != 0 */ { /* NB: NetWare servers lie about their hop count so we * dropped the test based on it. This is the best way @@ -742,7 +742,7 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) else { printk(KERN_WARNING "IPX: Network number collision %lx\n %s %s and %s %s\n", - htonl(ipx->ipx_source.net), + (long unsigned int) htonl(ipx->ipx_source.net), ipx_device_name(i), ipx_frame_name(i->if_dlink_type), ipx_device_name(intrfc), @@ -750,18 +750,17 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } } -#ifdef CONFIG_IPX_PPROP_ROUTING if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 && skb->pkt_type == PACKET_HOST ) { int i; ipx_interface *ifcs; struct sk_buff *skb2; - long *l; + __u32 *l; char *c; c = (char *) skb->data; c += sizeof( struct ipxhdr ); - l = (long *) c; + l = (__u32 *) c; i = 0; /* @@ -780,7 +779,7 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) for ( ifcs = ipx_interfaces; ifcs != NULL ; ifcs = ifcs->if_next) { /* That aren't in the list */ - l = (long *) c; + l = (__u32 *) c; for( i = 0 ; i <= ipx->ipx_tctrl ; i++ ) if( ifcs->if_netnum == *l++ ) break; @@ -802,11 +801,10 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } } -#endif - if (ipx->ipx_dest.net == 0L) + if (!ipx->ipx_dest.net) ipx->ipx_dest.net = intrfc->if_netnum; - if (ipx->ipx_source.net == 0L) + if (!ipx->ipx_source.net) ipx->ipx_source.net = intrfc->if_netnum; if (intrfc->if_netnum != ipx->ipx_dest.net) @@ -873,7 +871,7 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) return -EEXIST; /* Must have a valid network number */ - if (idef->ipx_network == 0L) + if (!idef->ipx_network) return -EADDRNOTAVAIL; if (ipxitf_find_using_net(idef->ipx_network) != NULL) return -EADDRINUSE; @@ -927,7 +925,7 @@ static int ipxitf_create(ipx_interface_definition *idef) if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL)) return -EEXIST; - if ((idef->ipx_network != 0L) && + if (idef->ipx_network && (ipxitf_find_using_net(idef->ipx_network) != NULL)) return -EADDRINUSE; @@ -1001,7 +999,7 @@ static int ipxitf_create(ipx_interface_definition *idef) } /* If the network number is known, add a route */ - if (intrfc->if_netnum == 0L) + if (!intrfc->if_netnum) return 0; return ipxitf_add_local_route(intrfc); @@ -1075,7 +1073,7 @@ static ipx_interface *ipxitf_auto_create(struct device *dev, if (intrfc!=NULL) { intrfc->if_dev=dev; - intrfc->if_netnum=0L; + intrfc->if_netnum=0; intrfc->if_dlink_type = dlink_type; intrfc->if_dlink = datalink; intrfc->if_sklist = NULL; @@ -1178,7 +1176,7 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) * * \*******************************************************************************************************************/ -static ipx_route *ipxrtr_lookup(unsigned long net) +static ipx_route *ipxrtr_lookup(__u32 net) { ipx_route *r; @@ -1188,7 +1186,7 @@ static ipx_route *ipxrtr_lookup(unsigned long net) return r; } -static int ipxrtr_add_route(unsigned long network, ipx_interface *intrfc, unsigned char *node) +static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char *node) { ipx_route *rt; @@ -1340,7 +1338,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru int err; /* Find the appropriate interface on which to send packet */ - if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) + if (!usipx->sipx_network && (ipx_primary_net != NULL)) { usipx->sipx_network = ipx_primary_net->if_netnum; intrfc = ipx_primary_net; @@ -1519,7 +1517,7 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", "Node_Address", "Primary", "Device", "Frame_Type"); for (i = ipx_interfaces; i != NULL; i = i->if_next) { - len += sprintf(buffer+len, "%08lX ", ntohl(i->if_netnum)); + len += sprintf(buffer+len, "%08lX ", (long unsigned int)ntohl(i->if_netnum)); len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); @@ -1572,7 +1570,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, #ifdef CONFIG_IPX_INTERN len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - htonl(s->protinfo.af_ipx.intrfc->if_netnum), + (long unsigned int) htonl(s->protinfo.af_ipx.intrfc->if_netnum), s->protinfo.af_ipx.node[0], s->protinfo.af_ipx.node[1], s->protinfo.af_ipx.node[2], @@ -1590,7 +1588,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, } else { len += sprintf (buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - htonl(s->protinfo.af_ipx.dest_addr.net), + (long unsigned int) htonl(s->protinfo.af_ipx.dest_addr.net), s->protinfo.af_ipx.dest_addr.node[0], s->protinfo.af_ipx.dest_addr.node[1], s->protinfo.af_ipx.dest_addr.node[2], @@ -1639,10 +1637,10 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, "Network", "Router_Net", "Router_Node"); for (rt = ipx_routes; rt != NULL; rt = rt->ir_next) { - len += sprintf (buffer+len,"%08lX ", ntohl(rt->ir_net)); + len += sprintf (buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); if (rt->ir_routed) { len += sprintf (buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", - ntohl(rt->ir_intrfc->if_netnum), + (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); @@ -1906,7 +1904,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, int ret; uaddr.sipx_port = 0; - uaddr.sipx_network = 0L; + uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); @@ -1966,7 +1964,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, #endif } else { - sipx.sipx_network = 0L; + sipx.sipx_network = 0; memset(sipx.sipx_node, '\0', IPX_NODE_LEN); } sipx.sipx_port = sk->protinfo.af_ipx.port; @@ -2022,8 +2020,8 @@ void dump_data(char *str,unsigned char *d, int len) void dump_addr(char *str,ipx_address *p) { - printk(KERN_DEBUG"%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n", - str,ntohl(p->net),p->node[0],p->node[1],p->node[2], + printk(KERN_DEBUG"%s: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", + str,(long unsigned int)ntohl(p->net),p->node[0],p->node[1],p->node[2], p->node[3],p->node[4],p->node[5],ntohs(p->sock)); } diff --git a/net/netlink.c b/net/netlink.c index 9bf31a126..d2128c180 100644 --- a/net/netlink.c +++ b/net/netlink.c @@ -81,11 +81,11 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait) * Write a message to the kernel side of a communication link */ -static long netlink_write(struct inode * inode, struct file * file, - const char * buf, unsigned long count) +static ssize_t netlink_write(struct file * file, const char * buf, + size_t count,loff_t *ppos) { int err; - unsigned int minor = MINOR(inode->i_rdev); + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); struct sk_buff *skb; skb=alloc_skb(count, GFP_KERNEL); err = copy_from_user(skb_put(skb,count),buf, count); @@ -96,11 +96,11 @@ static long netlink_write(struct inode * inode, struct file * file, * Read a message from the kernel side of the communication link */ -static long netlink_read(struct inode * inode, struct file * file, char * buf, - unsigned long count) +static ssize_t netlink_read(struct file * file, char * buf, + size_t count,loff_t *ppos) { int err; - unsigned int minor = MINOR(inode->i_rdev); + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); struct sk_buff *skb; cli(); while((skb=skb_dequeue(&skb_queue_rd[minor]))==NULL) @@ -111,7 +111,7 @@ static long netlink_read(struct inode * inode, struct file * file, char * buf, return -EAGAIN; } interruptible_sleep_on(&read_space_wait[minor]); - if(current->signal & ~current->blocked) + if(signal_pending(current)) { sti(); return -ERESTARTSYS; diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 2d6b82593..8b51f7120 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -699,7 +699,7 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, */ while (sk->state == TCP_SYN_SENT) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } @@ -750,7 +750,7 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags) return -EWOULDBLOCK; } interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } diff --git a/net/netsyms.c b/net/netsyms.c index 9ab63c530..089d6ebc1 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -319,7 +319,6 @@ EXPORT_SYMBOL(skb_copy); EXPORT_SYMBOL(dev_alloc_skb); EXPORT_SYMBOL(netif_rx); EXPORT_SYMBOL(dev_tint); -EXPORT_SYMBOL(irq2dev_map); EXPORT_SYMBOL(dev_add_pack); EXPORT_SYMBOL(dev_remove_pack); EXPORT_SYMBOL(dev_get); diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 6d22f3704..69b77a9f2 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -787,7 +787,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le */ while (sk->state == TCP_SYN_SENT) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } @@ -838,7 +838,7 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags) return -EWOULDBLOCK; } interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } diff --git a/net/socket.c b/net/socket.c index 3405677cd..ee19a84f2 100644 --- a/net/socket.c +++ b/net/socket.c @@ -97,10 +97,10 @@ static long long sock_lseek(struct file *file, long long offset, int whence); -static long sock_read(struct inode *inode, struct file *file, - char *buf, unsigned long size); -static long sock_write(struct inode *inode, struct file *file, - const char *buf, unsigned long size); +static ssize_t sock_read(struct file *file, char *buf, + size_t size, loff_t *ppos); +static ssize_t sock_write(struct file *file, const char *buf, + size_t size, loff_t *ppos); static int sock_close(struct inode *inode, struct file *file); static unsigned int sock_poll(struct file *file, poll_table *wait); @@ -362,18 +362,20 @@ static long long sock_lseek(struct file *file,long long offset, int whence) * area ubuf...ubuf+size-1 is writable before asking the protocol. */ -static long sock_read(struct inode *inode, struct file *file, - char *ubuf, unsigned long size) +static ssize_t sock_read(struct file *file, char *ubuf, + size_t size, loff_t *ppos) { struct socket *sock; struct iovec iov; struct msghdr msg; - sock = socki_lookup(inode); - + if (ppos != &file->f_pos) + return -ESPIPE; if (size==0) /* Match SYS5 behaviour */ return 0; + sock = socki_lookup(file->f_dentry->d_inode); + msg.msg_name=NULL; msg.msg_namelen=0; msg.msg_iov=&iov; @@ -389,22 +391,24 @@ static long sock_read(struct inode *inode, struct file *file, /* - * Write data to a socket. We verify that the user area ubuf..ubuf+size-1 is - * readable by the user process. + * Write data to a socket. We verify that the user area ubuf..ubuf+size-1 + * is readable by the user process. */ -static long sock_write(struct inode *inode, struct file *file, - const char *ubuf, unsigned long size) +static ssize_t sock_write(struct file *file, const char *ubuf, + size_t size, loff_t *ppos) { struct socket *sock; struct msghdr msg; struct iovec iov; - sock = socki_lookup(inode); - + if (ppos != &file->f_pos) + return -ESPIPE; if(size==0) /* Match SYS5 behaviour */ return 0; + sock = socki_lookup(file->f_dentry->d_inode); + msg.msg_name=NULL; msg.msg_namelen=0; msg.msg_iov=&iov; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 971163963..ec6f52e3f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -116,17 +116,23 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname, /* * Properly shut down an RPC client, terminating all outstanding - * requests. + * requests. Note that we must be certain that cl_oneshot and + * cl_dead are cleared, or else the client would be destroyed + * when the last task releases it. */ int rpc_shutdown_client(struct rpc_clnt *clnt) { dprintk("RPC: shutting down %s client for %s\n", - clnt->cl_protname, clnt->cl_server); + clnt->cl_protname, clnt->cl_server); while (clnt->cl_users) { - dprintk("sigmask %08lx\n", current->signal); - dprintk("users %d\n", clnt->cl_users); - clnt->cl_dead = 1; +#ifdef RPC_DEBUG + printk("rpc_shutdown_client: client %s, tasks=%d\n", + clnt->cl_protname, clnt->cl_users); +#endif + /* Don't let rpc_release_client destroy us */ + clnt->cl_oneshot = 0; + clnt->cl_dead = 0; rpc_killall_tasks(clnt); sleep_on(&destroy_wait); } @@ -142,7 +148,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) dprintk("RPC: destroying %s client for %s\n", clnt->cl_protname, clnt->cl_server); - rpcauth_destroy(clnt->cl_auth); + if (clnt->cl_auth) { + rpcauth_destroy(clnt->cl_auth); + clnt->cl_auth = NULL; + } if (clnt->cl_xprt) { xprt_destroy(clnt->cl_xprt); clnt->cl_xprt = NULL; @@ -159,12 +168,16 @@ rpc_release_client(struct rpc_clnt *clnt) { dprintk("RPC: rpc_release_client(%p, %d)\n", clnt, clnt->cl_users); - if (--(clnt->cl_users) == 0) { - wake_up(&destroy_wait); - if (clnt->cl_oneshot || clnt->cl_dead) - rpc_destroy_client(clnt); - } - dprintk("RPC: rpc_release_client done\n"); + if (clnt->cl_users) { + if (--(clnt->cl_users) > 0) + return; + } else + printk("rpc_release_client: %s client already free??\n", + clnt->cl_protname); + + wake_up(&destroy_wait); + if (clnt->cl_oneshot || clnt->cl_dead) + rpc_destroy_client(clnt); } /* @@ -202,10 +215,9 @@ rpc_do_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, if ((async = (flags & RPC_TASK_ASYNC)) != 0) { if (!func) func = rpc_default_callback; - if (!(task = rpc_new_task(clnt, func, flags))) { - current->blocked = oldmask; - return -ENOMEM; - } + status = -ENOMEM; + if (!(task = rpc_new_task(clnt, func, flags))) + goto out; task->tk_calldata = data; } else { rpc_init_task(task, clnt, NULL, flags); @@ -219,12 +231,13 @@ rpc_do_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, } else async = 0; + status = 0; if (!async) { status = task->tk_status; rpc_release_task(task); - } else - status = 0; + } +out: current->blocked = oldmask; return status; } @@ -312,21 +325,36 @@ call_reserveresult(struct rpc_task *task) { dprintk("RPC: %4d call_reserveresult (status %d)\n", task->tk_pid, task->tk_status); + /* + * After a call to xprt_reserve(), we must have either + * a request slot or else an error status. + */ + if ((task->tk_status >= 0 && !task->tk_rqstp) || + (task->tk_status < 0 && task->tk_rqstp)) + printk("call_reserveresult: status=%d, request=%p??\n", + task->tk_status, task->tk_rqstp); if (task->tk_status >= 0) { task->tk_action = call_allocate; + goto out; } else if (task->tk_status == -EAGAIN) { task->tk_timeout = task->tk_client->cl_timeout.to_resrvval; task->tk_status = 0; xprt_reserve(task); - return; + goto out; } else if (task->tk_status == -ETIMEDOUT) { + printk("RPC: task timed out\n"); task->tk_action = call_timeout; + goto out; } else { task->tk_action = NULL; } - if (!task->tk_rqstp) + if (!task->tk_rqstp) { + printk("RPC: task has no request, exit EIO\n"); rpc_exit(task, -EIO); + } +out: + return; } /* @@ -351,6 +379,7 @@ call_allocate(struct rpc_task *task) if ((task->tk_buffer = rpc_malloc(task, bufsiz)) != NULL) return; + printk("RPC: buffer allocation failed for task %p\n", task); if (1 || !signalled()) { xprt_release(task); @@ -401,6 +430,7 @@ call_encode(struct rpc_task *task) /* Encode header and provided arguments */ encode = rpcproc_encode(clnt, task->tk_proc); if (!(p = call_header(task))) { + printk("RPC: call_header failed, exit EIO\n"); rpc_exit(task, -EIO); } else if ((status = encode(req, p, task->tk_argp)) < 0) { @@ -735,6 +765,7 @@ garbage: task->tk_action = call_encode; return NULL; } + printk("RPC: garbage, exit EIO\n"); rpc_exit(task, -EIO); return NULL; } diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index 4a05efd9c..2bbe9d50a 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c @@ -54,15 +54,16 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt) } clnt->cl_binding = 1; - task->tk_status = 0; - if (!(pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot))) { - task->tk_status = -EACCES; + task->tk_status = -EACCES; /* why set this? returns -EIO below */ + if (!(pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot))) goto bailout; - } - if (!(child = rpc_new_child(pmap_clnt, task))) { - rpc_destroy_client(pmap_clnt); + task->tk_status = 0; + + /* + * Note: rpc_new_child will release client after a failure. + */ + if (!(child = rpc_new_child(pmap_clnt, task))) goto bailout; - } /* Setup the call info struct */ rpc_call_setup(child, PMAP_GETPORT, map, &clnt->cl_port, 0); diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index fb02640f9..8e2d5868c 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -56,7 +56,8 @@ static struct rpc_task * all_tasks = NULL; */ static struct wait_queue * rpciod_idle = NULL; static struct wait_queue * rpciod_killer = NULL; -static int rpciod_sema = 0; +static struct semaphore rpciod_sema = MUTEX; +static unsigned int rpciod_users = 0; static pid_t rpciod_pid = 0; static int rpc_inhibit = 0; @@ -575,19 +576,36 @@ rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, current->pid); } +/* + * Create a new task for the specified client. We have to + * clean up after an allocation failure, as the client may + * have specified "oneshot". + */ struct rpc_task * rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags) { struct rpc_task *task; - if (!(task = (struct rpc_task *) rpc_allocate(flags, sizeof(*task)))) - return NULL; + task = (struct rpc_task *) rpc_allocate(flags, sizeof(*task)); + if (!task) + goto cleanup; rpc_init_task(task, clnt, callback, flags); dprintk("RPC: %4d allocated task\n", task->tk_pid); task->tk_flags |= RPC_TASK_DYNAMIC; +out: return task; + +cleanup: + /* Check whether to release the client */ + if (clnt) { + printk("rpc_new_task: failed, users=%d, oneshot=%d\n", + clnt->cl_users, clnt->cl_oneshot); + clnt->cl_users++; /* pretend we were used ... */ + rpc_release_client(clnt); + } + goto out; } void @@ -662,6 +680,9 @@ rpc_child_exit(struct rpc_task *child) rpc_release_task(child); } +/* + * Note: rpc_new_task releases the client after a failure. + */ struct rpc_task * rpc_new_child(struct rpc_clnt *clnt, struct rpc_task *parent) { @@ -715,11 +736,15 @@ rpciod(void *ptr) unsigned long oldflags; int rounds = 0; + MOD_INC_USE_COUNT; lock_kernel(); + /* + * Let our maker know we're running ... + */ rpciod_pid = current->pid; + wake_up(&rpciod_idle); - MOD_INC_USE_COUNT; - /* exit_files(current); */ + exit_files(current); exit_mm(current); current->blocked |= ~_S(SIGKILL); current->session = 1; @@ -727,25 +752,28 @@ rpciod(void *ptr) sprintf(current->comm, "rpciod"); dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid); - while (rpciod_sema) { + while (rpciod_users) { if (signalled()) { if (current->signal & _S(SIGKILL)) { rpciod_killall(); } else { printk("rpciod: ignoring signal (%d users)\n", - rpciod_sema); + rpciod_users); } current->signal &= current->blocked; } __rpc_schedule(); - if (++rounds >= 64) /* safeguard */ + if (++rounds >= 64) { /* safeguard */ schedule(); + rounds = 0; + } save_flags(oldflags); cli(); if (!schedq.task) { dprintk("RPC: rpciod back to sleep\n"); interruptible_sleep_on(&rpciod_idle); dprintk("RPC: switch to rpciod\n"); + rounds = 0; } restore_flags(oldflags); } @@ -780,26 +808,84 @@ rpciod_killall(void) } } -void +/* + * Start up the rpciod process if it's not already running. + */ +int rpciod_up(void) { - dprintk("rpciod_up pid %d sema %d\n", rpciod_pid, rpciod_sema); - if (!(rpciod_sema++) || !rpciod_pid) - kernel_thread(rpciod, &rpciod_killer, 0); + int error = 0; + + MOD_INC_USE_COUNT; + down(&rpciod_sema); + dprintk("rpciod_up: pid %d, users %d\n", rpciod_pid, rpciod_users); + rpciod_users++; + if (rpciod_pid) + goto out; + /* + * If there's no pid, we should be the first user. + */ + if (rpciod_users > 1) + printk("rpciod_up: no pid, %d users??\n", rpciod_users); + /* + * Create the rpciod thread and wait for it to start. + */ + error = kernel_thread(rpciod, &rpciod_killer, 0); + if (error < 0) { + printk("rpciod_up: create thread failed, error=%d\n", error); + goto out; + } + sleep_on(&rpciod_idle); + error = 0; +out: + up(&rpciod_sema); + MOD_DEC_USE_COUNT; + return error; } void rpciod_down(void) { - dprintk("rpciod_down pid %d sema %d\n", rpciod_pid, rpciod_sema); - if (--rpciod_sema > 0) - return; + unsigned long oldflags; + + MOD_INC_USE_COUNT; + down(&rpciod_sema); + dprintk("rpciod_down pid %d sema %d\n", rpciod_pid, rpciod_users); + if (rpciod_users) { + if (--rpciod_users) + goto out; + } else + printk("rpciod_down: pid=%d, no users??\n", rpciod_pid); + + if (!rpciod_pid) { + printk("rpciod_down: Nothing to do!\n"); + goto out; + } - rpciod_sema = 0; kill_proc(rpciod_pid, SIGKILL, 1); + /* + * Usually rpciod will exit very quickly, so we + * wait briefly before checking the process id. + */ + oldflags = current->signal; + current->signal = 0; + current->state = TASK_INTERRUPTIBLE; + current->timeout = jiffies + 1; + schedule(); + current->timeout = 0; + /* + * Display a message if we're going to wait longer. + */ while (rpciod_pid) { - if (signalled()) - return; + printk("rpciod_down: waiting for pid %d to exit\n", rpciod_pid); + if (signalled()) { + printk("rpciod_down: caught signal\n"); + break; + } interruptible_sleep_on(&rpciod_killer); } + current->signal = oldflags; +out: + up(&rpciod_sema); + MOD_DEC_USE_COUNT; } diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 55282366f..17376ef76 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -62,8 +62,12 @@ svc_destroy(struct svc_serv *serv) serv->sv_program->pg_name, serv->sv_nrthreads); - if (--(serv->sv_nrthreads) != 0) - return; + if (serv->sv_nrthreads) { + if (--(serv->sv_nrthreads) != 0) + return; + } else + printk("svc_destroy: no threads for serv=%p!\n", serv); + while ((svsk = serv->sv_allsocks) != NULL) svc_delete_socket(svsk); @@ -110,30 +114,31 @@ svc_release_buffer(struct svc_buf *bufp) int svc_create_thread(svc_thread_fn func, struct svc_serv *serv) { - struct svc_rqst *rqstp = 0; - int error; + struct svc_rqst *rqstp; + int error = -ENOMEM; - if (!(rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL))) - return -ENOMEM; + rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL); + if (!rqstp) + goto out; memset(rqstp, 0, sizeof(*rqstp)); if (!(rqstp->rq_argp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL)) || !(rqstp->rq_resp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL)) - || !svc_init_buffer(&rqstp->rq_defbuf, serv->sv_bufsz)) { - error = -ENOMEM; - goto failure; - } + || !svc_init_buffer(&rqstp->rq_defbuf, serv->sv_bufsz)) + goto out_thread; serv->sv_nrthreads++; - if ((error = kernel_thread((int (*)(void *)) func, rqstp, 0)) < 0) - goto failure; - rqstp->rq_server = serv; - return 0; + error = kernel_thread((int (*)(void *)) func, rqstp, 0); + if (error < 0) + goto out_thread; + error = 0; +out: + return error; -failure: +out_thread: svc_exit_thread(rqstp); - return error; + goto out; } /* @@ -152,7 +157,8 @@ svc_exit_thread(struct svc_rqst *rqstp) kfree(rqstp); /* Release the server */ - svc_destroy(serv); + if (serv) + svc_destroy(serv); } /* diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 87a5ed82e..fb6b81db2 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -743,14 +743,18 @@ again: if ((svsk = svc_sock_dequeue(serv)) != NULL) { enable_bh(NET_BH); rqstp->rq_sock = svsk; - svsk->sk_inuse++; + svsk->sk_inuse++; /* N.B. where is this decremented? */ } else { /* No data pending. Go to sleep */ rqstp->rq_sock = NULL; rqstp->rq_wait = NULL; svc_serv_enqueue(serv, rqstp); - current->state = TASK_UNINTERRUPTIBLE; + /* + * We have to be able to interrupt this wait + * to bring down the daemons ... + */ + current->state = TASK_INTERRUPTIBLE; add_wait_queue(&rqstp->rq_wait, &wait); enable_bh(NET_BH); schedule(); diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 0372500ee..15703111d 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1009,18 +1009,11 @@ xprt_reserve_status(struct rpc_task *task) } else if (!RPCXPRT_CONGESTED(xprt)) { /* OK: There's room for us. Grab a free slot and bump * congestion value */ - if (!(req = xprt->free)) { - /* printk("RPC: inconsistent free list!\n"); */ - rpc_debug = ~0; - dprintk("RPC: %4d inconsistent free list " - "(cong %ld cwnd %ld)\n", - task->tk_pid, xprt->cong, xprt->cwnd); - goto bummer; - } - if (req->rq_xid) { - printk("RPC: used rqst slot %p on free list!\n", req); - goto bummer; - } + req = xprt->free; + if (!req) + goto bad_list; + if (req->rq_xid) + goto bad_used; xprt->free = req->rq_next; xprt->cong += RPC_CWNDSCALE; task->tk_rqstp = req; @@ -1035,6 +1028,13 @@ xprt_reserve_status(struct rpc_task *task) return; +bad_list: + printk("RPC: %4d inconsistent free list (cong %ld cwnd %ld)\n", + task->tk_pid, xprt->cong, xprt->cwnd); + rpc_debug = ~0; + goto bummer; +bad_used: + printk("RPC: used rqst slot %p on free list!\n", req); bummer: task->tk_status = -EIO; xprt->free = NULL; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 8622da797..936d61220 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -705,7 +705,7 @@ static int unix_stream_connect1(struct socket *sock, struct msghdr *msg, if(nonblock) return -EINPROGRESS; interruptible_sleep_on(sk->sleep); - if(current->signal & ~current->blocked) + if(signal_pending(current)) return -ERESTARTSYS; } @@ -802,7 +802,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) if(flags&O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(sk->sleep); - if(current->signal & ~current->blocked) + if(signal_pending(current)) return -ERESTARTSYS; continue; } @@ -1219,7 +1219,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, int size if (noblock) return -EAGAIN; unix_data_wait(sk); - if (current->signal & ~current->blocked) + if (signal_pending(current)) return -ERESTARTSYS; down(&sk->protinfo.af_unix.readsem); continue; diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index a9a12f092..2970a82b9 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -653,7 +653,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len */ while (sk->state == TCP_SYN_SENT) { interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } @@ -704,7 +704,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) return -EWOULDBLOCK; } interruptible_sleep_on(sk->sleep); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { sti(); return -ERESTARTSYS; } |