patch-1.3.44 linux/fs/nfs/nfsroot.c

Next file: linux/fs/pipe.c
Previous file: linux/fs/isofs/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.43/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
@@ -7,6 +7,14 @@
  *  is to first determine the local IP address via RARP. Then handle
  *  the RPC negotiation with the system which replied to the RARP. The
  *  actual mounting is done later, when init() is running.
+ *
+ * 	Changes:
+ *
+ *	Alan Cox	:	Removed get_address name clash with FPU.
+ *	Alan Cox	:	Reformatted a bit.
+ *
+ *	TODO:
+ *		Support bootp and dhcp as well as rarp.
  */
 
 
@@ -42,7 +50,6 @@
 #include <linux/nfs.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
-/* #include <netinet/in.h> */
 
 #define IPPORT_RESERVED 1024
 
@@ -99,41 +106,51 @@
  *  For receiving rarp packets a packet type has to be registered. Also
  *  initialize all devices for usage by RARP.
  */
+
 static int root_rarp_open(void)
 {
-  struct open_dev *openp;
-  struct device *dev;
-  unsigned short old_flags;
-  int num;
-
-  /* Register the packet type */
-  rarp_packet_type.type=htons(ETH_P_RARP);
-  dev_add_pack(&rarp_packet_type);
-
-  /* Open all devices which allow RARP */
-  for (dev = dev_base, num = 0; dev != NULL; dev = dev->next) {
-	if (dev->type < ARPHRD_SLIP &&
-	    dev->family == AF_INET &&
-	    !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_NOARP))) {
-		/* First up the interface */
-		old_flags = dev->flags;
-		dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
-		if (!(old_flags & IFF_UP) && dev_open(dev)) {
-			dev->flags = old_flags;
-			continue;
-		}
-		openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
+	struct open_dev *openp;
+	struct device *dev;
+	unsigned short old_flags;
+	int num;
+
+	/*
+	 *	Register the packet type 
+	 */
+	 
+	rarp_packet_type.type=htons(ETH_P_RARP);
+	dev_add_pack(&rarp_packet_type);
+
+	/*
+	 *	Open all devices which allow RARP 
+	 */
+	 
+	for (dev = dev_base, num = 0; dev != NULL; dev = dev->next) 
+	{
+		if (dev->type < ARPHRD_SLIP &&
+			dev->family == AF_INET &&
+			!(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_NOARP))) 
+		{
+			/* First up the interface */
+			old_flags = dev->flags;
+			dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
+			if (!(old_flags & IFF_UP) && dev_open(dev)) 
+			{
+				dev->flags = old_flags;
+				continue;
+			}
+			openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 						GFP_ATOMIC);
-		if (openp == NULL)
-			continue;
-		openp->dev = dev;
-		openp->old_flags = old_flags;
-		openp->next = open_base;
-		open_base = openp;
-		num++;
+			if (openp == NULL)
+				continue;
+			openp->dev = dev;
+			openp->old_flags = old_flags;
+			openp->next = open_base;
+			open_base = openp;
+			num++;
+		}
 	}
-  }
-  return num;
+	return num;
 }
 
 
@@ -142,159 +159,204 @@
  *  and restore the state of the device. However, keep the root device
  *  open for the upcoming mount.
  */
+
 static void root_rarp_close(void)
 {
-  struct open_dev *openp;
-  struct open_dev *nextp;
-
-  /* Deregister the packet type */
-  rarp_packet_type.type=htons(ETH_P_RARP);
-  dev_remove_pack(&rarp_packet_type);
+	struct open_dev *openp;
+	struct open_dev *nextp;
 
-  /* Deactivate all previously opened devices except that one which is
-   * able to connect to a suitable server
-   */
-  openp = open_base;
-  while (openp != NULL) {
-	nextp = openp->next;
-	openp->next = NULL;
-	if (openp->dev != root_dev) {
-		if (!(openp->old_flags & IFF_UP))
-			dev_close(openp->dev);
-		openp->dev->flags = openp->old_flags;
+	/*
+	 *	Deregister the packet type 
+	 */
+	 
+	rarp_packet_type.type=htons(ETH_P_RARP);
+	dev_remove_pack(&rarp_packet_type);
+
+	/*
+	 *	Deactivate all previously opened devices except that one which is
+	 *	able to connect to a suitable server
+	 */
+
+	openp = open_base;
+	while (openp != NULL) 
+	{
+		nextp = openp->next;
+		openp->next = NULL;
+		if (openp->dev != root_dev) 
+		{
+			if (!(openp->old_flags & IFF_UP))
+				dev_close(openp->dev);
+			openp->dev->flags = openp->old_flags;
+		}
+		kfree_s(openp, sizeof(struct open_dev));
+		openp = nextp;
 	}
-	kfree_s(openp, sizeof(struct open_dev));
-	openp = nextp;
-  }
 }
 
 
 /*
- * Receive RARP packets.
+ *	Receive RARP packets.
  */
+ 
 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 {
-  struct arphdr *rarp = (struct arphdr *)skb->h.raw;
-  unsigned char *rarp_ptr = (unsigned char *)(rarp+1);
-  unsigned long sip, tip;
-  unsigned char *sha, *tha;		/* s for "source", t for "target" */
+	struct arphdr *rarp = (struct arphdr *)skb->h.raw;
+	unsigned char *rarp_ptr = (unsigned char *)(rarp+1);
+	unsigned long sip, tip;
+	unsigned char *sha, *tha;		/* s for "source", t for "target" */
   
-  /* If this test doesn't pass, its not IP, or we should ignore it anyway */
-  if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
-	kfree_skb(skb, FREE_READ);
-	return 0;
-  }
+	/*
+	 *	If this test doesn't pass, its not IP, or we should ignore it anyway 
+	 */
+	 
+	if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) 
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
 
-  /* If it's not a RARP reply, delete it. */
-  if (rarp->ar_op != htons(ARPOP_RREPLY)) {
-	kfree_skb(skb, FREE_READ);
-	return 0;
-  }
+	/*
+	 *	If it's not a RARP reply, delete it. 
+	 */
+	 
+	if (rarp->ar_op != htons(ARPOP_RREPLY)) 
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
 
-  /* If it's not ethernet or AX25, delete it. */
-  if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) || 
+	/*
+	 *	If it's not ethernet or AX25, delete it. 
+	 */
+	 
+	if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) || 
 #ifdef CONFIG_AX25
-      (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
+		(rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 #endif
-       rarp->ar_pln != 4) {
-	kfree_skb(skb, FREE_READ);
-	return 0;
-  }
+		rarp->ar_pln != 4) 
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
   
-  /* Extract variable width fields */
-  sha = rarp_ptr;
-  rarp_ptr += dev->addr_len;
-  memcpy(&sip, rarp_ptr, 4);
-  rarp_ptr += 4;
-  tha = rarp_ptr;
-  rarp_ptr += dev->addr_len;
-  memcpy(&tip, rarp_ptr, 4);
-
-  /* Discard packets which are not meant for us. */
-  if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
-	kfree_skb(skb, FREE_READ);
-	return 0;
-  }
+	/*
+	 *	Extract variable width fields 
+	 */
+	 
+	sha = rarp_ptr;
+	rarp_ptr += dev->addr_len;
+	memcpy(&sip, rarp_ptr, 4);
+	rarp_ptr += 4;
+	tha = rarp_ptr;
+	rarp_ptr += dev->addr_len;
+	memcpy(&tip, rarp_ptr, 4);
+
+	/*
+	 *	Discard packets which are not meant for us. 
+	 */
+	 
+	if (memcmp(tha, dev->dev_addr, dev->addr_len)) 
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
 
-  /* The packet is what we were looking for. Setup the global variables. */
-  cli();
-  if (root_dev != NULL) {
+	/*
+	 *	The packet is what we were looking for. Setup the global variables. 
+	 */
+
+	cli();
+	if (root_dev != NULL) 
+	{
+		sti();
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
+	root_dev = dev;
 	sti();
-	kfree_skb(skb, FREE_READ);
-	return 0;
-  }
-  root_dev = dev;
-  sti();
 
-  myaddr.sin_family = dev->family;
-  myaddr.sin_addr.s_addr = tip;
-  server.sin_family = dev->family;
-  if (!server.sin_addr.s_addr)
-    server.sin_addr.s_addr = sip;
+	myaddr.sin_family = dev->family;
+	myaddr.sin_addr.s_addr = tip;
+	server.sin_family = dev->family;
+	if (!server.sin_addr.s_addr)
+		server.sin_addr.s_addr = sip;
 
-  kfree_skb(skb, FREE_READ);
-  return 0;
+	kfree_skb(skb, FREE_READ);
+	return 0;
 }
 
 
 /*
- * Send RARP request packet over all devices which allow RARP.
+ *	Send RARP request packet over all devices which allow RARP.
  */
+
 static void root_rarp_send(void)
 {
-  struct open_dev *openp;
-  struct device *dev;
+	struct open_dev *openp;
+	struct device *dev;
 
 #ifdef NFSROOT_DEBUG
-  printk(KERN_NOTICE "NFS: Sending RARP request...\n");
+	printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 #endif
 
-  for (openp = open_base; openp != NULL; openp = openp->next) {
-	dev = openp->dev;
-	arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
-						dev->dev_addr, dev->dev_addr);
-  }
+	for (openp = open_base; openp != NULL; openp = openp->next) 
+	{
+		dev = openp->dev;
+		arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
+			dev->dev_addr, dev->dev_addr);
+	}
 }
 
 
 /*
- * Determine client and server IP numbers and appropriate device by using
- * the RARP protocol.
+ *	Determine client and server IP numbers and appropriate device by using
+ *	the RARP protocol.
  */
+
 static int do_rarp(void)
 {
-  int retries = 0;
-  unsigned long timeout;
+	int retries = 0;
+	unsigned long timeout;
+
+	/* 
+	 *	Open all devices and setup RARP protocol 
+	 */
+	 
+	if (!root_rarp_open()) 
+	{
+		printk(KERN_ERR "NFS: No network device found to send RARP request to\n");
+		return -1;
+	}
+
+	/*
+	 *	Send RARP request and wait, until we get an answer. This loop seems
+	 *	to be a terrible waste of cpu time, but actually there is no process
+	 *	running at all, so we don't need to use any scheduler functions.
+	 *	[Actually we could now, but the nothing else running note still 
+	 *	 applies.. - AC]
+	 */
+
+	for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) 
+	{
+		root_rarp_send();
+		timeout = jiffies + (RARP_TIMEOUT * HZ);
+		while (jiffies < timeout && root_dev == NULL)
+			;;
+	}
+
+	if (root_dev == NULL) 
+	{
+		printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
+		return -1;
+	}
+
+	root_rarp_close();
 
-  /* Open all devices and setup RARP protocol */
-  if (!root_rarp_open()) {
-	printk(KERN_ERR "NFS: No network device found to send RARP request to\n");
-	return -1;
-  }
-
-  /* Send RARP request and wait, until we get an answer. This loop seems
-   * to be a terrible waste of cpu time, but actually there is no process
-   * running at all, so we don't need to use any scheduler functions.
-   */
-  for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) {
-	root_rarp_send();
-	timeout = jiffies + (RARP_TIMEOUT * HZ);
-	while (jiffies < timeout && root_dev == NULL)
-		;;
-  }
-
-  if (root_dev == NULL) {
-	printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
-	return -1;
-  }
-
-  root_rarp_close();
-
-  printk(KERN_NOTICE "NFS: ");
-  printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
-  printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
+	printk(KERN_NOTICE "NFS: ");
+	printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
+	printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 
-  return 0;
+	return 0;
 }
 
 
@@ -311,7 +373,10 @@
 			unsigned short mss, unsigned long window);
 
 
-/* The following integer options are recognized */
+/*
+ *	The following integer options are recognized
+ */
+ 
 static struct nfs_int_opts
 {
 	char *name;
@@ -329,7 +394,10 @@
 	{ NULL,		NULL }};
 
 
-/* And now the flag options */
+/*
+ *	And now the flag options 
+ */
+ 
 static struct nfs_bool_opts
 {
 	char *name;
@@ -346,125 +414,145 @@
 	{ "nocto",	~NFS_MOUNT_NOCTO,	NFS_MOUNT_NOCTO },
 	{ "ac",		~NFS_MOUNT_NOAC,	0 },
 	{ "noac",	~NFS_MOUNT_NOAC,	NFS_MOUNT_NOAC },
-	{ NULL,		0,			0 }};
+	{ NULL,		0,			0 }
+};
 
 
-static unsigned long get_address (char **str)
+static unsigned long nfs_get_address (char **str)
 {
-   unsigned long l;
-   unsigned int val;
-   int i;
+	unsigned long l;
+	unsigned int val;
+	int i;
    
-   l = 0;
-   for (i = 0; i < 4; i++) 
-     {
-	
-	l <<= 8;
-	if (**str != '\0')
-	  {
-	     
-	     val = 0;
-	     while (**str != '\0' && **str != '.' && **str != ':')
-	       {
-		  
-		  val *= 10;
-		  val += **str - '0';
-		  (*str)++;
-	       }
-	     
-	     l |= val;
-	     if (**str != '\0') 
-	       (*str)++;
-	  }
-	
-     }
-   
-   return(htonl(l));
+	l = 0;
+	for (i = 0; i < 4; i++) 
+	{
+		l <<= 8;
+		if (**str != '\0')
+		{
+	     		val = 0;
+	     		while (**str != '\0' && **str != '.' && **str != ':')
+	       		{
+		  		val *= 10;
+		  		val += **str - '0';
+				(*str)++;
+			}
+			l |= val;
+			if (**str != '\0') 
+				(*str)++;
+		}
+	}
+   	return(htonl(l));
 }
 
 /*
- * Prepare the NFS data structure and parse any options
+ *	Prepare the NFS data structure and parse any options
  */
+ 
 static int root_nfs_parse(char *name)
 {
-  char buf[NFS_MAXPATHLEN];
-  char *cp, *options, *val;
+	char buf[NFS_MAXPATHLEN];
+	char *cp, *options, *val;
+
+	/*
+	 *	Get the host ip number 
+	 */
+	 
+	if (*name >= '0' && *name <= '9')
+	{
+		server.sin_addr.s_addr = nfs_get_address (&name);
+	}
 
-  /* get the host ip number */
-  if (*name >= '0' && *name <= '9'){
-    server.sin_addr.s_addr = get_address (&name);
-  }
-  /* Setup the server hostname */
-  cp = in_ntoa(server.sin_addr.s_addr);
-  strncpy(nfs_data.hostname, cp, 255);
-  nfs_data.addr = server;
-
-  /* Set the name of the directory to mount */
-  cp = in_ntoa(myaddr.sin_addr.s_addr);
-  strncpy(buf, name, 255);
-  if ((options = strchr(buf, ',')))
-	*options++ = '\0';
-  if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
-	printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
-	return -1;
-  }
-  sprintf(nfs_path, buf, cp);
-
-  /* Set some default values */
-  nfs_port          = -1;
-  nfs_data.version  = NFS_MOUNT_VERSION;
-  nfs_data.flags    = 0;
-  nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
-  nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
-  nfs_data.timeo    = 7;
-  nfs_data.retrans  = 3;
-  nfs_data.acregmin = 3;
-  nfs_data.acregmax = 60;
-  nfs_data.acdirmin = 30;
-  nfs_data.acdirmax = 60;
-
-  /* Process any options */
-  if (options) {
-	cp = strtok(options, ",");
-	while (cp) {
-		if ((val = strchr(cp, '='))) {
-			struct nfs_int_opts *opts = root_int_opts;
-			*val++ = '\0';
-			while (opts->name && strcmp(opts->name, cp))
-				opts++;
-			if (opts->name)
-				*(opts->val) = (int) simple_strtoul(val, NULL, 10);
-		} else {
-			struct nfs_bool_opts *opts = root_bool_opts;
-			while (opts->name && strcmp(opts->name, cp))
-				opts++;
-			if (opts->name) {
-				nfs_data.flags &= opts->and_mask;
-				nfs_data.flags |= opts->or_mask;
+	/*
+	 *	Setup the server hostname 
+	 */
+	 
+	cp = in_ntoa(server.sin_addr.s_addr);
+	strncpy(nfs_data.hostname, cp, 255);
+	nfs_data.addr = server;
+
+	/*
+	 *	Set the name of the directory to mount 
+	 */
+	 
+	cp = in_ntoa(myaddr.sin_addr.s_addr);
+	strncpy(buf, name, 255);
+	if ((options = strchr(buf, ',')))
+		*options++ = '\0';
+	if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) 
+	{
+		printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
+		return -1;
+	}
+	sprintf(nfs_path, buf, cp);
+
+	/*
+	 *	Set some default values 
+	 */
+	 
+	nfs_port          = -1;
+	nfs_data.version  = NFS_MOUNT_VERSION;
+	nfs_data.flags    = 0;
+	nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
+	nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
+	nfs_data.timeo    = 7;
+	nfs_data.retrans  = 3;
+	nfs_data.acregmin = 3;
+	nfs_data.acregmax = 60;
+	nfs_data.acdirmin = 30;
+	nfs_data.acdirmax = 60;
+
+	/*
+	 *	Process any options
+	 */
+
+	if (options) 
+	{
+		cp = strtok(options, ",");
+		while (cp) 
+		{
+			if ((val = strchr(cp, '='))) 
+			{
+				struct nfs_int_opts *opts = root_int_opts;
+				*val++ = '\0';
+				while (opts->name && strcmp(opts->name, cp))
+					opts++;
+				if (opts->name)
+					*(opts->val) = (int) simple_strtoul(val, NULL, 10);
 			}
+			else
+			{
+				struct nfs_bool_opts *opts = root_bool_opts;
+				while (opts->name && strcmp(opts->name, cp))
+					opts++;
+				if (opts->name) 
+				{
+					nfs_data.flags &= opts->and_mask;
+					nfs_data.flags |= opts->or_mask;
+				}
+			}
+			cp = strtok(NULL, ",");
 		}
-		cp = strtok(NULL, ",");
 	}
-  }
-
-  return 0;
+	return 0;
 }
 
 
 /*
- * Tell the user what's going on.
+ *	Tell the user what's going on.
  */
+
 static void root_nfs_print(void)
 {
 #ifdef NFSROOT_DEBUG
-  printk(KERN_NOTICE "NFS: Mounting %s on server %s as root\n",
+	printk(KERN_NOTICE "NFS: Mounting %s on server %s as root\n",
 		nfs_path, nfs_data.hostname);
-  printk(KERN_NOTICE "NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
+	printk(KERN_NOTICE "NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
 		nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
-  printk(KERN_NOTICE "NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
+	printk(KERN_NOTICE "NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
 		nfs_data.acregmin, nfs_data.acregmax,
 		nfs_data.acdirmin, nfs_data.acdirmax);
-  printk(KERN_NOTICE "NFS:     port = %d, flags = %08x\n",
+	printk(KERN_NOTICE "NFS:     port = %d, flags = %08x\n",
 		nfs_port, nfs_data.flags);
 #endif
 }
@@ -475,53 +563,62 @@
  */
 static void root_nfs_setup(void)
 {
-  struct rtentry server_route;
-  struct sockaddr_in *sin;
+	struct rtentry server_route;
+	struct sockaddr_in *sin;
 
-  /* Setup the device correctly */
-  root_dev->family     = myaddr.sin_family;
-  root_dev->pa_addr    = myaddr.sin_addr.s_addr;
-  root_dev->pa_mask    = ip_get_mask(myaddr.sin_addr.s_addr);
-  root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
-  root_dev->pa_dstaddr = 0;
-
-  sin=(struct sockaddr_in *)&server_route.rt_dst;
-  *sin=server;
-  sin=(struct sockaddr_in *)&server_route.rt_genmask;
-  sin->sin_family=AF_INET;
-  sin->sin_addr.s_addr= root_dev->pa_mask;
-  server_route.rt_dev=NULL;
-  server_route.rt_flags=RTF_HOST|RTF_UP;
+	/* 
+	 *	Setup the device correctly
+	 */
+	 
+	root_dev->family     = myaddr.sin_family;
+	root_dev->pa_addr    = myaddr.sin_addr.s_addr;
+	root_dev->pa_mask    = ip_get_mask(myaddr.sin_addr.s_addr);
+	root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
+	root_dev->pa_dstaddr = 0;
+
+	sin=(struct sockaddr_in *)&server_route.rt_dst;
+	*sin=server;
+	sin=(struct sockaddr_in *)&server_route.rt_genmask;
+	sin->sin_family=AF_INET;
+	sin->sin_addr.s_addr= root_dev->pa_mask;
+	server_route.rt_dev=NULL;
+	server_route.rt_flags=RTF_HOST|RTF_UP;
   
-  /* Now add a route to the server */
-  if(ip_rt_new(&server_route)==-1)
-  	printk("Unable to add NFS server route.\n");
+	/*
+	 *	Now add a route to the server
+	 */
+ 
+	if(ip_rt_new(&server_route)==-1)
+	  	printk("Unable to add NFS server route.\n");
 }
 
 
 /*
- * Get the necessary IP addresses and prepare for mounting the required
- * NFS filesystem.
+ *	Get the necessary IP addresses and prepare for mounting the required
+ *	NFS filesystem.
  */
+
 int nfs_root_init(char *nfsname)
 {
-  /* Initialize network device and get local and server IP address */
-  if (do_rarp() < 0)
-	return -1;
-
-  /* Initialize the global variables necessary for NFS. The server
-   * directory is actually mounted after init() has been started.
-   */
-  if (root_nfs_parse(nfsname) < 0)
-	return -1;
-  root_nfs_print();
-  root_nfs_setup();
-  return 0;
+	/*
+	 *	Initialize network device and get local and server IP address 
+	 */
+
+	if (do_rarp() < 0)
+		return -1;
+
+	/*
+	 *	Initialize the global variables necessary for NFS. The server
+	 *	directory is actually mounted after init() has been started.
+	 */
+
+	if (root_nfs_parse(nfsname) < 0)
+		return -1;
+	root_nfs_print();
+	root_nfs_setup();
+	return 0;
 }
 
-
-
-
 /***************************************************************************
 
 		Routines to actually mount the root directory
@@ -537,313 +634,385 @@
 
 
 /*
- * Open a UDP socket.
+ *	Open a UDP socket.
  */
+
 static int root_nfs_open(void)
 {
-  struct file *filp;
-  unsigned long opt[] = { AF_INET, SOCK_DGRAM, IPPROTO_UDP };
+	struct file *filp;
+	unsigned long opt[] = { AF_INET, SOCK_DGRAM, IPPROTO_UDP };
 
-  /* Open the socket */
-  if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) {
-	printk(KERN_ERR "NFS: Cannot open UDP socket\n");
-	return -1;
-  }
-
-  /* Copy the file and inode data area so that we can remove the
-   * file lateron without killing the socket. After all this the
-   * closing routine just needs to remove the file pointer from
-   * the init-task descriptor.
-   */
-  filp = current->files->fd[nfs_data.fd];
-  memcpy(&nfs_file, filp, sizeof(struct file));
-  nfs_file.f_next = nfs_file.f_prev = NULL;
-  current->files->fd[nfs_data.fd] = &nfs_file;
-  filp->f_count = 0;		/* Free the file descriptor */
-
-  memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
-  nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
-  nfs_inode.i_next = nfs_inode.i_prev = NULL;
-  clear_inode(nfs_file.f_inode);
-  nfs_file.f_inode = &nfs_inode;
-  nfs_inode.u.socket_i.inode = &nfs_inode;
-  nfs_file.private_data = NULL;
-
-  return 0;
+	/*
+	 *	Open the socket 
+	 */
+
+	if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) 
+	{
+		printk(KERN_ERR "NFS: Cannot open UDP socket\n");
+		return -1;
+	}
+
+	/*	
+	 *	Copy the file and inode data area so that we can remove the
+	 *	file lateron without killing the socket. After all this the
+	 *	closing routine just needs to remove the file pointer from
+	 *	the init-task descriptor.
+	 */
+
+	filp = current->files->fd[nfs_data.fd];
+	memcpy(&nfs_file, filp, sizeof(struct file));
+	nfs_file.f_next = nfs_file.f_prev = NULL;
+	current->files->fd[nfs_data.fd] = &nfs_file;
+	filp->f_count = 0;		/* Free the file descriptor */
+
+	memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
+	nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
+	nfs_inode.i_next = nfs_inode.i_prev = NULL;
+	clear_inode(nfs_file.f_inode);
+	nfs_file.f_inode = &nfs_inode;
+	nfs_inode.u.socket_i.inode = &nfs_inode;
+	nfs_file.private_data = NULL;
+
+	return 0;
 }
 
 
 /*
- * Close the UDP file descriptor. The main part of preserving the socket
- * has already been done after opening it. Now we have to remove the
- * file descriptor from the init task.
+ *	Close the UDP file descriptor. The main part of preserving the socket
+ *	has already been done after opening it. Now we have to remove the
+ *	file descriptor from the init task.
  */
+
 static void root_nfs_close(int close_all)
 {
-  /* Remove the file from the list of open files */
-  current->files->fd[nfs_data.fd] = NULL;
-  if (current->files->count > 0)
-	current->files->count--;
-
-  /* Clear memory use by the RPC packet */
-  if (rpc_packet != NULL)
-	kfree_s(rpc_packet, nfs_data.wsize + 1024);
-
-  /* In case of an error we also have to close the socket again (sigh) */
-  if (close_all) {
-	nfs_inode.u.socket_i.inode = NULL;	/* The inode is already cleared */
-	if (nfs_file.f_op->release)
-		nfs_file.f_op->release(&nfs_inode, &nfs_file);
-  }
+	/*
+	 *	Remove the file from the list of open files 
+	 */
+
+	current->files->fd[nfs_data.fd] = NULL;
+	if (current->files->count > 0)
+		current->files->count--;
+
+	/*
+	 *	Clear memory use by the RPC packet 
+	 */
+	 
+	if (rpc_packet != NULL)
+		kfree_s(rpc_packet, nfs_data.wsize + 1024);
+
+	/*
+	 *	In case of an error we also have to close the socket again (sigh)
+	 */
+	 
+	if (close_all) 
+	{
+		nfs_inode.u.socket_i.inode = NULL;	/* The inode is already cleared */
+		if (nfs_file.f_op->release)
+			nfs_file.f_op->release(&nfs_inode, &nfs_file);
+	}
 }
 
 
 /*
- * Find a suitable listening port and bind to it
+ *	Find a suitable listening port and bind to it
  */
+
 static int root_nfs_bind(void)
 {
-  int res = -1;
-  short port = STARTPORT;
-  struct sockaddr_in *sin = &myaddr;
-  int i;
-
-  if (nfs_inode.u.socket_i.ops->bind) {
-	for (i = 0; i < NPORTS && res < 0; i++) {
-		sin->sin_port = htons(port++);
-		if (port > ENDPORT) {
-			port = STARTPORT;
+	int res = -1;
+	short port = STARTPORT;
+	struct sockaddr_in *sin = &myaddr;
+	int i;
+
+	if (nfs_inode.u.socket_i.ops->bind) 
+	{
+		for (i = 0; i < NPORTS && res < 0; i++) 
+		{
+			sin->sin_port = htons(port++);
+			if (port > ENDPORT) 
+			{
+				port = STARTPORT;
+			}
+			res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
+				(struct sockaddr *) sin, sizeof(struct sockaddr_in));
 		}
-		res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
-			(struct sockaddr *) sin, sizeof(struct sockaddr_in));
 	}
-  }
-  if (res < 0) {
-	printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
-	root_nfs_close(1);
-	return -1;
-  }
-
+	if (res < 0) 
+	{
+		printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
+		root_nfs_close(1);
+		return -1;
+	}
 #ifdef NFSROOT_DEBUG
-  printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
+	printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
 #endif
-  return 0;
+	return 0;
 }
 
 
 /*
- * Send an RPC request and wait for the answer
+ *	Send an RPC request and wait for the answer
  */
+
 static int *root_nfs_call(int *end)
 {
-  struct file *filp;
-  struct socket *sock;
-  int dummylen;
-  static struct nfs_server s =
-	{ &nfs_file, /* struct file * */
-	  0,         /* struct rsock * */
-	  {
-	     0, "",
-	  },         /* toaddr */
-          0,         /* lock */
-	  NULL,      /* wait queue */
-	  NFS_MOUNT_SOFT, /* flags */
-	  0, 0,           /* rsize, wsize */
-	  0,              /* timeo */
-	  0,              /* retrans */
-	  3*HZ, 60*HZ, 30*HZ, 60*HZ, "\0" };
+	struct file *filp;
+	struct socket *sock;
+	int dummylen;
+	static struct nfs_server s = {
+		&nfs_file, /* struct file * */
+		0,         /* struct rsock * */
+		{
+			0, "",
+		},         /* toaddr */
+		0,         /* lock */
+		NULL,      /* wait queue */
+		NFS_MOUNT_SOFT, /* flags - this seems a ___BAD___ default - AC */
+		0, 0,           /* rsize, wsize */
+		0,              /* timeo */
+		0,              /* retrans */
+		3*HZ, 60*HZ, 30*HZ, 60*HZ, "\0" 
+	};
 
-  filp = &nfs_file;
-  sock = &((filp->f_inode)->u.socket_i);
+	filp = &nfs_file;
+	sock = &((filp->f_inode)->u.socket_i);
     
-  /* extract the other end of the socket into server->toaddr */
-  sock->ops->getname(sock, &(s.toaddr), &dummylen, 1) ;
-  ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
-  ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
-  ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
+	/*
+	 *	extract the other end of the socket into server->toaddr 
+	 */
+	 
+	sock->ops->getname(sock, &(s.toaddr), &dummylen, 1) ;
+	((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
+	((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
+	((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
   
-  s.rsock = rpc_makesock(filp);
-  s.flags = nfs_data.flags;
-  s.rsize = nfs_data.rsize;
-  s.wsize = nfs_data.wsize;
-  s.timeo = nfs_data.timeo * HZ / 10;
-  s.retrans = nfs_data.retrans;
-  strcpy(s.hostname, nfs_data.hostname);
-
-  /* First connect the UDP socket to a server port, then send the packet
-   * out, and finally check wether the answer is OK.
-   */
-  if (nfs_inode.u.socket_i.ops->connect &&
-      nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
+	s.rsock	= rpc_makesock(filp);
+	s.flags = nfs_data.flags;
+	s.rsize = nfs_data.rsize;
+	s.wsize = nfs_data.wsize;
+	s.timeo = nfs_data.timeo * HZ / 10;
+	s.retrans = nfs_data.retrans;
+	strcpy(s.hostname, nfs_data.hostname);
+
+	/*
+	 *	First connect the UDP socket to a server port, then send the packet
+	 *	out, and finally check wether the answer is OK.
+	 */
+	 
+	if (nfs_inode.u.socket_i.ops->connect &&
+		nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 		(struct sockaddr *) &server, sizeof(struct sockaddr_in),
 		nfs_file.f_flags) < 0)
-	return NULL;
-  if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
-	return NULL;
-  return rpc_verify(rpc_packet);
+	{
+		return NULL;
+	}
+
+	if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
+		return NULL;
+	return rpc_verify(rpc_packet);
 }
 
 
 /*
- * Create an RPC packet header
+ *	Create an RPC packet header
  */
+ 
 static int *root_nfs_header(int proc, int program, int version)
 {
-  int groups[] = { 0, NOGROUP };
+	int groups[] = { 0, NOGROUP };
 
-  if (rpc_packet == NULL) {
-	if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
-		printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
-		return NULL;
+	if (rpc_packet == NULL) 
+	{
+		if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) 
+		{
+			printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
+			return NULL;
+		}
 	}
-  }
-  strcpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr));
-  return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
+	strcpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr));
+	return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 }
 
 
 /*
- * Query server portmapper for the port of a daemon program
+ *	Query server portmapper for the port of a daemon program
  */
+
 static int root_nfs_get_port(int program, int version)
 {
-  int *p;
+	int *p;
 
-  /* Prepare header for portmap request */
-  server.sin_port = htons(NFS_PMAP_PORT);
-  p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
-  if (!p)
-	return -1;
+	/*
+	 *	Prepare header for portmap request
+	 */
+	 
+	server.sin_port = htons(NFS_PMAP_PORT);
+	p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
+	if (!p)
+		return -1;
 
-  /* Set arguments for portmapper */
-  *p++ = htonl(program);
-  *p++ = htonl(version);
-  *p++ = htonl(IPPROTO_UDP);
-  *p++ = 0;
+	/*
+	 *	Set arguments for portmapper
+	 */
+	 
+	*p++ = htonl(program);
+	*p++ = htonl(version);
+	*p++ = htonl(IPPROTO_UDP);
+	*p++ = 0;
 
-  /* Send request to server portmapper */
-  if ((p = root_nfs_call(p)) == NULL)
-	return -1;
+	/*
+	 *	Send request to server portmapper
+	 */
+	 
+	if ((p = root_nfs_call(p)) == NULL)
+		return -1;
 
-  return ntohl(*p);
+	return ntohl(*p);
 }
 
 
 /*
- * Get portnumbers for mountd and nfsd from server
+ *	Get portnumbers for mountd and nfsd from server
  */
+ 
 static int root_nfs_ports(void)
 {
-  int port;
+	int port;
 
-  if (nfs_port < 0) {
-	if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
-		printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
-		port = NFS_NFS_PORT;
-	}
-	nfs_port = port;
+	if (nfs_port < 0) 
+	{
+		if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) 
+		{
+			printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
+			port = NFS_NFS_PORT;
+		}
+		nfs_port = port;
 #ifdef NFSROOT_DEBUG
-	printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
+		printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 #endif
-  }
+	}
 
-  if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
-	printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
-	port = NFS_MOUNT_PORT;
-  }
-  server.sin_port = htons(port);
+	if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) 
+	{
+		printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
+		port = NFS_MOUNT_PORT;
+	}
+	server.sin_port = htons(port);
 #ifdef NFSROOT_DEBUG
-  printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
+	printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 #endif
-
-  return 0;
+	return 0;
 }
 
 
 /*
- * Get a file handle from the server for the directory which is to be mounted
+ *	Get a file handle from the server for the directory which is to be mounted
  */
+ 
 static int root_nfs_get_handle(void)
 {
-  int len, status, *p;
+	int len, status, *p;
+
+	/*
+	 *	Prepare header for mountd request 
+	 */
+	 
+	p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
+	if (!p) 
+	{
+		root_nfs_close(1);
+		return -1;
+	}
 
-  /* Prepare header for mountd request */
-  p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
-  if (!p) {
-	root_nfs_close(1);
-	return -1;
-  }
-
-  /* Set arguments for mountd */
-  len = strlen(nfs_path);
-  *p++ = htonl(len);
-  memcpy(p, nfs_path, len);
-  len = (len + 3) >> 2;
-  p[len] = 0;
-  p += len;
-
-  /* Send request to server portmapper */
-  if ((p = root_nfs_call(p)) == NULL) {
-	root_nfs_close(1);
-	return -1;
-  }
-
-  status = ntohl(*p++);
-  if (status == 0) {
-	nfs_data.root = *((struct nfs_fh *) p);
-  } else {
-	printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
-							status, nfs_path);
-	root_nfs_close(1);
-	return -1;
-  }
+	/*
+	 *	Set arguments for mountd
+	 */
+
+	len = strlen(nfs_path);
+	*p++ = htonl(len);
+	memcpy(p, nfs_path, len);
+	len = (len + 3) >> 2;
+	p[len] = 0;
+	p += len;
+
+	/*
+	 *	Send request to server portmapper 
+	 */
+
+	if ((p = root_nfs_call(p)) == NULL)
+	{
+		root_nfs_close(1);
+		return -1;
+	}
 
-  return 0;
+	status = ntohl(*p++);
+	if (status == 0) 
+	{
+		nfs_data.root = *((struct nfs_fh *) p);
+	} 
+	else
+	{
+		printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
+			status, nfs_path);
+		root_nfs_close(1);
+		return -1;
+	}
+	return 0;
 }
 
 
 /*
- * Now actually mount the given directory
+ *	Now actually mount the given directory
  */
