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

Next file: linux/fs/super.c
Previous file: linux/fs/filesystems.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.41/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
@@ -1,10 +1,10 @@
 /*
- *  linux/fs/nfs/nfsroot.c -- version 2.3
+ *  $Id: nfsroot.c,v 1.36 1997/05/27 15:57:47 mj Exp $
  *
  *  Copyright (C) 1995, 1996  Gero Kuhlmann <gero@gkminix.han.de>
  *
  *  For parts of this file:
- *  Copyright (C) 1996  Martin Mares <mj@k332.feld.cvut.cz>
+ *  Copyright (C) 1996, 1997  Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  *
  *  Allow an NFS filesystem to be mounted as root. The way this works is:
  *     (1) Determine the local IP address via RARP or BOOTP or from the
@@ -54,6 +54,9 @@
  *	Jacek Zapala	:	Fixed a bug which prevented server-ip address
  *				from nfsroot parameter from being used.
  *	Olaf Kirch	:	Adapted to new NFS code.
+ *	Jakub Jelinek	:	Free used code segment.
+ *	Marko Kohtala	:	Fixed some bugs.
+ *	Martin Mares	:	Debug message cleanup
  *
  */
 
@@ -71,6 +74,7 @@
 #include <linux/fs.h>
 #include <linux/random.h>
 #include <linux/fcntl.h>
+#include <linux/init.h>
 
 #include <asm/param.h>
 #include <linux/utsname.h>
@@ -120,28 +124,28 @@
 	struct open_dev *next;
 };
 
-static struct open_dev *open_base = NULL;
+static struct open_dev *open_base __initdata = NULL;
 
 
 /* IP configuration */
-static struct device *root_dev = NULL;	/* Device selected for booting */
-static char user_dev_name[IFNAMSIZ];	/* Name of user-selected boot device */
-static __u32 myaddr;			/* My IP address */
-static __u32 servaddr;			/* Server IP address */
-static __u32 gateway;			/* Gateway IP address */
-static __u32 netmask;			/* Netmask for local subnet */
+static struct device *root_dev __initdata = NULL;	/* Device selected for booting */
+static char user_dev_name[IFNAMSIZ] __initdata = { 0, };/* Name of user-selected boot device */
+static __u32 myaddr __initdata = 0;			/* My IP address */
+static __u32 servaddr __initdata = 0;			/* Server IP address */
+static __u32 gateway __initdata = 0;			/* Gateway IP address */
+static __u32 netmask __initdata = 0;			/* Netmask for local subnet */
 
 
 /* BOOTP/RARP variables */
-static int bootp_flag;			/* User said: Use BOOTP! */
-static int rarp_flag;			/* User said: Use RARP! */
-static int bootp_dev_count = 0;		/* Number of devices allowing BOOTP */
-static int rarp_dev_count = 0;		/* Number of devices allowing RARP */
-static __u32 rarp_serv;			/* IP address of RARP server */
+static int bootp_flag __initdata = 0;		/* User said: Use BOOTP! */
+static int rarp_flag __initdata = 0;		/* User said: Use RARP! */
+static int bootp_dev_count __initdata = 0;	/* Number of devices allowing BOOTP */
+static int rarp_dev_count __initdata = 0;	/* Number of devices allowing RARP */
+static __u32 rarp_serv __initdata = 0;		/* IP address of RARP server */
 
 #if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
-#define CONFIG_RNFS_DYNAMIC		/* Enable dynamic IP config */
-static volatile int pkt_arrived;	/* BOOTP/RARP packet detected */
+#define CONFIG_RNFS_DYNAMIC			/* Enable dynamic IP config */
+static volatile int pkt_arrived __initdata = 0;	/* BOOTP/RARP packet detected */
 
 #define ARRIVED_BOOTP	1
 #define ARRIVED_RARP	2
@@ -149,10 +153,10 @@
 
 
 /* NFS-related data */
