This source file includes following definitions.
- root_dev_open
- root_dev_close
- root_rarp_open
- root_rarp_close
- root_rarp_recv
- root_rarp_send
- root_free_bootp
- root_alloc_bootp
- root_add_bootp_route
- root_del_bootp_route
- root_open_udp_sock
- root_connect_udp_sock
- root_bind_udp_sock
- root_send_udp
- root_recv_udp
- root_bootp_init_ext
- root_bootp_close
- root_bootp_open
- root_bootp_send
- root_bootp_string
- root_do_bootp_ext
- root_bootp_recv
- root_auto_config
- root_nfs_name
- root_nfs_print
- root_nfs_addrs
- root_nfs_setup
- nfs_root_init
- root_nfs_open
- root_nfs_close
- root_nfs_bind
- root_nfs_call
- root_nfs_header
- root_nfs_get_port
- root_nfs_ports
- root_nfs_get_handle
- root_nfs_do_mount
- nfs_root_mount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 #undef NFSROOT_DEBUG
47 #undef NFSROOT_BOOTP_DEBUG
48
49
50 #include <linux/config.h>
51 #include <linux/types.h>
52 #include <linux/string.h>
53 #include <linux/kernel.h>
54 #include <linux/sched.h>
55 #include <linux/fs.h>
56 #include <linux/random.h>
57 #include <linux/fcntl.h>
58
59 #include <asm/param.h>
60 #include <linux/utsname.h>
61 #include <linux/in.h>
62 #include <linux/if.h>
63 #include <linux/inet.h>
64 #include <linux/net.h>
65 #include <linux/netdevice.h>
66 #include <linux/if_arp.h>
67 #ifdef CONFIG_AX25
68 #include <net/ax25.h>
69 #endif
70 #include <linux/skbuff.h>
71 #include <linux/socket.h>
72 #include <linux/route.h>
73 #include <linux/nfs.h>
74 #include <linux/nfs_fs.h>
75 #include <linux/nfs_mount.h>
76 #include <linux/in.h>
77 #include <net/route.h>
78 #include <net/sock.h>
79
80
81
82 #define STARTPORT 600
83 #define ENDPORT 1023
84 #define NPORTS (ENDPORT - STARTPORT + 1)
85
86
87
88 #define CONF_BASE_TIMEOUT (HZ*5)
89 #define CONF_RETRIES 10
90 #define CONF_TIMEOUT_RANDOM (HZ)
91 #define CONF_TIMEOUT_MULT *5/4
92 #define CONF_TIMEOUT_MAX (HZ*30)
93
94
95
96 struct open_dev {
97 struct device *dev;
98 unsigned short old_flags;
99 struct open_dev *next;
100 };
101
102 static struct open_dev *open_base = NULL;
103
104
105
106 static struct device *root_dev = NULL;
107 static char user_dev_name[IFNAMSIZ];
108 static struct sockaddr_in myaddr;
109 static struct sockaddr_in server;
110 static struct sockaddr_in gateway;
111 static struct sockaddr_in netmask;
112
113
114
115 static int bootp_flag;
116 static int rarp_flag;
117 static int bootp_dev_count = 0;
118 static int rarp_dev_count = 0;
119
120 #if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
121 #define CONFIG_RNFS_DYNAMIC
122 static volatile int pkt_arrived;
123
124 #define ARRIVED_BOOTP 1
125 #define ARRIVED_RARP 2
126 #endif
127
128
129
130 static struct nfs_mount_data nfs_data;
131 static char nfs_path[NFS_MAXPATHLEN] = "";
132 static int nfs_port;
133
134
135
136 extern asmlinkage int sys_socket(int family, int type, int protocol);
137
138
139
140
141
142
143
144
145
146
147
148
149
150 static int root_dev_open(void)
151 {
152 struct open_dev *openp, **last;
153 struct device *dev;
154 unsigned short old_flags;
155
156 last = &open_base;
157 for (dev = dev_base; dev != NULL; dev = dev->next) {
158 if (dev->type < ARPHRD_SLIP &&
159 dev->family == AF_INET &&
160 !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
161 (!user_dev_name[0] || !strcmp(dev->name, user_dev_name))) {
162
163 old_flags = dev->flags;
164 dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
165 if (!(old_flags & IFF_UP) && dev_open(dev)) {
166 dev->flags = old_flags;
167 continue;
168 }
169 openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
170 GFP_ATOMIC);
171 if (openp == NULL)
172 continue;
173 openp->dev = dev;
174 openp->old_flags = old_flags;
175 *last = openp;
176 last = &openp->next;
177 bootp_dev_count++;
178 if (!(dev->flags & IFF_NOARP))
179 rarp_dev_count++;
180 #ifdef NFSROOT_DEBUG
181 printk(KERN_NOTICE "Root-NFS: Opened %s\n", dev->name);
182 #endif
183 }
184 }
185 *last = NULL;
186
187 if (!bootp_dev_count && !rarp_dev_count) {
188 printk(KERN_ERR "Root-NFS: Unable to open at least one network device\n");
189 return -1;
190 }
191 return 0;
192 }
193
194
195
196
197
198
199 static void root_dev_close(void)
200 {
201 struct open_dev *openp;
202 struct open_dev *nextp;
203
204 openp = open_base;
205 while (openp != NULL) {
206 nextp = openp->next;
207 openp->next = NULL;
208 if (openp->dev != root_dev) {
209 if (!(openp->old_flags & IFF_UP))
210 dev_close(openp->dev);
211 openp->dev->flags = openp->old_flags;
212 }
213 kfree_s(openp, sizeof(struct open_dev));
214 openp = nextp;
215 }
216 }
217
218
219
220
221
222
223
224
225
226 #ifdef CONFIG_RNFS_RARP
227
228 extern void arp_send(int type, int ptype, unsigned long target_ip,
229 struct device *dev, unsigned long src_ip,
230 unsigned char *dest_hw, unsigned char *src_hw,
231 unsigned char *target_hw);
232
233 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
234 struct packet_type *pt);
235
236
237 static struct packet_type rarp_packet_type = {
238 0,
239
240 NULL,
241 root_rarp_recv,
242 NULL,
243 NULL
244 };
245
246
247
248
249
250 static void root_rarp_open(void)
251 {
252 rarp_packet_type.type = htons(ETH_P_RARP);
253 dev_add_pack(&rarp_packet_type);
254 }
255
256
257
258
259
260 static void root_rarp_close(void)
261 {
262 rarp_packet_type.type = htons(ETH_P_RARP);
263 dev_remove_pack(&rarp_packet_type);
264 }
265
266
267
268
269
270 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
271 {
272 struct arphdr *rarp = (struct arphdr *)skb->h.raw;
273 unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
274 unsigned long sip, tip;
275 unsigned char *sha, *tha;
276
277
278 if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
279 kfree_skb(skb, FREE_READ);
280 return 0;
281 }
282
283
284 if (rarp->ar_op != htons(ARPOP_RREPLY)) {
285 kfree_skb(skb, FREE_READ);
286 return 0;
287 }
288
289
290 if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
291 #ifdef CONFIG_AX25
292 (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
293 #endif
294 rarp->ar_pln != 4) {
295 kfree_skb(skb, FREE_READ);
296 return 0;
297 }
298
299
300 sha = rarp_ptr;
301 rarp_ptr += dev->addr_len;
302 memcpy(&sip, rarp_ptr, 4);
303 rarp_ptr += 4;
304 tha = rarp_ptr;
305 rarp_ptr += dev->addr_len;
306 memcpy(&tip, rarp_ptr, 4);
307
308
309 if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
310 kfree_skb(skb, FREE_READ);
311 return 0;
312 }
313
314 if (rarp_flag && !bootp_flag &&
315 server.sin_addr.s_addr != INADDR_NONE &&
316 server.sin_addr.s_addr != sip) {
317 kfree_skb(skb, FREE_READ);
318 return 0;
319 }
320
321
322
323
324
325 cli();
326 if (pkt_arrived) {
327 sti();
328 kfree_skb(skb, FREE_READ);
329 return 0;
330 }
331 pkt_arrived = ARRIVED_RARP;
332 sti();
333 root_dev = dev;
334
335 if (myaddr.sin_addr.s_addr == INADDR_NONE) {
336 myaddr.sin_family = dev->family;
337 myaddr.sin_addr.s_addr = tip;
338 }
339 if (server.sin_addr.s_addr == INADDR_NONE) {
340 server.sin_family = dev->family;
341 server.sin_addr.s_addr = sip;
342 }
343 kfree_skb(skb, FREE_READ);
344 return 0;
345 }
346
347
348
349
350
351 static void root_rarp_send(void)
352 {
353 struct open_dev *openp;
354 struct device *dev;
355 int num = 0;
356
357 for (openp = open_base; openp != NULL; openp = openp->next) {
358 dev = openp->dev;
359 if (!(dev->flags & IFF_NOARP)) {
360 arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
361 dev->dev_addr, dev->dev_addr);
362 num++;
363 }
364 }
365 }
366 #endif
367
368
369
370
371
372
373
374
375
376 #ifdef CONFIG_RNFS_BOOTP
377
378 static struct device *bootp_dev = NULL;
379
380 static int bootp_xmit_fd = -1;
381 static struct socket *bootp_xmit_sock;
382 static int bootp_recv_fd = -1;
383 static struct socket *bootp_recv_sock;
384
385 struct bootp_pkt {
386 u8 op;
387 u8 htype;
388 u8 hlen;
389 u8 hops;
390 u32 xid;
391 u16 secs;
392 u16 flags;
393 u32 client_ip;
394 u32 your_ip;
395 u32 server_ip;
396 u32 relay_ip;
397 u8 hw_addr[16];
398 u8 serv_name[64];
399 u8 boot_file[128];
400 u8 vendor_area[128];
401 };
402
403 #define BOOTP_REQUEST 1
404 #define BOOTP_REPLY 2
405
406 static struct bootp_pkt *xmit_bootp;
407 static struct bootp_pkt *recv_bootp;
408
409 static int bootp_have_route = 0;
410
411
412
413
414
415 static void root_free_bootp(void)
416 {
417 if (xmit_bootp) {
418 kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
419 xmit_bootp = NULL;
420 }
421 if (recv_bootp) {
422 kfree_s(recv_bootp, sizeof(struct bootp_pkt));
423 recv_bootp = NULL;
424 }
425 }
426
427
428
429
430
431 static inline int root_alloc_bootp(void)
432 {
433 if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
434 !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
435 printk("BOOTP: Out of memory!");
436 return -1;
437 }
438 return 0;
439 }
440
441
442
443
444
445 static int root_add_bootp_route(void)
446 {
447 struct rtentry route;
448
449 memset(&route, 0, sizeof(route));
450 route.rt_dev = bootp_dev->name;
451 route.rt_mss = bootp_dev->mtu;
452 route.rt_flags = RTF_UP;
453 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
454 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_family = AF_INET;
455 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
456 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_family = AF_INET;
457 if (ip_rt_new(&route)) {
458 printk(KERN_ERR "BOOTP: Adding of route failed!\n");
459 return -1;
460 }
461 bootp_have_route = 1;
462 return 0;
463 }
464
465
466
467
468
469 static int root_del_bootp_route(void)
470 {
471 struct rtentry route;
472
473 if (!bootp_have_route)
474 return 0;
475 memset(&route, 0, sizeof(route));
476 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
477 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
478 if (ip_rt_kill(&route)) {
479 printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
480 return -1;
481 }
482 bootp_have_route = 0;
483 return 0;
484 }
485
486
487
488
489
490 static int root_open_udp_sock(int *fd, struct socket **sock)
491 {
492 struct file *file;
493 struct inode *inode;
494
495 *fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
496 if (*fd >= 0) {
497 file = current->files->fd[*fd];
498 inode = file->f_inode;
499 *sock = &inode->u.socket_i;
500 return 0;
501 }
502
503 printk(KERN_ERR "BOOTP: Cannot open UDP socket!\n");
504 return -1;
505 }
506
507
508
509
510
511 static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
512 {
513 struct sockaddr_in sa;
514 int result;
515
516 sa.sin_family = AF_INET;
517 sa.sin_addr.s_addr = htonl(addr);
518 sa.sin_port = htons(port);
519 result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
520 if (result < 0) {
521 printk(KERN_ERR "BOOTP: connect() failed\n");
522 return -1;
523 }
524 return 0;
525 }
526
527
528
529
530
531 static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
532 {
533 struct sockaddr_in sa;
534 int result;
535
536 sa.sin_family = AF_INET;
537 sa.sin_addr.s_addr = htonl(addr);
538 sa.sin_port = htons(port);
539 result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
540 if (result < 0) {
541 printk(KERN_ERR "BOOTP: bind() failed\n");
542 return -1;
543 }
544 return 0;
545 }
546
547
548
549
550
551 static inline int root_send_udp(struct socket *sock, void *buf, int size)
552 {
553 u32 oldfs;
554 int result;
555 struct msghdr msg;
556 struct iovec iov;
557
558 oldfs = get_fs();
559 set_fs(get_ds());
560 iov.iov_base = buf;
561 iov.iov_len = size;
562 msg.msg_name = NULL;
563 msg.msg_iov = &iov;
564 msg.msg_iovlen = 1;
565 msg.msg_accrights = NULL;
566 result = sock->ops->sendmsg(sock, &msg, size, 0, 0);
567 set_fs(oldfs);
568 return (result != size);
569 }
570
571
572
573
574
575 static inline int root_recv_udp(struct socket *sock, void *buf, int size)
576 {
577 u32 oldfs;
578 int result;
579 struct msghdr msg;
580 struct iovec iov;
581
582 oldfs = get_fs();
583 set_fs(get_ds());
584 iov.iov_base = buf;
585 iov.iov_len = size;
586 msg.msg_name = NULL;
587 msg.msg_iov = &iov;
588 msg.msg_iovlen = 1;
589 msg.msg_accrights = NULL;
590 msg.msg_namelen = 0;
591 result = sock->ops->recvmsg(sock, &msg, size, O_NONBLOCK, 0, &msg.msg_namelen);
592 set_fs(oldfs);
593 return result;
594 }
595
596
597
598
599
600 static void root_bootp_init_ext(u8 *e)
601 {
602 *e++ = 99;
603 *e++ = 130;
604 *e++ = 83;
605 *e++ = 99;
606 *e++ = 1;
607 *e++ = 4;
608 e += 4;
609 *e++ = 3;
610 *e++ = 4;
611 e += 4;
612 *e++ = 12;
613 *e++ = 32;
614 e += 32;
615 *e++ = 15;
616 *e++ = 32;
617 e += 32;
618 *e++ = 17;
619 *e++ = 32;
620 e += 32;
621 *e = 255;
622 }
623
624
625
626
627
628 static void root_bootp_close(void)
629 {
630 if (bootp_xmit_fd != -1)
631 sys_close(bootp_xmit_fd);
632 if (bootp_recv_fd != -1)
633 sys_close(bootp_recv_fd);
634 root_del_bootp_route();
635 root_free_bootp();
636 }
637
638
639
640
641
642 static int root_bootp_open(void)
643 {
644 struct open_dev *openp;
645 struct device *dev, *best_dev;
646
647
648
649
650
651
652
653
654 best_dev = NULL;
655 for (openp = open_base; openp != NULL; openp = openp->next) {
656 dev = openp->dev;
657 if (dev->flags & IFF_BROADCAST) {
658 if (!best_dev ||
659 ((best_dev->flags & IFF_NOARP) && !(dev->flags & IFF_NOARP)))
660 best_dev = dev;
661 }
662 }
663
664 if (!best_dev) {
665 printk(KERN_ERR "BOOTP: This cannot happen!\n");
666 return -1;
667 }
668 bootp_dev = best_dev;
669
670
671 if (root_alloc_bootp())
672 return -1;
673
674
675 memset(xmit_bootp, 0, sizeof(struct bootp_pkt));
676 xmit_bootp->op = BOOTP_REQUEST;
677 get_random_bytes(&xmit_bootp->xid, sizeof(xmit_bootp->xid));
678 xmit_bootp->htype = best_dev->type;
679 xmit_bootp->hlen = best_dev->addr_len;
680 memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
681 root_bootp_init_ext(xmit_bootp->vendor_area);
682 #ifdef NFSROOT_BOOTP_DEBUG
683 {
684 int x;
685 printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
686 xmit_bootp->xid,
687 best_dev->name,
688 xmit_bootp->htype,
689 xmit_bootp->hlen);
690 for(x=0; x<xmit_bootp->hlen; x++)
691 printk("%02x", xmit_bootp->hw_addr[x]);
692 printk("\n");
693 }
694 #endif
695
696
697 if (root_add_bootp_route())
698 return -1;
699
700
701 if (root_open_udp_sock(&bootp_xmit_fd, &bootp_xmit_sock) ||
702 root_open_udp_sock(&bootp_recv_fd, &bootp_recv_sock))
703 return -1;
704
705
706 ((struct sock *) bootp_xmit_sock->data) -> broadcast = 1;
707 ((struct sock *) bootp_xmit_sock->data) -> reuse = 1;
708 ((struct sock *) bootp_recv_sock->data) -> reuse = 1;
709 if (root_bind_udp_sock(bootp_recv_sock, INADDR_ANY, 68) ||
710 root_bind_udp_sock(bootp_xmit_sock, INADDR_ANY, 68) ||
711 root_connect_udp_sock(bootp_xmit_sock, INADDR_BROADCAST, 67))
712 return -1;
713
714 return 0;
715 }
716
717
718
719
720
721 static int root_bootp_send(u32 jiffies)
722 {
723 xmit_bootp->secs = htons(jiffies / HZ);
724 return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
725 }
726
727
728
729
730
731 static int root_bootp_string(char *dest, char *src, int len, int max)
732 {
733 if (*dest || !len)
734 return 0;
735 if (len > max-1)
736 len = max-1;
737 strncpy(dest, src, len);
738 dest[len] = '\0';
739 return 1;
740 }
741
742
743
744
745
746 static void root_do_bootp_ext(u8 *ext)
747 {
748 u8 *c;
749 static int got_bootp_domain = 0;
750
751 #ifdef NFSROOT_BOOTP_DEBUG
752 printk("BOOTP: Got extension %02x",*ext);
753 for(c=ext+2; c<ext+2+ext[1]; c++)
754 printk(" %02x", *c);
755 printk("\n");
756 #endif
757
758 switch (*ext++) {
759 case 1:
760 if (netmask.sin_addr.s_addr == INADDR_NONE)
761 memcpy(&netmask.sin_addr.s_addr, ext+1, 4);
762 break;
763 case 3:
764 if (gateway.sin_addr.s_addr == INADDR_NONE)
765 memcpy(&gateway.sin_addr.s_addr, ext+1, 4);
766 break;
767 case 12:
768 if (root_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN)) {
769 c = strchr(system_utsname.nodename, '.');
770 if (c) {
771 *c++ = 0;
772 if (!system_utsname.domainname[0]) {
773 strcpy(system_utsname.domainname, c);
774 got_bootp_domain = 1;
775 }
776 }
777 }
778 break;
779 case 15:
780 if (got_bootp_domain && *ext && ext[1])
781 system_utsname.domainname[0] = '\0';
782 root_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
783 break;
784 case 17:
785 root_bootp_string(nfs_path, ext+1, *ext, NFS_MAXPATHLEN);
786 break;
787 }
788 }
789
790
791
792
793
794 static void root_bootp_recv(void)
795 {
796 int len;
797 u8 *ext, *end, *opt;
798
799 len = root_recv_udp(bootp_recv_sock, recv_bootp, sizeof(struct bootp_pkt));
800 if (len < 0)
801 return;
802
803
804 if (len < 300 ||
805 recv_bootp->op != BOOTP_REPLY ||
806 recv_bootp->htype != xmit_bootp->htype ||
807 recv_bootp->hlen != xmit_bootp->hlen ||
808 recv_bootp->xid != xmit_bootp->xid) {
809 #ifdef NFSROOT_BOOTP_DEBUG
810 printk("?");
811 #endif
812 return;
813 }
814
815
816 cli();
817 if (pkt_arrived) {
818 sti();
819 return;
820 }
821 pkt_arrived = ARRIVED_BOOTP;
822 sti();
823 root_dev = bootp_dev;
824
825
826 myaddr.sin_addr.s_addr = recv_bootp->your_ip;
827 server.sin_addr.s_addr = recv_bootp->server_ip;
828
829
830 if (recv_bootp->vendor_area[0] == 99 &&
831 recv_bootp->vendor_area[1] == 130 &&
832 recv_bootp->vendor_area[2] == 83 &&
833 recv_bootp->vendor_area[3] == 99) {
834 ext = &recv_bootp->vendor_area[4];
835 end = (u8 *) recv_bootp + len;
836 while (ext < end && *ext != 255) {
837 if (*ext == 0)
838 ext++;
839 else {
840 opt = ext;
841 ext += ext[1] + 2;
842 if (ext <= end)
843 root_do_bootp_ext(opt);
844 }
845 }
846 }
847 }
848 #endif
849
850
851
852
853
854
855
856
857
858 #ifdef CONFIG_RNFS_DYNAMIC
859
860
861
862
863
864 static int root_auto_config(void)
865 {
866 int retries;
867 unsigned long timeout, jiff;
868 unsigned long start_jiffies;
869
870
871
872
873
874
875
876 if (!bootp_flag && !rarp_flag) {
877 printk(KERN_ERR "Root-NFS: Neither RARP nor BOOTP selected.\n");
878 return -1;
879 }
880
881 #ifdef CONFIG_RNFS_BOOTP
882 if (bootp_flag && !bootp_dev_count) {
883 printk(KERN_ERR "Root-NFS: No suitable device for BOOTP found.\n");
884 bootp_flag = 0;
885 }
886 #else
887 bootp_flag = 0;
888 #endif
889
890 #ifdef CONFIG_RNFS_RARP
891 if (rarp_flag && !rarp_dev_count) {
892 printk(KERN_ERR "Root-NFS: No suitable device for RARP found.\n");
893 rarp_flag = 0;
894 }
895 #else
896 rarp_flag = 0;
897 #endif
898
899 if (!bootp_flag && !rarp_flag)
900
901 return -1;
902
903
904
905
906 #ifdef CONFIG_RNFS_RARP
907 if (rarp_flag)
908 root_rarp_open();
909 #endif
910 #ifdef CONFIG_RNFS_BOOTP
911 if (bootp_flag && root_bootp_open() < 0) {
912 root_bootp_close();
913 return -1;
914 }
915 #endif
916
917
918
919
920
921
922
923
924
925 printk(KERN_NOTICE "Sending %s%s%s requests...",
926 bootp_flag ? "BOOTP" : "",
927 bootp_flag && rarp_flag ? " and " : "",
928 rarp_flag ? "RARP" : "");
929 start_jiffies = jiffies;
930 retries = CONF_RETRIES;
931 get_random_bytes(&timeout, sizeof(timeout));
932 timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
933 for(;;) {
934 #ifdef CONFIG_RNFS_BOOTP
935 if (bootp_flag && root_bootp_send(jiffies - start_jiffies) < 0) {
936 printk(" BOOTP failed!\n");
937 root_bootp_close();
938 bootp_flag = 0;
939 if (!rarp_flag)
940 break;
941 }
942 #endif
943 #ifdef CONFIG_RNFS_RARP
944 if (rarp_flag)
945 root_rarp_send();
946 #endif
947 printk(".");
948 jiff = jiffies + timeout;
949 while (jiffies < jiff && !pkt_arrived)
950 #ifdef CONFIG_RNFS_BOOTP
951 root_bootp_recv();
952 #else
953 ;
954 #endif
955 if (pkt_arrived)
956 break;
957 if (! --retries) {
958 printk(" timed out!\n");
959 break;
960 }
961 timeout = timeout CONF_TIMEOUT_MULT;
962 if (timeout > CONF_TIMEOUT_MAX)
963 timeout = CONF_TIMEOUT_MAX;
964 }
965
966 #ifdef CONFIG_RNFS_RARP
967 if (rarp_flag)
968 root_rarp_close();
969 #endif
970 #ifdef CONFIG_RNFS_BOOTP
971 if (bootp_flag)
972 root_bootp_close();
973 #endif
974
975 if (!pkt_arrived)
976 return -1;
977
978 printk(" OK\n");
979 printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
980 (pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
981 in_ntoa(server.sin_addr.s_addr));
982 printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
983
984 return 0;
985 }
986 #endif
987
988
989
990
991
992
993
994
995
996
997
998
999
1000 static struct nfs_int_opts {
1001 char *name;
1002 int *val;
1003 } root_int_opts[] = {
1004 { "port", &nfs_port },
1005 { "rsize", &nfs_data.rsize },
1006 { "wsize", &nfs_data.wsize },
1007 { "timeo", &nfs_data.timeo },
1008 { "retrans", &nfs_data.retrans },
1009 { "acregmin", &nfs_data.acregmin },
1010 { "acregmax", &nfs_data.acregmax },
1011 { "acdirmin", &nfs_data.acdirmin },
1012 { "acdirmax", &nfs_data.acdirmax },
1013 { NULL, NULL }
1014 };
1015
1016
1017
1018
1019
1020 static struct nfs_bool_opts {
1021 char *name;
1022 int and_mask;
1023 int or_mask;
1024 } root_bool_opts[] = {
1025 { "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT },
1026 { "hard", ~NFS_MOUNT_SOFT, 0 },
1027 { "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR },
1028 { "nointr", ~NFS_MOUNT_INTR, 0 },
1029 { "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX },
1030 { "noposix", ~NFS_MOUNT_POSIX, 0 },
1031 { "cto", ~NFS_MOUNT_NOCTO, 0 },
1032 { "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO },
1033 { "ac", ~NFS_MOUNT_NOAC, 0 },
1034 { "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC },
1035 { NULL, 0, 0 }
1036 };
1037
1038
1039
1040
1041
1042
1043 static int root_nfs_name(char *name)
1044 {
1045 char buf[NFS_MAXPATHLEN];
1046 char *cp, *options, *val;
1047
1048
1049 if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
1050 *cp++ = '\0';
1051 server.sin_addr.s_addr = in_aton(name);
1052 name = cp;
1053 }
1054
1055
1056 memset(&nfs_data, 0, sizeof(nfs_data));
1057 strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr),
1058 sizeof(nfs_data.hostname)-1);
1059
1060
1061 cp = in_ntoa(myaddr.sin_addr.s_addr);
1062 strncpy(buf, name, 255);
1063 if ((options = strchr(buf, ',')))
1064 *options++ = '\0';
1065 if (!strcmp(buf, "default"))
1066 strcpy(buf, NFS_ROOT);
1067 if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
1068 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
1069 return -1;
1070 }
1071 sprintf(nfs_path, buf, cp);
1072
1073
1074 nfs_port = -1;
1075 nfs_data.version = NFS_MOUNT_VERSION;
1076 nfs_data.flags = 0;
1077 nfs_data.rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
1078 nfs_data.wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
1079 nfs_data.timeo = 7;
1080 nfs_data.retrans = 3;
1081 nfs_data.acregmin = 3;
1082 nfs_data.acregmax = 60;
1083 nfs_data.acdirmin = 30;
1084 nfs_data.acdirmax = 60;
1085
1086
1087 if (options) {
1088 cp = strtok(options, ",");
1089 while (cp) {
1090 if ((val = strchr(cp, '='))) {
1091 struct nfs_int_opts *opts = root_int_opts;
1092 *val++ = '\0';
1093 while (opts->name && strcmp(opts->name, cp))
1094 opts++;
1095 if (opts->name)
1096 *(opts->val) = (int) simple_strtoul(val, NULL, 10);
1097 } else {
1098 struct nfs_bool_opts *opts = root_bool_opts;
1099 while (opts->name && strcmp(opts->name, cp))
1100 opts++;
1101 if (opts->name) {
1102 nfs_data.flags &= opts->and_mask;
1103 nfs_data.flags |= opts->or_mask;
1104 }
1105 }
1106 cp = strtok(NULL, ",");
1107 }
1108 }
1109 return 0;
1110 }
1111
1112
1113
1114
1115
1116 #ifdef NFSROOT_DEBUG
1117 static void root_nfs_print(void)
1118 {
1119 #define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
1120
1121 printk(KERN_NOTICE "Root-NFS: IP config: dev=%s, ",
1122 root_dev ? root_dev->name : "none");
1123 printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1124 printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1125 printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1126 printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1127 printk("host=%s, domain=%s\n",
1128 system_utsname.nodename[0] ? system_utsname.nodename : "none",
1129 system_utsname.domainname[0] ? system_utsname.domainname : "none");
1130 printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
1131 nfs_path, nfs_data.hostname);
1132 printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
1133 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
1134 printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
1135 nfs_data.acregmin, nfs_data.acregmax,
1136 nfs_data.acdirmin, nfs_data.acdirmax);
1137 printk(KERN_NOTICE "Root-NFS: port = %d, flags = %08x\n",
1138 nfs_port, nfs_data.flags);
1139
1140 #undef IN_NTOA
1141 }
1142 #endif
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 static void root_nfs_addrs(char *addrs)
1165 {
1166 char *cp, *ip, *dp;
1167 int num = 0;
1168
1169
1170 myaddr.sin_family = server.sin_family =
1171 gateway.sin_family = netmask.sin_family = AF_INET;
1172 myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
1173 gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
1174 system_utsname.nodename[0] = '\0';
1175 system_utsname.domainname[0] = '\0';
1176 user_dev_name[0] = '\0';
1177 bootp_flag = rarp_flag = 1;
1178
1179
1180 if (!strcmp(addrs, "bootp")) {
1181 rarp_flag = 0;
1182 return;
1183 } else if (!strcmp(addrs, "rarp")) {
1184 bootp_flag = 0;
1185 return;
1186 } else if (!strcmp(addrs, "both")) {
1187 return;
1188 }
1189
1190
1191 ip = addrs;
1192 while (ip && *ip) {
1193 if ((cp = strchr(ip, ':')))
1194 *cp++ = '\0';
1195 if (strlen(ip) > 0) {
1196 #ifdef NFSROOT_DEBUG
1197 printk(KERN_NOTICE "Root-NFS: Config string num %d is \"%s\"\n",
1198 num, ip);
1199 #endif
1200 switch (num) {
1201 case 0:
1202 myaddr.sin_addr.s_addr = in_aton(ip);
1203 break;
1204 case 1:
1205 server.sin_addr.s_addr = in_aton(ip);
1206 break;
1207 case 2:
1208 gateway.sin_addr.s_addr = in_aton(ip);
1209 break;
1210 case 3:
1211 netmask.sin_addr.s_addr = in_aton(ip);
1212 break;
1213 case 4:
1214 if ((dp = strchr(ip, '.'))) {
1215 *dp++ = '\0';
1216 strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
1217 system_utsname.domainname[__NEW_UTS_LEN] = '\0';
1218 }
1219 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
1220 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1221 break;
1222 case 5:
1223 strncpy(user_dev_name, ip, IFNAMSIZ);
1224 user_dev_name[IFNAMSIZ-1] = '\0';
1225 break;
1226 case 6:
1227 if (!strcmp(ip, "rarp"))
1228 bootp_flag = 0;
1229 else if (!strcmp(ip, "bootp"))
1230 rarp_flag = 0;
1231 else if (strcmp(ip, "both"))
1232 bootp_flag = rarp_flag = 0;
1233 break;
1234 default:
1235 break;
1236 }
1237 }
1238 ip = cp;
1239 num++;
1240 }
1241 }
1242
1243
1244
1245
1246
1247 static int root_nfs_setup(void)
1248 {
1249 struct rtentry route;
1250
1251
1252 if (!system_utsname.nodename[0]) {
1253 strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
1254 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1255 }
1256
1257
1258 if (netmask.sin_addr.s_addr == INADDR_NONE)
1259 netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
1260
1261
1262 root_dev->family = myaddr.sin_family;
1263 root_dev->pa_addr = myaddr.sin_addr.s_addr;
1264 root_dev->pa_mask = netmask.sin_addr.s_addr;
1265 root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
1266 root_dev->pa_dstaddr = 0;
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276 memset(&route, 0, sizeof(route));
1277 route.rt_dev = root_dev->name;
1278 route.rt_mss = root_dev->mtu;
1279 route.rt_flags = RTF_UP;
1280 *((struct sockaddr_in *) &(route.rt_dst)) = myaddr;
1281 (((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr &= netmask.sin_addr.s_addr;
1282 *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
1283 if (ip_rt_new(&route)) {
1284 printk(KERN_ERR "Root-NFS: Adding of local route failed!\n");
1285 return -1;
1286 }
1287
1288 if (gateway.sin_addr.s_addr != INADDR_NONE) {
1289 (((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr = INADDR_ANY;
1290 (((struct sockaddr_in *) &(route.rt_genmask)))->sin_addr.s_addr = INADDR_ANY;
1291 *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
1292 route.rt_flags |= RTF_GATEWAY;
1293 if ((gateway.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1294 printk(KERN_ERR "Root-NFS: Gateway not on local network!\n");
1295 return -1;
1296 }
1297 if (ip_rt_new(&route)) {
1298 printk(KERN_ERR "Root-NFS: Adding of default route failed!\n");
1299 return -1;
1300 }
1301 } else if ((server.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1302 printk(KERN_ERR "Root-NFS: Boot server not on local network and no default gateway configured!\n");
1303 return -1;
1304 }
1305
1306 return 0;
1307 }
1308
1309
1310
1311
1312
1313
1314 int nfs_root_init(char *nfsname, char *nfsaddrs)
1315 {
1316
1317
1318
1319
1320
1321 root_nfs_addrs(nfsaddrs);
1322
1323
1324
1325
1326 if (root_dev_open() < 0)
1327 return -1;
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341 if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
1342 server.sin_addr.s_addr == INADDR_NONE ||
1343 (open_base != NULL && open_base->next != NULL))
1344 #ifdef CONFIG_RNFS_DYNAMIC
1345 && root_auto_config() < 0
1346 #endif
1347 ) {
1348 root_dev_close();
1349 return -1;
1350 }
1351 if (root_dev == NULL) {
1352 if (open_base != NULL && open_base->next == NULL) {
1353 root_dev = open_base->dev;
1354 } else {
1355 printk(KERN_ERR "Root-NFS: Multiple devices and no server\n");
1356 root_dev_close();
1357 return -1;
1358 }
1359 }
1360
1361
1362
1363
1364
1365 root_dev_close();
1366
1367
1368
1369
1370
1371
1372
1373 if (root_nfs_name(nfsname) < 0)
1374 return -1;
1375
1376
1377
1378
1379
1380 if (root_nfs_setup() < 0)
1381 return -1;
1382
1383 #ifdef NFSROOT_DEBUG
1384 root_nfs_print();
1385 #endif
1386
1387 return 0;
1388 }
1389
1390
1391
1392
1393
1394
1395
1396
1397 static struct file *nfs_file;
1398 static struct inode *nfs_sock_inode;
1399 static int *rpc_packet = NULL;
1400
1401
1402
1403
1404
1405 static int root_nfs_open(void)
1406 {
1407
1408 if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
1409 printk(KERN_ERR "Root-NFS: Cannot open UDP socket for NFS!\n");
1410 return -1;
1411 }
1412 nfs_file = current->files->fd[nfs_data.fd];
1413 nfs_sock_inode = nfs_file->f_inode;
1414 return 0;
1415 }
1416
1417
1418
1419
1420
1421
1422
1423 static void root_nfs_close(void)
1424 {
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 sys_close(nfs_data.fd);
1436 }
1437
1438
1439
1440
1441
1442 static int root_nfs_bind(void)
1443 {
1444 int res = -1;
1445 short port = STARTPORT;
1446 struct sockaddr_in *sin = &myaddr;
1447 int i;
1448
1449 if (nfs_sock_inode->u.socket_i.ops->bind) {
1450 for (i = 0; i < NPORTS && res < 0; i++) {
1451 sin->sin_port = htons(port++);
1452 if (port > ENDPORT) {
1453 port = STARTPORT;
1454 }
1455 res = nfs_sock_inode->u.socket_i.ops->bind(&nfs_sock_inode->u.socket_i,
1456 (struct sockaddr *)sin,
1457 sizeof(struct sockaddr_in));
1458 }
1459 }
1460 if (res < 0) {
1461 printk(KERN_ERR "Root-NFS: Cannot find a suitable listening port\n");
1462 root_nfs_close();
1463 return -1;
1464 }
1465 #ifdef NFSROOT_DEBUG
1466 printk(KERN_NOTICE "Root-NFS: Binding to listening port %d\n", port);
1467 #endif
1468 return 0;
1469 }
1470
1471
1472
1473
1474
1475 static int *root_nfs_call(int *end)
1476 {
1477 struct socket *sock;
1478 int dummylen;
1479 static struct nfs_server s = {
1480 0,
1481 0,
1482 {
1483 0, "",
1484 },
1485 0,
1486 NULL,
1487 NFS_MOUNT_SOFT,
1488 0, 0,
1489 0,
1490 0,
1491 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
1492 };
1493
1494 s.file = nfs_file;
1495 sock = &((nfs_file->f_inode)->u.socket_i);
1496
1497
1498 sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
1499 ((struct sockaddr_in *) &s.toaddr)->sin_port = server.sin_port;
1500 ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
1501 ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
1502
1503 s.rsock = rpc_makesock(nfs_file);
1504 s.flags = nfs_data.flags;
1505 s.rsize = nfs_data.rsize;
1506 s.wsize = nfs_data.wsize;
1507 s.timeo = nfs_data.timeo * HZ / 10;
1508 s.retrans = nfs_data.retrans;
1509 strcpy(s.hostname, nfs_data.hostname);
1510
1511
1512
1513
1514
1515 if (nfs_sock_inode->u.socket_i.ops->connect &&
1516 nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
1517 (struct sockaddr *) &server,
1518 sizeof(struct sockaddr_in),
1519 nfs_file->f_flags) < 0)
1520 return NULL;
1521 if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
1522 return NULL;
1523 return rpc_verify(rpc_packet);
1524 }
1525
1526
1527
1528
1529
1530 static int *root_nfs_header(int proc, int program, int version)
1531 {
1532 int groups[] = { 0, NOGROUP };
1533
1534 if (rpc_packet == NULL) {
1535 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
1536 printk(KERN_ERR "Root-NFS: Cannot allocate UDP buffer\n");
1537 return NULL;
1538 }
1539 }
1540 return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
1541 }
1542
1543
1544
1545
1546
1547 static int root_nfs_get_port(int program, int version)
1548 {
1549 int *p;
1550
1551
1552 server.sin_port = htons(NFS_PMAP_PORT);
1553 p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
1554 if (!p)
1555 return -1;
1556
1557
1558 *p++ = htonl(program);
1559 *p++ = htonl(version);
1560 *p++ = htonl(IPPROTO_UDP);
1561 *p++ = 0;
1562
1563
1564 if ((p = root_nfs_call(p)) == NULL)
1565 return -1;
1566
1567 return ntohl(*p);
1568 }
1569
1570
1571
1572
1573
1574 static int root_nfs_ports(void)
1575 {
1576 int port;
1577
1578 if (nfs_port < 0) {
1579 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
1580 printk(KERN_ERR "Root-NFS: Unable to get nfsd port number from server, using default\n");
1581 port = NFS_NFS_PORT;
1582 }
1583 nfs_port = port;
1584 #ifdef NFSROOT_DEBUG
1585 printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as nfsd port\n", port);
1586 #endif
1587 }
1588 if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
1589 printk(KERN_ERR "Root-NFS: Unable to get mountd port number from server, using default\n");
1590 port = NFS_MOUNT_PORT;
1591 }
1592 server.sin_port = htons(port);
1593 #ifdef NFSROOT_DEBUG
1594 printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as mountd port\n", port);
1595 #endif
1596
1597 return 0;
1598 }
1599
1600
1601
1602
1603
1604
1605 static int root_nfs_get_handle(void)
1606 {
1607 int len, status, *p;
1608
1609
1610 p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
1611 if (!p) {
1612 root_nfs_close();
1613 return -1;
1614 }
1615
1616
1617 len = strlen(nfs_path);
1618 *p++ = htonl(len);
1619 memcpy(p, nfs_path, len);
1620 len = (len + 3) >> 2;
1621 p[len] = 0;
1622 p += len;
1623
1624
1625 if ((p = root_nfs_call(p)) == NULL) {
1626 root_nfs_close();
1627 return -1;
1628 }
1629 status = ntohl(*p++);
1630 if (status == 0) {
1631 nfs_data.root = *((struct nfs_fh *) p);
1632 printk(KERN_NOTICE "Root-NFS: Got file handle for %s via RPC\n", nfs_path);
1633 } else {
1634 printk(KERN_ERR "Root-NFS: Server returned error %d while mounting %s\n",
1635 status, nfs_path);
1636 root_nfs_close();
1637 return -1;
1638 }
1639
1640 return 0;
1641 }
1642
1643
1644
1645
1646
1647 static int root_nfs_do_mount(struct super_block *sb)
1648 {
1649
1650 server.sin_port = htons(nfs_port);
1651 nfs_data.addr = server;
1652 if (nfs_sock_inode->u.socket_i.ops->connect &&
1653 nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
1654 (struct sockaddr *) &server,
1655 sizeof(struct sockaddr_in),
1656 nfs_file->f_flags) < 0) {
1657 root_nfs_close();
1658 return -1;
1659 }
1660
1661
1662 if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
1663 root_nfs_close();
1664 return -1;
1665 }
1666 return 0;
1667 }
1668
1669
1670
1671
1672
1673
1674 int nfs_root_mount(struct super_block *sb)
1675 {
1676 if (root_nfs_open() < 0)
1677 return -1;
1678 if (root_nfs_bind() < 0)
1679 return -1;
1680 if (root_nfs_ports() < 0)
1681 return -1;
1682 if (root_nfs_get_handle() < 0)
1683 return -1;
1684 if (root_nfs_do_mount(sb) < 0)
1685 return -1;
1686 root_nfs_close();
1687 return 0;
1688 }