Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (C) 1995, 1996  Gero Kuhlmann <gero@gkminix.han.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Allow an NFS filesystem to be mounted as root. The way this works is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *     (1) Use the IP autoconfig mechanism to set local IP addresses and routes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *     (2) Construct the device string and the options string using DHCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *         option 17 and/or kernel command line options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *     (3) When mount_root() sets up the root file system, pass these strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *         to the NFS client's regular mount interface via sys_mount().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *	Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *	Alan Cox	:	Removed get_address name clash with FPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *	Alan Cox	:	Reformatted a bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *	Gero Kuhlmann	:	Code cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *	Michael Rausch  :	Fixed recognition of an incoming RARP answer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *	Martin Mares	: (2.0)	Auto-configuration via BOOTP supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *	Martin Mares	:	Manual selection of interface & BOOTP/RARP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *	Martin Mares	:	Using network routes instead of host routes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *				allowing the default configuration to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *				for normal operation of the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *	Martin Mares	:	Randomized timer with exponential backoff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *				installed to minimize network congestion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *	Martin Mares	:	Code cleanup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *	Martin Mares	: (2.1)	BOOTP and RARP made configuration options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *	Martin Mares	:	Server hostname generation fixed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *	Gerd Knorr	:	Fixed wired inode handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *	Martin Mares	: (2.2)	"0.0.0.0" addresses from command line ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *	Martin Mares	:	RARP replies not tested for server address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *	Gero Kuhlmann	: (2.3) Some bug fixes and code cleanup again (please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *				send me your new patches _before_ bothering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *				Linus so that I don' always have to cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *				_afterwards_ - thanks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *	Gero Kuhlmann	:	Last changes of Martin Mares undone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *	Gero Kuhlmann	: 	RARP replies are tested for specified server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *				again. However, it's now possible to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *				different RARP and NFS servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	Gero Kuhlmann	:	"0.0.0.0" addresses from command line are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *				now mapped to INADDR_NONE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *	Gero Kuhlmann	:	Fixed a bug which prevented BOOTP path name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *				from being used (thanks to Leo Spiekman)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *	Andy Walker	:	Allow to specify the NFS server in nfs_root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *				without giving a path name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  *	Swen Thümmler	:	Allow to specify the NFS options in nfs_root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *				without giving a path name. Fix BOOTP request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *				for domainname (domainname is NIS domain, not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *				DNS domain!). Skip dummy devices for BOOTP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *	Jacek Zapala	:	Fixed a bug which prevented server-ip address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  *				from nfsroot parameter from being used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *	Olaf Kirch	:	Adapted to new NFS code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *	Jakub Jelinek	:	Free used code segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *	Marko Kohtala	:	Fixed some bugs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *	Martin Mares	:	Debug message cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *	Martin Mares	:	Changed to use the new generic IP layer autoconfig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *				code. BOOTP and RARP moved there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *	Martin Mares	:	Default path now contains host name instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *				host IP address (but host name defaults to IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *				address anyway).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *	Martin Mares	:	Use root_server_addr appropriately during setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *	Martin Mares	:	Rewrote parameter parsing, now hopefully giving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *				correct overriding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *	Trond Myklebust :	Add in preliminary support for NFSv3 and TCP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *				Fix bug in root_nfs_addr(). nfs_data.namlen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *				is NOT for the length of the hostname.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *	Hua Qin		:	Support for mounting root file system via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *				NFS over TCP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *	Fabian Frederick:	Option parser rebuilt (using parser lib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	Chuck Lever	:	Use super.c's text-based mount option parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	Chuck Lever	:	Add "nfsrootdebug".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #include <linux/nfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #include <linux/root_dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #include <net/ipconfig.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define NFSDBG_FACILITY NFSDBG_ROOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) /* Default path we try to mount. "%s" gets replaced by our IP address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define NFS_ROOT		"/tftpboot/%s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) /* Default NFSROOT mount options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #if defined(CONFIG_NFS_V2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define NFS_DEF_OPTIONS		"vers=2,tcp,rsize=4096,wsize=4096"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #elif defined(CONFIG_NFS_V3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define NFS_DEF_OPTIONS		"vers=3,tcp,rsize=4096,wsize=4096"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define NFS_DEF_OPTIONS		"vers=4,tcp,rsize=4096,wsize=4096"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /* Parameters passed from the kernel command line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static char nfs_root_parms[NFS_MAXPATHLEN + 1] __initdata = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Text-based mount options passed to super.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static char nfs_root_options[256] __initdata = NFS_DEF_OPTIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Address of NFS server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static __be32 servaddr __initdata = htonl(INADDR_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Name of directory to mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* server:export path string passed to super.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static char nfs_root_device[NFS_MAXPATHLEN + 1] __initdata = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #ifdef NFS_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * When the "nfsrootdebug" kernel command line option is specified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * enable debugging messages for NFSROOT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int __init nfs_root_debug(char *__unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	nfs_debug |= NFSDBG_ROOT | NFSDBG_MOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) __setup("nfsrootdebug", nfs_root_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *  Parse NFS server and directory information passed on the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  *  command line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *  nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *  If there is a "%s" token in the <root-dir> string, it is replaced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *  by the ASCII-representation of the client's IP address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int __init nfs_root_setup(char *line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	ROOT_DEV = Root_NFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		strlcpy(nfs_root_parms, line, sizeof(nfs_root_parms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		size_t n = strlen(line) + sizeof(NFS_ROOT) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		if (n >= sizeof(nfs_root_parms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			line[sizeof(nfs_root_parms) - sizeof(NFS_ROOT) - 2] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		sprintf(nfs_root_parms, NFS_ROOT, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	 * Extract the IP address of the NFS server containing our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 * root file system, if one was specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 * Note: root_nfs_parse_addr() removes the server-ip from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	 *	 nfs_root_parms, if it exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	root_server_addr = root_nfs_parse_addr(nfs_root_parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) __setup("nfsroot=", nfs_root_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int __init root_nfs_copy(char *dest, const char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				     const size_t destlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (strlcpy(dest, src, destlen) > destlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int __init root_nfs_cat(char *dest, const char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			       const size_t destlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	size_t len = strlen(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (len && dest[len - 1] != ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		if (strlcat(dest, ",", destlen) > destlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (strlcat(dest, src, destlen) > destlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * Parse out root export path and mount options from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * passed-in string @incoming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * Copy the export path into @exppath.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int __init root_nfs_parse_options(char *incoming, char *exppath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 					 const size_t exppathlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	 * Set the NFS remote path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	p = strsep(&incoming, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (*p != '\0' && strcmp(p, "default") != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		if (root_nfs_copy(exppath, p, exppathlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	 * @incoming now points to the rest of the string; if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	 * contains something, append it to our root options buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (incoming != NULL && *incoming != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		if (root_nfs_cat(nfs_root_options, incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 						sizeof(nfs_root_options)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  *  Decode the export directory path name and NFS options from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *  the kernel command line.  This has to be done late in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  *  use a dynamically acquired client IP address for the remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  *  root directory path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  *  Returns zero if successful; otherwise -1 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int __init root_nfs_data(char *cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	char mand_options[sizeof("nolock,addr=") + INET_ADDRSTRLEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	int len, retval = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	char *tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	const size_t tmplen = sizeof(nfs_export_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	tmp = kzalloc(tmplen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (tmp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	strcpy(tmp, NFS_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (root_server_path[0] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		dprintk("Root-NFS: DHCPv4 option 17: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			root_server_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		if (root_nfs_parse_options(root_server_path, tmp, tmplen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			goto out_optionstoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (cmdline[0] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		dprintk("Root-NFS: nfsroot=%s\n", cmdline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (root_nfs_parse_options(cmdline, tmp, tmplen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			goto out_optionstoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * Append mandatory options for nfsroot so they override
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 * what has come before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	snprintf(mand_options, sizeof(mand_options), "nolock,addr=%pI4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			&servaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (root_nfs_cat(nfs_root_options, mand_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 						sizeof(nfs_root_options)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		goto out_optionstoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * Set up nfs_root_device.  For NFS mounts, this looks like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 *	server:/path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 * At this point, utsname()->nodename contains our local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	 * IP address or hostname, set by ipconfig.  If "%s" exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	 * in tmp, substitute the nodename, then shovel the whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	 * mess into nfs_root_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	len = snprintf(nfs_export_path, sizeof(nfs_export_path),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				tmp, utsname()->nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (len >= (int)sizeof(nfs_export_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		goto out_devnametoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	len = snprintf(nfs_root_device, sizeof(nfs_root_device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				"%pI4:%s", &servaddr, nfs_export_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (len >= (int)sizeof(nfs_root_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		goto out_devnametoolong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	kfree(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) out_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	printk(KERN_ERR "Root-NFS: could not allocate memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) out_optionstoolong:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	printk(KERN_ERR "Root-NFS: mount options string too long\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) out_devnametoolong:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	printk(KERN_ERR "Root-NFS: root device name too long.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * nfs_root_data - Return prepared 'data' for NFSROOT mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * @root_device: OUT: address of string containing NFSROOT device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * @root_data: OUT: address of string containing NFSROOT mount options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * Returns zero and sets @root_device and @root_data if successful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * otherwise -1 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int __init nfs_root_data(char **root_device, char **root_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	servaddr = root_server_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (servaddr == htonl(INADDR_NONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		printk(KERN_ERR "Root-NFS: no NFS server address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (root_nfs_data(nfs_root_parms) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	*root_device = nfs_root_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	*root_data = nfs_root_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }