diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2010-09-17 10:54:37 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-17 10:54:37 -0400 |
commit | 8d2321037896aa4868a67f45b2d6ed52b579a48a (patch) | |
tree | 9b7c7d75ce392539696dbe0992d8163dc0bf53a5 /fs/nfs/nfsroot.c | |
parent | 56463e50d1fc3f070492434cea6303b35ea000de (diff) |
NFS: Clean up nfsroot.c
Clean up: now that mount option parsing for nfsroot is handled
in fs/nfs/super.c, remove code in fs/nfs/nfsroot.c that is no
longer used. This includes code that constructs the legacy
nfs_mount_data structure, and code that does a MNT call to the
server.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfsroot.c')
-rw-r--r-- | fs/nfs/nfsroot.c | 419 |
1 files changed, 1 insertions, 418 deletions
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index cb4a6bdca871..8e7d623173a9 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -71,22 +71,12 @@ | |||
71 | 71 | ||
72 | #include <linux/types.h> | 72 | #include <linux/types.h> |
73 | #include <linux/string.h> | 73 | #include <linux/string.h> |
74 | #include <linux/kernel.h> | ||
75 | #include <linux/time.h> | ||
76 | #include <linux/fs.h> | ||
77 | #include <linux/init.h> | 74 | #include <linux/init.h> |
78 | #include <linux/sunrpc/clnt.h> | ||
79 | #include <linux/sunrpc/xprtsock.h> | ||
80 | #include <linux/nfs.h> | 75 | #include <linux/nfs.h> |
81 | #include <linux/nfs_fs.h> | 76 | #include <linux/nfs_fs.h> |
82 | #include <linux/nfs_mount.h> | ||
83 | #include <linux/in.h> | ||
84 | #include <linux/major.h> | ||
85 | #include <linux/utsname.h> | 77 | #include <linux/utsname.h> |
86 | #include <linux/inet.h> | ||
87 | #include <linux/root_dev.h> | 78 | #include <linux/root_dev.h> |
88 | #include <net/ipconfig.h> | 79 | #include <net/ipconfig.h> |
89 | #include <linux/parser.h> | ||
90 | 80 | ||
91 | #include "internal.h" | 81 | #include "internal.h" |
92 | 82 | ||
@@ -94,9 +84,6 @@ | |||
94 | #undef NFSROOT_DEBUG | 84 | #undef NFSROOT_DEBUG |
95 | #define NFSDBG_FACILITY NFSDBG_ROOT | 85 | #define NFSDBG_FACILITY NFSDBG_ROOT |
96 | 86 | ||
97 | /* Default port to use if server is not running a portmapper */ | ||
98 | #define NFS_MNT_PORT 627 | ||
99 | |||
100 | /* Default path we try to mount. "%s" gets replaced by our IP address */ | 87 | /* Default path we try to mount. "%s" gets replaced by our IP address */ |
101 | #define NFS_ROOT "/tftpboot/%s" | 88 | #define NFS_ROOT "/tftpboot/%s" |
102 | 89 | ||
@@ -107,7 +94,7 @@ static char nfs_root_parms[256] __initdata = ""; | |||
107 | static char nfs_root_options[256] __initdata = ""; | 94 | static char nfs_root_options[256] __initdata = ""; |
108 | 95 | ||
109 | /* Address of NFS server */ | 96 | /* Address of NFS server */ |
110 | static __be32 servaddr __initdata = 0; | 97 | static __be32 servaddr __initdata = htonl(INADDR_NONE); |
111 | 98 | ||
112 | /* Name of directory to mount */ | 99 | /* Name of directory to mount */ |
113 | static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = ""; | 100 | static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = ""; |
@@ -115,279 +102,6 @@ static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = ""; | |||
115 | /* server:export path string passed to super.c */ | 102 | /* server:export path string passed to super.c */ |
116 | static char nfs_root_device[NFS_MAXPATHLEN + 1] __initdata = ""; | 103 | static char nfs_root_device[NFS_MAXPATHLEN + 1] __initdata = ""; |
117 | 104 | ||
118 | /* NFS-related data */ | ||
119 | static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */ | ||
120 | static int nfs_port __initdata = 0; /* Port to connect to for NFS */ | ||
121 | static int mount_port __initdata = 0; /* Mount daemon port number */ | ||
122 | |||
123 | |||
124 | /*************************************************************************** | ||
125 | |||
126 | Parsing of options | ||
127 | |||
128 | ***************************************************************************/ | ||
129 | |||
130 | enum { | ||
131 | /* Options that take integer arguments */ | ||
132 | Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin, | ||
133 | Opt_acregmax, Opt_acdirmin, Opt_acdirmax, | ||
134 | /* Options that take no arguments */ | ||
135 | Opt_soft, Opt_hard, Opt_intr, | ||
136 | Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, | ||
137 | Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, | ||
138 | Opt_acl, Opt_noacl, | ||
139 | /* Error token */ | ||
140 | Opt_err | ||
141 | }; | ||
142 | |||
143 | static const match_table_t tokens __initconst = { | ||
144 | {Opt_port, "port=%u"}, | ||
145 | {Opt_rsize, "rsize=%u"}, | ||
146 | {Opt_wsize, "wsize=%u"}, | ||
147 | {Opt_timeo, "timeo=%u"}, | ||
148 | {Opt_retrans, "retrans=%u"}, | ||
149 | {Opt_acregmin, "acregmin=%u"}, | ||
150 | {Opt_acregmax, "acregmax=%u"}, | ||
151 | {Opt_acdirmin, "acdirmin=%u"}, | ||
152 | {Opt_acdirmax, "acdirmax=%u"}, | ||
153 | {Opt_soft, "soft"}, | ||
154 | {Opt_hard, "hard"}, | ||
155 | {Opt_intr, "intr"}, | ||
156 | {Opt_nointr, "nointr"}, | ||
157 | {Opt_posix, "posix"}, | ||
158 | {Opt_noposix, "noposix"}, | ||
159 | {Opt_cto, "cto"}, | ||
160 | {Opt_nocto, "nocto"}, | ||
161 | {Opt_ac, "ac"}, | ||
162 | {Opt_noac, "noac"}, | ||
163 | {Opt_lock, "lock"}, | ||
164 | {Opt_nolock, "nolock"}, | ||
165 | {Opt_v2, "nfsvers=2"}, | ||
166 | {Opt_v2, "v2"}, | ||
167 | {Opt_v3, "nfsvers=3"}, | ||
168 | {Opt_v3, "v3"}, | ||
169 | {Opt_udp, "proto=udp"}, | ||
170 | {Opt_udp, "udp"}, | ||
171 | {Opt_tcp, "proto=tcp"}, | ||
172 | {Opt_tcp, "tcp"}, | ||
173 | {Opt_acl, "acl"}, | ||
174 | {Opt_noacl, "noacl"}, | ||
175 | {Opt_err, NULL} | ||
176 | |||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * Parse option string. | ||
181 | */ | ||
182 | |||
183 | static int __init root_nfs_parse(char *name, char *buf) | ||
184 | { | ||
185 | |||
186 | char *p; | ||
187 | substring_t args[MAX_OPT_ARGS]; | ||
188 | int option; | ||
189 | |||
190 | if (!name) | ||
191 | return 1; | ||
192 | |||
193 | /* Set the NFS remote path */ | ||
194 | p = strsep(&name, ","); | ||
195 | if (p[0] != '\0' && strcmp(p, "default") != 0) | ||
196 | strlcpy(buf, p, NFS_MAXPATHLEN); | ||
197 | |||
198 | while ((p = strsep (&name, ",")) != NULL) { | ||
199 | int token; | ||
200 | if (!*p) | ||
201 | continue; | ||
202 | token = match_token(p, tokens, args); | ||
203 | |||
204 | /* %u tokens only. Beware if you add new tokens! */ | ||
205 | if (token < Opt_soft && match_int(&args[0], &option)) | ||
206 | return 0; | ||
207 | switch (token) { | ||
208 | case Opt_port: | ||
209 | nfs_port = option; | ||
210 | break; | ||
211 | case Opt_rsize: | ||
212 | nfs_data.rsize = option; | ||
213 | break; | ||
214 | case Opt_wsize: | ||
215 | nfs_data.wsize = option; | ||
216 | break; | ||
217 | case Opt_timeo: | ||
218 | nfs_data.timeo = option; | ||
219 | break; | ||
220 | case Opt_retrans: | ||
221 | nfs_data.retrans = option; | ||
222 | break; | ||
223 | case Opt_acregmin: | ||
224 | nfs_data.acregmin = option; | ||
225 | break; | ||
226 | case Opt_acregmax: | ||
227 | nfs_data.acregmax = option; | ||
228 | break; | ||
229 | case Opt_acdirmin: | ||
230 | nfs_data.acdirmin = option; | ||
231 | break; | ||
232 | case Opt_acdirmax: | ||
233 | nfs_data.acdirmax = option; | ||
234 | break; | ||
235 | case Opt_soft: | ||
236 | nfs_data.flags |= NFS_MOUNT_SOFT; | ||
237 | break; | ||
238 | case Opt_hard: | ||
239 | nfs_data.flags &= ~NFS_MOUNT_SOFT; | ||
240 | break; | ||
241 | case Opt_intr: | ||
242 | case Opt_nointr: | ||
243 | break; | ||
244 | case Opt_posix: | ||
245 | nfs_data.flags |= NFS_MOUNT_POSIX; | ||
246 | break; | ||
247 | case Opt_noposix: | ||
248 | nfs_data.flags &= ~NFS_MOUNT_POSIX; | ||
249 | break; | ||
250 | case Opt_cto: | ||
251 | nfs_data.flags &= ~NFS_MOUNT_NOCTO; | ||
252 | break; | ||
253 | case Opt_nocto: | ||
254 | nfs_data.flags |= NFS_MOUNT_NOCTO; | ||
255 | break; | ||
256 | case Opt_ac: | ||
257 | nfs_data.flags &= ~NFS_MOUNT_NOAC; | ||
258 | break; | ||
259 | case Opt_noac: | ||
260 | nfs_data.flags |= NFS_MOUNT_NOAC; | ||
261 | break; | ||
262 | case Opt_lock: | ||
263 | nfs_data.flags &= ~NFS_MOUNT_NONLM; | ||
264 | break; | ||
265 | case Opt_nolock: | ||
266 | nfs_data.flags |= NFS_MOUNT_NONLM; | ||
267 | break; | ||
268 | case Opt_v2: | ||
269 | nfs_data.flags &= ~NFS_MOUNT_VER3; | ||
270 | break; | ||
271 | case Opt_v3: | ||
272 | nfs_data.flags |= NFS_MOUNT_VER3; | ||
273 | break; | ||
274 | case Opt_udp: | ||
275 | nfs_data.flags &= ~NFS_MOUNT_TCP; | ||
276 | break; | ||
277 | case Opt_tcp: | ||
278 | nfs_data.flags |= NFS_MOUNT_TCP; | ||
279 | break; | ||
280 | case Opt_acl: | ||
281 | nfs_data.flags &= ~NFS_MOUNT_NOACL; | ||
282 | break; | ||
283 | case Opt_noacl: | ||
284 | nfs_data.flags |= NFS_MOUNT_NOACL; | ||
285 | break; | ||
286 | default: | ||
287 | printk(KERN_WARNING "Root-NFS: unknown " | ||
288 | "option: %s\n", p); | ||
289 | return 0; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return 1; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Prepare the NFS data structure and parse all options. | ||
298 | */ | ||
299 | static int __init root_nfs_name(char *name) | ||
300 | { | ||
301 | static char buf[NFS_MAXPATHLEN] __initdata; | ||
302 | char *cp; | ||
303 | |||
304 | /* Set some default values */ | ||
305 | memset(&nfs_data, 0, sizeof(nfs_data)); | ||
306 | nfs_port = -1; | ||
307 | nfs_data.version = NFS_MOUNT_VERSION; | ||
308 | nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */ | ||
309 | nfs_data.rsize = NFS_DEF_FILE_IO_SIZE; | ||
310 | nfs_data.wsize = NFS_DEF_FILE_IO_SIZE; | ||
311 | nfs_data.acregmin = NFS_DEF_ACREGMIN; | ||
312 | nfs_data.acregmax = NFS_DEF_ACREGMAX; | ||
313 | nfs_data.acdirmin = NFS_DEF_ACDIRMIN; | ||
314 | nfs_data.acdirmax = NFS_DEF_ACDIRMAX; | ||
315 | strcpy(buf, NFS_ROOT); | ||
316 | |||
317 | /* Process options received from the remote server */ | ||
318 | root_nfs_parse(root_server_path, buf); | ||
319 | |||
320 | /* Override them by options set on kernel command-line */ | ||
321 | root_nfs_parse(name, buf); | ||
322 | |||
323 | cp = utsname()->nodename; | ||
324 | if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) { | ||
325 | printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n"); | ||
326 | return -1; | ||
327 | } | ||
328 | sprintf(nfs_export_path, buf, cp); | ||
329 | |||
330 | return 1; | ||
331 | } | ||
332 | |||
333 | |||
334 | /* | ||
335 | * Get NFS server address. | ||
336 | */ | ||
337 | static int __init root_nfs_addr(void) | ||
338 | { | ||
339 | if ((servaddr = root_server_addr) == htonl(INADDR_NONE)) { | ||
340 | printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); | ||
341 | return -1; | ||
342 | } | ||
343 | |||
344 | snprintf(nfs_data.hostname, sizeof(nfs_data.hostname), | ||
345 | "%pI4", &servaddr); | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Tell the user what's going on. | ||
351 | */ | ||
352 | #ifdef NFSROOT_DEBUG | ||
353 | static void __init root_nfs_print(void) | ||
354 | { | ||
355 | printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n", | ||
356 | nfs_export_path, nfs_data.hostname); | ||
357 | printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n", | ||
358 | nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans); | ||
359 | printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n", | ||
360 | nfs_data.acregmin, nfs_data.acregmax, | ||
361 | nfs_data.acdirmin, nfs_data.acdirmax); | ||
362 | printk(KERN_NOTICE "Root-NFS: nfsd port = %d, mountd port = %d, flags = %08x\n", | ||
363 | nfs_port, mount_port, nfs_data.flags); | ||
364 | } | ||
365 | #endif | ||
366 | |||
367 | |||
368 | static int __init root_nfs_init(void) | ||
369 | { | ||
370 | #ifdef NFSROOT_DEBUG | ||
371 | nfs_debug |= NFSDBG_ROOT; | ||
372 | #endif | ||
373 | |||
374 | /* | ||
375 | * Decode the root directory path name and NFS options from | ||
376 | * the kernel command line. This has to go here in order to | ||
377 | * be able to use the client IP address for the remote root | ||
378 | * directory (necessary for pure RARP booting). | ||
379 | */ | ||
380 | if (root_nfs_name(nfs_root_parms) < 0 || | ||
381 | root_nfs_addr() < 0) | ||
382 | return -1; | ||
383 | |||
384 | #ifdef NFSROOT_DEBUG | ||
385 | root_nfs_print(); | ||
386 | #endif | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /* | 105 | /* |
392 | * Parse NFS server and directory information passed on the kernel | 106 | * Parse NFS server and directory information passed on the kernel |
393 | * command line. | 107 | * command line. |
@@ -424,137 +138,6 @@ static int __init nfs_root_setup(char *line) | |||
424 | 138 | ||
425 | __setup("nfsroot=", nfs_root_setup); | 139 | __setup("nfsroot=", nfs_root_setup); |
426 | 140 | ||
427 | /*************************************************************************** | ||
428 | |||
429 | Routines to actually mount the root directory | ||
430 | |||
431 | ***************************************************************************/ | ||
432 | |||
433 | /* | ||
434 | * Construct sockaddr_in from address and port number. | ||
435 | */ | ||
436 | static inline void | ||
437 | set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port) | ||
438 | { | ||
439 | sin->sin_family = AF_INET; | ||
440 | sin->sin_addr.s_addr = addr; | ||
441 | sin->sin_port = port; | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | * Query server portmapper for the port of a daemon program. | ||
446 | */ | ||
447 | static int __init root_nfs_getport(int program, int version, int proto) | ||
448 | { | ||
449 | struct sockaddr_in sin; | ||
450 | |||
451 | printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n", | ||
452 | program, version, &servaddr); | ||
453 | set_sockaddr(&sin, servaddr, 0); | ||
454 | return rpcb_getport_sync(&sin, program, version, proto); | ||
455 | } | ||
456 | |||
457 | |||
458 | /* | ||
459 | * Use portmapper to find mountd and nfsd port numbers if not overriden | ||
460 | * by the user. Use defaults if portmapper is not available. | ||
461 | * XXX: Is there any nfs server with no portmapper? | ||
462 | */ | ||
463 | static int __init root_nfs_ports(void) | ||
464 | { | ||
465 | int port; | ||
466 | int nfsd_ver, mountd_ver; | ||
467 | int nfsd_port, mountd_port; | ||
468 | int proto; | ||
469 | |||
470 | if (nfs_data.flags & NFS_MOUNT_VER3) { | ||
471 | nfsd_ver = NFS3_VERSION; | ||
472 | mountd_ver = NFS_MNT3_VERSION; | ||
473 | nfsd_port = NFS_PORT; | ||
474 | mountd_port = NFS_MNT_PORT; | ||
475 | } else { | ||
476 | nfsd_ver = NFS2_VERSION; | ||
477 | mountd_ver = NFS_MNT_VERSION; | ||
478 | nfsd_port = NFS_PORT; | ||
479 | mountd_port = NFS_MNT_PORT; | ||
480 | } | ||
481 | |||
482 | proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | ||
483 | |||
484 | if (nfs_port < 0) { | ||
485 | if ((port = root_nfs_getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) { | ||
486 | printk(KERN_ERR "Root-NFS: Unable to get nfsd port " | ||
487 | "number from server, using default\n"); | ||
488 | port = nfsd_port; | ||
489 | } | ||
490 | nfs_port = port; | ||
491 | dprintk("Root-NFS: Portmapper on server returned %d " | ||
492 | "as nfsd port\n", port); | ||
493 | } | ||
494 | |||
495 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { | ||
496 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " | ||
497 | "number from server, using default\n"); | ||
498 | port = mountd_port; | ||
499 | } | ||
500 | mount_port = port; | ||
501 | dprintk("Root-NFS: mountd port is %d\n", port); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | |||
507 | /* | ||
508 | * Get a file handle from the server for the directory which is to be | ||
509 | * mounted. | ||
510 | */ | ||
511 | static int __init root_nfs_get_handle(void) | ||
512 | { | ||
513 | struct sockaddr_in sin; | ||
514 | unsigned int auth_flav_len = 0; | ||
515 | struct nfs_mount_request request = { | ||
516 | .sap = (struct sockaddr *)&sin, | ||
517 | .salen = sizeof(sin), | ||
518 | .dirpath = nfs_export_path, | ||
519 | .version = (nfs_data.flags & NFS_MOUNT_VER3) ? | ||
520 | NFS_MNT3_VERSION : NFS_MNT_VERSION, | ||
521 | .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ? | ||
522 | XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP, | ||
523 | .auth_flav_len = &auth_flav_len, | ||
524 | }; | ||
525 | int status = -ENOMEM; | ||
526 | |||
527 | request.fh = nfs_alloc_fhandle(); | ||
528 | if (!request.fh) | ||
529 | goto out; | ||
530 | set_sockaddr(&sin, servaddr, htons(mount_port)); | ||
531 | status = nfs_mount(&request); | ||
532 | if (status < 0) | ||
533 | printk(KERN_ERR "Root-NFS: Server returned error %d " | ||
534 | "while mounting %s\n", status, nfs_export_path); | ||
535 | else { | ||
536 | nfs_data.root.size = request.fh->size; | ||
537 | memcpy(&nfs_data.root.data, request.fh->data, request.fh->size); | ||
538 | } | ||
539 | nfs_free_fhandle(request.fh); | ||
540 | out: | ||
541 | return status; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * Get the NFS port numbers and file handle, and return the prepared 'data' | ||
546 | * argument for mount() if everything went OK. Return NULL otherwise. | ||
547 | */ | ||
548 | void * __init old_nfs_root_data(void) | ||
549 | { | ||
550 | if (root_nfs_init() < 0 | ||
551 | || root_nfs_ports() < 0 | ||
552 | || root_nfs_get_handle() < 0) | ||
553 | return NULL; | ||
554 | set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port)); | ||
555 | return (void*)&nfs_data; | ||
556 | } | ||
557 | |||
558 | static int __init root_nfs_copy(char *dest, const char *src, | 141 | static int __init root_nfs_copy(char *dest, const char *src, |
559 | const size_t destlen) | 142 | const size_t destlen) |
560 | { | 143 | { |