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