+
 static int root_nfs_do_mount(struct super_block *sb)
 {
-  /* First connect to the nfsd port on the server */
-  server.sin_port = htons(nfs_port);
-  nfs_data.addr = server;
-  if (nfs_inode.u.socket_i.ops->connect &&
-      nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
+	/*
+	 *	First connect to the nfsd port on the server 
+	 */
+
+	server.sin_port = htons(nfs_port);
+	nfs_data.addr = server;
+	if (nfs_inode.u.socket_i.ops->connect &&
+		nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 		(struct sockaddr *) &server, sizeof(struct sockaddr_in),
-		nfs_file.f_flags) < 0) {
-	root_nfs_close(1);
-	return -1;
-  }
+		nfs_file.f_flags) < 0) 
+	{
+		root_nfs_close(1);
+		return -1;
+	}
 
-  /* Now (finally ;-)) read the super block for mounting */
-  if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
-	root_nfs_close(1);
-	return -1;
-  }
+	/*
+	 *	Now (finally ;-)) read the super block for mounting
+	 */
+
+	if (nfs_read_super(sb, &nfs_data, 1) == NULL) 
+	{
+		root_nfs_close(1);
+		return -1;
+	}
 
-  return 0;
+	return 0;
 }
 
 
 /*
- * Get the NFS port numbers and file handle, and then read the super-
- * block for mounting.
+ *	Get the NFS port numbers and file handle, and then read the super-
+ *	block for mounting.
  */
+
 int nfs_root_mount(struct super_block *sb)
 {
-  if (root_nfs_open() < 0)
-	return -1;
-  if (root_nfs_bind() < 0)
-	return -1;
-  if (root_nfs_ports() < 0)
-	return -1;
-  if (root_nfs_get_handle() < 0)
-	return -1;
-  if (root_nfs_do_mount(sb) < 0)
-	return -1;
-  root_nfs_close(0);
-  return 0;
+	if (root_nfs_open() < 0)
+		return -1;
+	if (root_nfs_bind() < 0)
+		return -1;
+	if (root_nfs_ports() < 0)
+		return -1;
+	if (root_nfs_get_handle() < 0)
+		return -1;
+	if (root_nfs_do_mount(sb) < 0)
+		return -1;
+	root_nfs_close(0);
+	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this