-static struct nfs_mount_data nfs_data;		/* NFS mount info */
-static char	nfs_path[NFS_MAXPATHLEN];	/* Name of directory to mount */
-static int	nfs_port;			/* Port to connect to for NFS */
-static int	mount_port;			/* Mount daemon port number */
+static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
+static char	nfs_path[NFS_MAXPATHLEN] __initdata = { 0, };/* Name of directory to mount */
+static int	nfs_port __initdata = 0;		/* Port to connect to for NFS */
+static int	mount_port __initdata = 0;		/* Mount daemon port number */
 
 
 /* Yes, we use sys_socket, but there's no include file for it */
@@ -170,7 +174,7 @@
  * Setup and initialize all network devices. If there is a user-preferred
  * interface, ignore all other interfaces.
  */
-static int root_dev_open(void)
+__initfunc(static int root_dev_open(void))
 {
 	struct open_dev *openp, **last;
 	struct device *dev;
@@ -221,8 +225,8 @@
 	sin->sin_port = port;
 }
 
-static int
-root_dev_chg_route(int op, struct device *dev, __u32 dest, __u32 mask, __u32 gw)
+__initfunc(static int
+root_dev_chg_route(int op, struct device *dev, __u32 dest, __u32 mask, __u32 gw))
 {
 	struct rtentry	route;
 	unsigned long	oldfs;
@@ -250,26 +254,28 @@
 	err = ip_rt_ioctl(op, &route);
 	set_fs(oldfs);
 
+#ifdef NFSROOT_DEBUG
 	/* in_ntoa in ipv4/utils.c uses a single static buffer, so
 	 * must make multiple printk calls, one for each in_ntoa
 	 * invocation...
 	 */
-	printk(KERN_NOTICE "%s route ", (op == SIOCADDRT ? "addr" : "del"));
+	printk(KERN_NOTICE "%s route ", (op == SIOCADDRT ? "add" : "del"));
 	printk("%s ", in_ntoa(dest));
 	printk("%s ", in_ntoa(mask));
 	printk("%s: res %d\n", in_ntoa(gw), err);
+#endif
 
 	return err;
 }
 
-static int
-root_dev_add_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway)
+__initfunc(static int
+root_dev_add_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway))
 {
 	return root_dev_chg_route(SIOCADDRT, dev, dest, mask, gateway);
 }
 
-static int
-root_dev_del_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway)
+__initfunc(static int
+root_dev_del_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway))
 {
 	return root_dev_chg_route(SIOCDELRT, dev, dest, mask, gateway);
 }
@@ -278,7 +284,7 @@
  *  Restore the state of all devices. However, keep the root device open
  *  for the upcoming mount.
  */
-static void root_dev_close(void)
+__initfunc(static void root_dev_close(void))
 {
 	struct open_dev *openp;
 	struct open_dev *nextp;
@@ -318,7 +324,7 @@
 			  struct packet_type *pt);
 
 
-static struct packet_type rarp_packet_type = {
+static struct packet_type rarp_packet_type __initdata = {
 	0,			/* Should be: __constant_htons(ETH_P_RARP)
 				 * - but this _doesn't_ come out constant! */
 	NULL,			/* Listen to all devices */
@@ -331,7 +337,7 @@
 /*
  *  Register the packet type for RARP
  */
-static void root_rarp_open(void)
+__initfunc(static void root_rarp_open(void))
 {
 	rarp_packet_type.type = htons(ETH_P_RARP);
 	dev_add_pack(&rarp_packet_type);
@@ -341,7 +347,7 @@
 /*
  *  Deregister the RARP packet type
  */
-static void root_rarp_close(void)
+__initfunc(static void root_rarp_close(void))
 {
 	rarp_packet_type.type = htons(ETH_P_RARP);
 	dev_remove_pack(&rarp_packet_type);
@@ -351,7 +357,8 @@
 /*
  *  Receive RARP packets.
  */
-static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+__initfunc(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);
@@ -428,7 +435,7 @@
 /*
  *  Send RARP request packet over all devices which allow RARP.
  */
-static void root_rarp_send(void)
+__initfunc(static void root_rarp_send(void))
 {
 	struct open_dev *openp;
 	struct device *dev;
@@ -455,10 +462,10 @@
 
 #ifdef CONFIG_RNFS_BOOTP
 
-static struct device *bootp_dev = NULL;	/* Device selected as best BOOTP target */
+static struct device *bootp_dev __initdata = NULL;	/* Device selected as best BOOTP target */
 
-static struct socket *bootp_xmit_sock;	/* BOOTP send socket */
-static struct socket *bootp_recv_sock;	/* BOOTP receive socket */
+static struct socket *bootp_xmit_sock __initdata = NULL;/* BOOTP send socket */
+static struct socket *bootp_recv_sock __initdata = NULL;/* BOOTP receive socket */
 
 struct bootp_pkt {		/* BOOTP packet format */
 	u8 op;			/* 1=request, 2=reply */
@@ -481,16 +488,16 @@
 #define BOOTP_REQUEST 1
 #define BOOTP_REPLY 2
 
-static struct bootp_pkt *xmit_bootp;	/* Packet being transmitted */
-static struct bootp_pkt *recv_bootp;	/* Packet being received */
+static struct bootp_pkt *xmit_bootp __initdata = NULL;	/* Packet being transmitted */
+static struct bootp_pkt *recv_bootp __initdata = NULL;	/* Packet being received */
 
-static int bootp_have_route = 0;	/* BOOTP route installed */
+static int bootp_have_route __initdata = 0;	/* BOOTP route installed */
 
 
 /*
  *  Free BOOTP packet buffers
  */
-static void root_free_bootp(void)
+__initfunc(static void root_free_bootp(void))
 {
 	if (xmit_bootp) {
 		kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
@@ -510,7 +517,7 @@
 {
 	if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
 	    !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
-		printk("BOOTP: Out of memory!");
+		printk(KERN_ERR "BOOTP: Out of memory!\n");
 		return -1;
 	}
 	return 0;
@@ -520,7 +527,7 @@
 /*
  *  Create default route for BOOTP sending
  */
-static int root_add_bootp_route(void)
+__initfunc(static int root_add_bootp_route(void))
 {
 	if (root_dev_add_route(bootp_dev, 0, 0, 0) < 0) {
 		printk(KERN_ERR "BOOTP: Failed to add route\n");
@@ -534,7 +541,7 @@
 /*
  *  Delete default route for BOOTP sending
  */
-static int root_del_bootp_route(void)
+__initfunc(static int root_del_bootp_route(void))
 {
 	if (bootp_have_route && root_dev_del_route(bootp_dev, 0, 0, 0) < 0) {
 		printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
@@ -548,7 +555,7 @@
 /*
  *  Open UDP socket.
  */
-static int root_open_udp_sock(struct socket **sock)
+__initfunc(static int root_open_udp_sock(struct socket **sock))
 {
 	int	err;
 
@@ -561,12 +568,13 @@
 /*
  *  Connect UDP socket.
  */
-static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
+__initfunc(static int
+root_connect_udp_sock(struct socket *sock, u32 addr, u16 port))
 {
 	struct sockaddr_in sa;
 	int result;
 
-	set_sockaddr(&sa, htonl(addr), htonl(port));
+	set_sockaddr(&sa, htonl(addr), htons(port));
 	result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
 	if (result < 0) {
 		printk(KERN_ERR "BOOTP: connect() failed\n");
@@ -579,12 +587,13 @@
 /*
  *  Bind UDP socket.
  */
-static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
+__initfunc(static int
+root_bind_udp_sock(struct socket *sock, u32 addr, u16 port))
 {
 	struct sockaddr_in sa;
 	int result;
 
-	set_sockaddr(&sa, htonl(addr), htonl(port));
+	set_sockaddr(&sa, htonl(addr), htons(port));
 	result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
 	if (result < 0) {
 		printk(KERN_ERR "BOOTP: bind() failed\n");
@@ -645,7 +654,7 @@
 /*
  *  Initialize BOOTP extension fields in the request.
  */
-static void root_bootp_init_ext(u8 *e)
+__initfunc(static void root_bootp_init_ext(u8 *e))
 {
 	*e++ = 99;		/* RFC1048 Magic Cookie */
 	*e++ = 130;
@@ -673,7 +682,7 @@
 /*
  *  Deinitialize the BOOTP mechanism.
  */
-static void root_bootp_close(void)
+__initfunc(static void root_bootp_close(void))
 {
 	if (bootp_xmit_sock)
 		sock_release(bootp_xmit_sock);
@@ -687,7 +696,7 @@
 /*
  *  Initialize the BOOTP mechanism.
  */
-static int root_bootp_open(void)
+__initfunc(static int root_bootp_open(void))
 {
 	struct open_dev *openp;
 	struct device *dev, *best_dev;
@@ -767,7 +776,7 @@
 /*
  *  Send BOOTP request.
  */
-static int root_bootp_send(u32 jiffies)
+__initfunc(static int root_bootp_send(u32 jiffies))
 {
 	xmit_bootp->secs = htons(jiffies / HZ);
 	return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
@@ -777,7 +786,8 @@
 /*
  *  Copy BOOTP-supplied string if not already set.
  */
-static int root_bootp_string(char *dest, char *src, int len, int max)
+__initfunc(static int
+root_bootp_string(char *dest, char *src, int len, int max))
 {
 	if (*dest || !len)
 		return 0;
@@ -792,12 +802,12 @@
 /*
  *  Process BOOTP extension.
  */
-static void root_do_bootp_ext(u8 *ext)
+__initfunc(static void root_do_bootp_ext(u8 *ext))
 {
 #ifdef NFSROOT_BOOTP_DEBUG
 	u8 *c;
 
-	printk("BOOTP: Got extension %02x",*ext);
+	printk(KERN_DEBUG "BOOTP: Got extension %02x",*ext);
 	for(c=ext+2; c<ext+2+ext[1]; c++)
 		printk(" %02x", *c);
 	printk("\n");
@@ -828,7 +838,7 @@
 /*
  *  Receive BOOTP request.
  */
-static void root_bootp_recv(void)
+__initfunc(static void root_bootp_recv(void))
 {
 	int len;
 	u8 *ext, *end, *opt;
@@ -897,7 +907,7 @@
  *  Determine client and server IP numbers and appropriate device by using
  *  the RARP and BOOTP protocols.
  */
-static int root_auto_config(void)
+__initfunc(static int root_auto_config(void))
 {
 	int retries;
 	unsigned long timeout, jiff;
@@ -988,8 +998,10 @@
 #else
 			;
 #endif
-		if (pkt_arrived)
+		if (pkt_arrived) {
+			printk(" OK\n");
 			break;
+		}
 		if (! --retries) {
 			printk(" timed out!\n");
 			break;
@@ -1011,7 +1023,6 @@
 	if (!pkt_arrived)
 		return -1;
 
-	printk(" OK\n");
 	printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
 		(pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
 		in_ntoa(servaddr));
@@ -1022,7 +1033,7 @@
 #endif
 
 /* Get default netmask - used to be exported from net/ipv4 */
-static unsigned long
+static inline unsigned long
 ip_get_mask(unsigned long addr)
 {
 	if (!addr)
@@ -1050,7 +1061,7 @@
 static struct nfs_int_opts {
 	char *name;
 	int  *val;
-} root_int_opts[] = {
+} root_int_opts[] __initdata = {
 	{ "port",	&nfs_port },
 	{ "rsize",	&nfs_data.rsize },
 	{ "wsize",	&nfs_data.wsize },
@@ -1071,7 +1082,7 @@
 	char *name;
 	int  and_mask;
 	int  or_mask;
-} root_bool_opts[] = {
+} root_bool_opts[] __initdata = {
 	{ "soft",	~NFS_MOUNT_SOFT,	NFS_MOUNT_SOFT },
 	{ "hard",	~NFS_MOUNT_SOFT,	0 },
 	{ "intr",	~NFS_MOUNT_INTR,	NFS_MOUNT_INTR },
@@ -1090,7 +1101,7 @@
  *  Prepare the NFS data structure and parse any options. This tries to
  *  set as many values in the nfs_data structure as known right now.
  */
-static int root_nfs_name(char *name)
+__initfunc(static int root_nfs_name(char *name))
 {
 	char buf[NFS_MAXPATHLEN];
 	char *cp, *cq, *options, *val;
@@ -1120,6 +1131,7 @@
 	memset(&nfs_data, 0, sizeof(nfs_data));
 	strncpy(nfs_data.hostname, in_ntoa(servaddr),
 						sizeof(nfs_data.hostname)-1);
+	nfs_data.namlen = strlen(nfs_data.hostname);
 
 	/* Set the name of the directory to mount */
 	if (nfs_path[0] == '\0' || strncmp(name, "default", 7))
@@ -1141,7 +1153,7 @@
 
 	/* Set some default values */
 	nfs_port          = -1;
-	nfs_data.version  = NFS_MNT_VERSION;
+	nfs_data.version  = NFS_MOUNT_VERSION;
 	nfs_data.flags    = NFS_MOUNT_NONLM;	/* No lockd in nfs root yet */
 	nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 	nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
@@ -1183,8 +1195,8 @@
 /*
  *  Tell the user what's going on.
  */
-#ifdef NFSROOT_BOOTP
-static void root_nfs_print(void)
+#ifdef NFSROOT_DEBUG
+__initfunc(static void root_nfs_print(void))
 {
 #define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
 
@@ -1231,7 +1243,7 @@
  *			  one for BOOTP
  *	<bootp|rarp>	- use both protocols to determine my own address
  */
-static void root_nfs_addrs(char *addrs)
+__initfunc(static void root_nfs_addrs(char *addrs))
 {
 	char *cp, *ip, *dp;
 	int num = 0;
@@ -1314,7 +1326,7 @@
 /*
  *  Set the interface address and configure a route to the server.
  */
-static int root_nfs_setup(void)
+__initfunc(static int root_nfs_setup(void))
 {
 	/* Set the default system name in case none was previously found */
 	if (!system_utsname.nodename[0]) {
@@ -1372,7 +1384,7 @@
  *  Get the necessary IP addresses and prepare for mounting the required
  *  NFS filesystem.
  */
-int nfs_root_init(char *nfsname, char *nfsaddrs)
+__initfunc(int nfs_root_init(char *nfsname, char *nfsaddrs))
 {
 #ifdef NFSROOT_DEBUG
 	nfs_debug |= NFSDBG_ROOT;
@@ -1461,14 +1473,14 @@
 /*
  *  Query server portmapper for the port of a daemon program
  */
-static int root_nfs_getport(int program, int version)
+__initfunc(static int root_nfs_getport(int program, int version))
 {
 	struct sockaddr_in	sin;
 
-printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
-	program, version, in_ntoa(servaddr));
-	set_sockaddr(&sin, servaddr, 0);
-	return rpc_getport_external(&sin, program, version, IPPROTO_UDP);
+	printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
+		program, version, in_ntoa(servaddr));
+		set_sockaddr(&sin, servaddr, 0);
+		return rpc_getport_external(&sin, program, version, IPPROTO_UDP);
 }
 
 
@@ -1478,7 +1490,7 @@
  *  keep this code is that we may want to use fallback ports. But is there
  *  actually someone who does not run portmap?
  */
-static int root_nfs_ports(void)
+__initfunc(static int root_nfs_ports(void))
 {
 	int	port;
 
@@ -1488,7 +1500,7 @@
 					"number from server, using default\n");
 			port = NFS_PORT;
 		}
-		nfs_port = port;
+		nfs_port = htons(port);
 		dprintk("Root-NFS: Portmapper on server returned %d "
 			"as nfsd port\n", port);
 	}
@@ -1511,7 +1523,7 @@
  *  Get a file handle from the server for the directory which is to be
  *  mounted
  */
-static int root_nfs_get_handle(void)
+__initfunc(static int root_nfs_get_handle(void))
 {
 	struct sockaddr_in sin;
 	int		status;
@@ -1529,7 +1541,7 @@
 /*
  *  Now actually mount the given directory
  */
-static int root_nfs_do_mount(struct super_block *sb)
+__initfunc(static int root_nfs_do_mount(struct super_block *sb))
 {
 	/* Pass the server address to NFS */
 	set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port);
@@ -1545,7 +1557,7 @@
  *  Get the NFS port numbers and file handle, and then read the super-
  *  block for mounting.
  */
-int nfs_root_mount(struct super_block *sb)
+__initfunc(int nfs_root_mount(struct super_block *sb))
 {
 	if (root_nfs_ports() < 0)
 		return -1;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov