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