summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /net
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'net')
-rw-r--r--net/802/Makefile2
-rw-r--r--net/802/cl2llc.c2
-rw-r--r--net/802/cl2llc.pre2
-rw-r--r--net/802/fddi.c33
-rw-r--r--net/802/llc_macinit.c13
-rw-r--r--net/802/llc_sendpdu.c3
-rw-r--r--net/Config.in3
-rw-r--r--net/appletalk/aarp.c29
-rw-r--r--net/appletalk/ddp.c149
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/core/datagram.c2
-rw-r--r--net/core/sock.c2
-rw-r--r--net/ipv4/af_inet.c4
-rw-r--r--net/ipv4/ip_fragment.c3
-rw-r--r--net/ipv4/tcp.c12
-rw-r--r--net/ipx/af_ipx.c60
-rw-r--r--net/netlink.c14
-rw-r--r--net/netrom/af_netrom.c4
-rw-r--r--net/netsyms.c1
-rw-r--r--net/rose/af_rose.c4
-rw-r--r--net/socket.c32
-rw-r--r--net/sunrpc/clnt.c71
-rw-r--r--net/sunrpc/pmap_clnt.c15
-rw-r--r--net/sunrpc/sched.c122
-rw-r--r--net/sunrpc/svc.c40
-rw-r--r--net/sunrpc/svcsock.c8
-rw-r--r--net/sunrpc/xprt.c24
-rw-r--r--net/unix/af_unix.c6
-rw-r--r--net/x25/af_x25.c4
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;
}