root/fs/nfs/nfsroot.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. root_rarp_open
  2. root_rarp_close
  3. root_rarp_recv
  4. root_rarp_send
  5. do_rarp
  6. nfs_get_address
  7. root_nfs_parse
  8. root_nfs_print
  9. root_nfs_setup
  10. nfs_root_init
  11. root_nfs_open
  12. root_nfs_close
  13. root_nfs_bind
  14. root_nfs_call
  15. root_nfs_header
  16. root_nfs_get_port
  17. root_nfs_ports
  18. root_nfs_get_handle
  19. root_nfs_do_mount
  20. nfs_root_mount

   1 /*
   2  *  linux/fs/nfs/nfsroot.c
   3  *
   4  *  Copyright (C) 1995  Gero Kuhlmann <gero@gkminix.han.de>
   5  *
   6  *  Allow an NFS filesystem to be mounted as root. The way this works
   7  *  is to first determine the local IP address via RARP. Then handle
   8  *  the RPC negotiation with the system which replied to the RARP. The
   9  *  actual mounting is done later, when init() is running.
  10  *
  11  *      Changes:
  12  *
  13  *      Alan Cox        :       Removed get_address name clash with FPU.
  14  *      Alan Cox        :       Reformatted a bit.
  15  *
  16  *      TODO:
  17  *              Support bootp and dhcp as well as rarp.
  18  */
  19 
  20 
  21 /* Define this to allow debugging output */
  22 #define NFSROOT_DEBUG 1
  23 
  24 /* Define the timeout for waiting for a RARP reply */
  25 #define RARP_TIMEOUT    30      /* 30 seconds */
  26 #define RARP_RETRIES     5      /* 5 retries */
  27 
  28 #include <linux/config.h>
  29 #include <linux/types.h>
  30 #include <linux/string.h>
  31 #include <linux/kernel.h>
  32 #include <linux/sched.h>
  33 #include <linux/fs.h>
  34 
  35 #include <asm/param.h>
  36 #include <linux/utsname.h>
  37 #include <linux/in.h>
  38 #include <linux/if.h>
  39 #include <linux/inet.h>
  40 #include <linux/net.h>
  41 #include <linux/if_arp.h>
  42 #include <linux/netdevice.h>
  43 #ifdef CONFIG_AX25
  44 #include <net/ax25.h>   /* For AX25_P_IP */
  45 #endif
  46 #include <linux/skbuff.h>
  47 #include <linux/socket.h>
  48 #include <linux/route.h>
  49 #include <net/route.h>
  50 #include <linux/nfs.h>
  51 #include <linux/nfs_fs.h>
  52 #include <linux/nfs_mount.h>
  53 
  54 #define IPPORT_RESERVED 1024
  55 
  56 /* Range of privileged ports */
  57 #define STARTPORT 600
  58 #define ENDPORT (IPPORT_RESERVED - 1)
  59 #define NPORTS  (ENDPORT - STARTPORT + 1)
  60 
  61 
  62 
  63 struct open_dev
  64 {
  65         struct device *dev;
  66         unsigned short old_flags;
  67         struct open_dev *next;
  68 };
  69 
  70 static struct open_dev *open_base = NULL;
  71 static struct device *root_dev = NULL;
  72 static struct sockaddr_in myaddr;       /* My IP address */
  73 static struct sockaddr_in server;       /* Server IP address */
  74 static struct nfs_mount_data nfs_data;  /* NFS mount info */
  75 static char nfs_path[NFS_MAXPATHLEN];   /* Name of directory to mount */
  76 static int nfs_port;                    /* Port to connect to for NFS service */
  77 
  78 
  79 
  80 /***************************************************************************
  81 
  82                         RARP Subroutines
  83 
  84  ***************************************************************************/
  85 
  86 extern void arp_send(int type, int ptype, unsigned long target_ip, 
  87                         struct device *dev, unsigned long src_ip, 
  88                         unsigned char *dest_hw, unsigned char *src_hw,
  89                         unsigned char *target_hw);
  90 
  91 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
  92                         struct packet_type *pt);
  93 
  94 
  95 static struct packet_type rarp_packet_type =
  96 {
  97         0,      /* Should be: __constant_htons(ETH_P_RARP) - but this _doesn't_ come out constant! */
  98         NULL,   /* Listen to all devices */
  99         root_rarp_recv,
 100         NULL,
 101         NULL
 102 };
 103 
 104 
 105 /*
 106  *  For receiving rarp packets a packet type has to be registered. Also
 107  *  initialize all devices for usage by RARP.
 108  */
 109 
 110 static int root_rarp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         struct open_dev *openp;
 113         struct device *dev;
 114         unsigned short old_flags;
 115         int num;
 116 
 117         /*
 118          *      Register the packet type 
 119          */
 120          
 121         rarp_packet_type.type=htons(ETH_P_RARP);
 122         dev_add_pack(&rarp_packet_type);
 123 
 124         /*
 125          *      Open all devices which allow RARP 
 126          */
 127          
 128         for (dev = dev_base, num = 0; dev != NULL; dev = dev->next) 
 129         {
 130                 if (dev->type < ARPHRD_SLIP &&
 131                         dev->family == AF_INET &&
 132                         !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_NOARP))) 
 133                 {
 134                         /* First up the interface */
 135                         old_flags = dev->flags;
 136                         dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
 137                         if (!(old_flags & IFF_UP) && dev_open(dev)) 
 138                         {
 139                                 dev->flags = old_flags;
 140                                 continue;
 141                         }
 142                         openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 143                                                 GFP_ATOMIC);
 144                         if (openp == NULL)
 145                                 continue;
 146                         openp->dev = dev;
 147                         openp->old_flags = old_flags;
 148                         openp->next = open_base;
 149                         open_base = openp;
 150                         num++;
 151                 }
 152         }
 153         return num;
 154 }
 155 
 156 
 157 /*
 158  *  Remove the packet type again when all rarp packets have been received
 159  *  and restore the state of the device. However, keep the root device
 160  *  open for the upcoming mount.
 161  */
 162 
 163 static void root_rarp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         struct open_dev *openp;
 166         struct open_dev *nextp;
 167 
 168         /*
 169          *      Deregister the packet type 
 170          */
 171          
 172         rarp_packet_type.type=htons(ETH_P_RARP);
 173         dev_remove_pack(&rarp_packet_type);
 174 
 175         /*
 176          *      Deactivate all previously opened devices except that one which is
 177          *      able to connect to a suitable server
 178          */
 179 
 180         openp = open_base;
 181         while (openp != NULL) 
 182         {
 183                 nextp = openp->next;
 184                 openp->next = NULL;
 185                 if (openp->dev != root_dev) 
 186                 {
 187                         if (!(openp->old_flags & IFF_UP))
 188                                 dev_close(openp->dev);
 189                         openp->dev->flags = openp->old_flags;
 190                 }
 191                 kfree_s(openp, sizeof(struct open_dev));
 192                 openp = nextp;
 193         }
 194 }
 195 
 196 
 197 /*
 198  *      Receive RARP packets.
 199  */
 200  
 201 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203         struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 204         unsigned char *rarp_ptr = (unsigned char *)(rarp+1);
 205         unsigned long sip, tip;
 206         unsigned char *sha, *tha;               /* s for "source", t for "target" */
 207   
 208         /*
 209          *      If this test doesn't pass, its not IP, or we should ignore it anyway 
 210          */
 211          
 212         if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) 
 213         {
 214                 kfree_skb(skb, FREE_READ);
 215                 return 0;
 216         }
 217 
 218         /*
 219          *      If it's not a RARP reply, delete it. 
 220          */
 221          
 222         if (rarp->ar_op != htons(ARPOP_RREPLY)) 
 223         {
 224                 kfree_skb(skb, FREE_READ);
 225                 return 0;
 226         }
 227 
 228         /*
 229          *      If it's not ethernet or AX25, delete it. 
 230          */
 231          
 232         if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) || 
 233 #ifdef CONFIG_AX25
 234                 (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 235 #endif
 236                 rarp->ar_pln != 4) 
 237         {
 238                 kfree_skb(skb, FREE_READ);
 239                 return 0;
 240         }
 241   
 242         /*
 243          *      Extract variable width fields 
 244          */
 245          
 246         sha = rarp_ptr;
 247         rarp_ptr += dev->addr_len;
 248         memcpy(&sip, rarp_ptr, 4);
 249         rarp_ptr += 4;
 250         tha = rarp_ptr;
 251         rarp_ptr += dev->addr_len;
 252         memcpy(&tip, rarp_ptr, 4);
 253 
 254         /*
 255          *      Discard packets which are not meant for us. 
 256          */
 257          
 258         if (memcmp(tha, dev->dev_addr, dev->addr_len)) 
 259         {
 260                 kfree_skb(skb, FREE_READ);
 261                 return 0;
 262         }
 263 
 264         /*
 265          *      The packet is what we were looking for. Setup the global variables. 
 266          */
 267 
 268         cli();
 269         if (root_dev != NULL) 
 270         {
 271                 sti();
 272                 kfree_skb(skb, FREE_READ);
 273                 return 0;
 274         }
 275         root_dev = dev;
 276         sti();
 277 
 278         myaddr.sin_family = dev->family;
 279         myaddr.sin_addr.s_addr = tip;
 280         server.sin_family = dev->family;
 281         if (!server.sin_addr.s_addr)
 282                 server.sin_addr.s_addr = sip;
 283 
 284         kfree_skb(skb, FREE_READ);
 285         return 0;
 286 }
 287 
 288 
 289 /*
 290  *      Send RARP request packet over all devices which allow RARP.
 291  */
 292 
 293 static void root_rarp_send(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295         struct open_dev *openp;
 296         struct device *dev;
 297 
 298 #ifdef NFSROOT_DEBUG
 299         printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 300 #endif
 301 
 302         for (openp = open_base; openp != NULL; openp = openp->next) 
 303         {
 304                 dev = openp->dev;
 305                 arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 306                         dev->dev_addr, dev->dev_addr);
 307         }
 308 }
 309 
 310 
 311 /*
 312  *      Determine client and server IP numbers and appropriate device by using
 313  *      the RARP protocol.
 314  */
 315 
 316 static int do_rarp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 317 {
 318         int retries = 0;
 319         unsigned long timeout;
 320 
 321         /* 
 322          *      Open all devices and setup RARP protocol 
 323          */
 324          
 325         if (!root_rarp_open()) 
 326         {
 327                 printk(KERN_ERR "NFS: No network device found to send RARP request to\n");
 328                 return -1;
 329         }
 330 
 331         /*
 332          *      Send RARP request and wait, until we get an answer. This loop seems
 333          *      to be a terrible waste of cpu time, but actually there is no process
 334          *      running at all, so we don't need to use any scheduler functions.
 335          *      [Actually we could now, but the nothing else running note still 
 336          *       applies.. - AC]
 337          */
 338 
 339         for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) 
 340         {
 341                 root_rarp_send();
 342                 timeout = jiffies + (RARP_TIMEOUT * HZ);
 343                 while (jiffies < timeout && root_dev == NULL)
 344                         ;;
 345         }
 346 
 347         if (root_dev == NULL) 
 348         {
 349                 printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
 350                 return -1;
 351         }
 352 
 353         root_rarp_close();
 354 
 355         printk(KERN_NOTICE "NFS: ");
 356         printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
 357         printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 358 
 359         return 0;
 360 }
 361 
 362 
 363 
 364 
 365 /***************************************************************************
 366 
 367                         Routines to setup NFS
 368 
 369  ***************************************************************************/
 370 
 371 extern void ip_rt_add(short flags, unsigned long addr, unsigned long mask,
 372                         unsigned long gw, struct device *dev,
 373                         unsigned short mss, unsigned long window);
 374 
 375 
 376 /*
 377  *      The following integer options are recognized
 378  */
 379  
 380 static struct nfs_int_opts
 381 {
 382         char *name;
 383         int  *val;
 384 } root_int_opts[] = {
 385         { "port",       &nfs_port },
 386         { "rsize",      &nfs_data.rsize },
 387         { "wsize",      &nfs_data.wsize },
 388         { "timeo",      &nfs_data.timeo },
 389         { "retrans",    &nfs_data.retrans },
 390         { "acregmin",   &nfs_data.acregmin },
 391         { "acregmax",   &nfs_data.acregmax },
 392         { "acdirmin",   &nfs_data.acdirmin },
 393         { "acdirmax",   &nfs_data.acdirmax },
 394         { NULL,         NULL }};
 395 
 396 
 397 /*
 398  *      And now the flag options 
 399  */
 400  
 401 static struct nfs_bool_opts
 402 {
 403         char *name;
 404         int  and_mask;
 405         int  or_mask;
 406 } root_bool_opts[] = {
 407         { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
 408         { "hard",       ~NFS_MOUNT_SOFT,        0 },
 409         { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
 410         { "nointr",     ~NFS_MOUNT_INTR,        0 },
 411         { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
 412         { "noposix",    ~NFS_MOUNT_POSIX,       0 },
 413         { "cto",        ~NFS_MOUNT_NOCTO,       0 },
 414         { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
 415         { "ac",         ~NFS_MOUNT_NOAC,        0 },
 416         { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
 417         { NULL,         0,                      0 }
 418 };
 419 
 420 
 421 static unsigned long nfs_get_address (char **str)
     /* [previous][next][first][last][top][bottom][index][help] */
 422 {
 423         unsigned long l;
 424         unsigned int val;
 425         int i;
 426    
 427         l = 0;
 428         for (i = 0; i < 4; i++) 
 429         {
 430                 l <<= 8;
 431                 if (**str != '\0')
 432                 {
 433                         val = 0;
 434                         while (**str != '\0' && **str != '.' && **str != ':')
 435                         {
 436                                 val *= 10;
 437                                 val += **str - '0';
 438                                 (*str)++;
 439                         }
 440                         l |= val;
 441                         if (**str != '\0') 
 442                                 (*str)++;
 443                 }
 444         }
 445         return(htonl(l));
 446 }
 447 
 448 /*
 449  *      Prepare the NFS data structure and parse any options
 450  */
 451  
 452 static int root_nfs_parse(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454         char buf[NFS_MAXPATHLEN];
 455         char *cp, *options, *val;
 456 
 457         /*
 458          *      Get the host ip number 
 459          */
 460          
 461         if (*name >= '0' && *name <= '9')
 462         {
 463                 server.sin_addr.s_addr = nfs_get_address (&name);
 464         }
 465 
 466         /*
 467          *      Setup the server hostname 
 468          */
 469          
 470         cp = in_ntoa(server.sin_addr.s_addr);
 471         strncpy(nfs_data.hostname, cp, 255);
 472         nfs_data.addr = server;
 473 
 474         /*
 475          *      Set the name of the directory to mount 
 476          */
 477          
 478         cp = in_ntoa(myaddr.sin_addr.s_addr);
 479         strncpy(buf, name, 255);
 480         if ((options = strchr(buf, ',')))
 481                 *options++ = '\0';
 482         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) 
 483         {
 484                 printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
 485                 return -1;
 486         }
 487         sprintf(nfs_path, buf, cp);
 488 
 489         /*
 490          *      Set some default values 
 491          */
 492          
 493         nfs_port          = -1;
 494         nfs_data.version  = NFS_MOUNT_VERSION;
 495         nfs_data.flags    = 0;
 496         nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 497         nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 498         nfs_data.timeo    = 7;
 499         nfs_data.retrans  = 3;
 500         nfs_data.acregmin = 3;
 501         nfs_data.acregmax = 60;
 502         nfs_data.acdirmin = 30;
 503         nfs_data.acdirmax = 60;
 504 
 505         /*
 506          *      Process any options
 507          */
 508 
 509         if (options) 
 510         {
 511                 cp = strtok(options, ",");
 512                 while (cp) 
 513                 {
 514                         if ((val = strchr(cp, '='))) 
 515                         {
 516                                 struct nfs_int_opts *opts = root_int_opts;
 517                                 *val++ = '\0';
 518                                 while (opts->name && strcmp(opts->name, cp))
 519                                         opts++;
 520                                 if (opts->name)
 521                                         *(opts->val) = (int) simple_strtoul(val, NULL, 10);
 522                         }
 523                         else
 524                         {
 525                                 struct nfs_bool_opts *opts = root_bool_opts;
 526                                 while (opts->name && strcmp(opts->name, cp))
 527                                         opts++;
 528                                 if (opts->name) 
 529                                 {
 530                                         nfs_data.flags &= opts->and_mask;
 531                                         nfs_data.flags |= opts->or_mask;
 532                                 }
 533                         }
 534                         cp = strtok(NULL, ",");
 535                 }
 536         }
 537         return 0;
 538 }
 539 
 540 
 541 /*
 542  *      Tell the user what's going on.
 543  */
 544 
 545 static void root_nfs_print(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 546 {
 547 #ifdef NFSROOT_DEBUG
 548         printk(KERN_NOTICE "NFS: Mounting %s on server %s as root\n",
 549                 nfs_path, nfs_data.hostname);
 550         printk(KERN_NOTICE "NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
 551                 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
 552         printk(KERN_NOTICE "NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
 553                 nfs_data.acregmin, nfs_data.acregmax,
 554                 nfs_data.acdirmin, nfs_data.acdirmax);
 555         printk(KERN_NOTICE "NFS:     port = %d, flags = %08x\n",
 556                 nfs_port, nfs_data.flags);
 557 #endif
 558 }
 559 
 560 
 561 /*
 562  * Set the interface address and configure a route to the server.
 563  */
 564 static void root_nfs_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 565 {
 566         struct rtentry server_route;
 567         struct sockaddr_in *sin;
 568 
 569         /* 
 570          *      Setup the device correctly
 571          */
 572          
 573         root_dev->family     = myaddr.sin_family;
 574         root_dev->pa_addr    = myaddr.sin_addr.s_addr;
 575         root_dev->pa_mask    = ip_get_mask(myaddr.sin_addr.s_addr);
 576         root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
 577         root_dev->pa_dstaddr = 0;
 578 
 579         sin=(struct sockaddr_in *)&server_route.rt_dst;
 580         *sin=server;
 581         sin=(struct sockaddr_in *)&server_route.rt_genmask;
 582         sin->sin_family=AF_INET;
 583         sin->sin_addr.s_addr= root_dev->pa_mask;
 584         server_route.rt_dev=NULL;
 585         server_route.rt_flags=RTF_HOST|RTF_UP;
 586   
 587         /*
 588          *      Now add a route to the server
 589          */
 590  
 591         if(ip_rt_new(&server_route)==-1)
 592                 printk("Unable to add NFS server route.\n");
 593 }
 594 
 595 
 596 /*
 597  *      Get the necessary IP addresses and prepare for mounting the required
 598  *      NFS filesystem.
 599  */
 600 
 601 int nfs_root_init(char *nfsname)
     /* [previous][next][first][last][top][bottom][index][help] */
 602 {
 603         /*
 604          *      Initialize network device and get local and server IP address 
 605          */
 606 
 607         if (do_rarp() < 0)
 608                 return -1;
 609 
 610         /*
 611          *      Initialize the global variables necessary for NFS. The server
 612          *      directory is actually mounted after init() has been started.
 613          */
 614 
 615         if (root_nfs_parse(nfsname) < 0)
 616                 return -1;
 617         root_nfs_print();
 618         root_nfs_setup();
 619         return 0;
 620 }
 621 
 622 /***************************************************************************
 623 
 624                 Routines to actually mount the root directory
 625 
 626  ***************************************************************************/
 627 
 628 static struct file nfs_file;            /* File descriptor containing socket */
 629 static struct inode nfs_inode;          /* Inode containing socket */
 630 static int *rpc_packet = NULL;          /* RPC packet */
 631 
 632 extern asmlinkage int sys_socketcall(int call, unsigned long *args);
 633 extern struct socket *socki_lookup(struct inode *inode);
 634 
 635 
 636 /*
 637  *      Open a UDP socket.
 638  */
 639 
 640 static int root_nfs_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 641 {
 642         struct file *filp;
 643         unsigned long opt[] = { AF_INET, SOCK_DGRAM, IPPROTO_UDP };
 644 
 645         /*
 646          *      Open the socket 
 647          */
 648 
 649         if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) 
 650         {
 651                 printk(KERN_ERR "NFS: Cannot open UDP socket\n");
 652                 return -1;
 653         }
 654 
 655         /*      
 656          *      Copy the file and inode data area so that we can remove the
 657          *      file lateron without killing the socket. After all this the
 658          *      closing routine just needs to remove the file pointer from
 659          *      the init-task descriptor.
 660          */
 661 
 662         filp = current->files->fd[nfs_data.fd];
 663         memcpy(&nfs_file, filp, sizeof(struct file));
 664         nfs_file.f_next = nfs_file.f_prev = NULL;
 665         current->files->fd[nfs_data.fd] = &nfs_file;
 666         filp->f_count = 0;              /* Free the file descriptor */
 667 
 668         memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
 669         nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
 670         nfs_inode.i_next = nfs_inode.i_prev = NULL;
 671         clear_inode(nfs_file.f_inode);
 672         nfs_file.f_inode = &nfs_inode;
 673         nfs_inode.u.socket_i.inode = &nfs_inode;
 674         nfs_file.private_data = NULL;
 675 
 676         return 0;
 677 }
 678 
 679 
 680 /*
 681  *      Close the UDP file descriptor. The main part of preserving the socket
 682  *      has already been done after opening it. Now we have to remove the
 683  *      file descriptor from the init task.
 684  */
 685 
 686 static void root_nfs_close(int close_all)
     /* [previous][next][first][last][top][bottom][index][help] */
 687 {
 688         /*
 689          *      Remove the file from the list of open files 
 690          */
 691 
 692         current->files->fd[nfs_data.fd] = NULL;
 693         if (current->files->count > 0)
 694                 current->files->count--;
 695 
 696         /*
 697          *      Clear memory use by the RPC packet 
 698          */
 699          
 700         if (rpc_packet != NULL)
 701                 kfree_s(rpc_packet, nfs_data.wsize + 1024);
 702 
 703         /*
 704          *      In case of an error we also have to close the socket again (sigh)
 705          */
 706          
 707         if (close_all) 
 708         {
 709                 nfs_inode.u.socket_i.inode = NULL;      /* The inode is already cleared */
 710                 if (nfs_file.f_op->release)
 711                         nfs_file.f_op->release(&nfs_inode, &nfs_file);
 712         }
 713 }
 714 
 715 
 716 /*
 717  *      Find a suitable listening port and bind to it
 718  */
 719 
 720 static int root_nfs_bind(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 721 {
 722         int res = -1;
 723         short port = STARTPORT;
 724         struct sockaddr_in *sin = &myaddr;
 725         int i;
 726 
 727         if (nfs_inode.u.socket_i.ops->bind) 
 728         {
 729                 for (i = 0; i < NPORTS && res < 0; i++) 
 730                 {
 731                         sin->sin_port = htons(port++);
 732                         if (port > ENDPORT) 
 733                         {
 734                                 port = STARTPORT;
 735                         }
 736                         res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
 737                                 (struct sockaddr *) sin, sizeof(struct sockaddr_in));
 738                 }
 739         }
 740         if (res < 0) 
 741         {
 742                 printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
 743                 root_nfs_close(1);
 744                 return -1;
 745         }
 746 #ifdef NFSROOT_DEBUG
 747         printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
 748 #endif
 749         return 0;
 750 }
 751 
 752 
 753 /*
 754  *      Send an RPC request and wait for the answer
 755  */
 756 
 757 static int *root_nfs_call(int *end)
     /* [previous][next][first][last][top][bottom][index][help] */
 758 {
 759         struct file *filp;
 760         struct socket *sock;
 761         int dummylen;
 762         static struct nfs_server s = {
 763                 &nfs_file, /* struct file * */
 764                 0,         /* struct rsock * */
 765                 {
 766                         0, "",
 767                 },         /* toaddr */
 768                 0,         /* lock */
 769                 NULL,      /* wait queue */
 770                 NFS_MOUNT_SOFT, /* flags - this seems a ___BAD___ default - AC */
 771                 0, 0,           /* rsize, wsize */
 772                 0,              /* timeo */
 773                 0,              /* retrans */
 774                 3*HZ, 60*HZ, 30*HZ, 60*HZ, "\0" 
 775         };
 776 
 777         filp = &nfs_file;
 778         sock = &((filp->f_inode)->u.socket_i);
 779     
 780         /*
 781          *      extract the other end of the socket into server->toaddr 
 782          */
 783          
 784         sock->ops->getname(sock, &(s.toaddr), &dummylen, 1) ;
 785         ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
 786         ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
 787         ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
 788   
 789         s.rsock = rpc_makesock(filp);
 790         s.flags = nfs_data.flags;
 791         s.rsize = nfs_data.rsize;
 792         s.wsize = nfs_data.wsize;
 793         s.timeo = nfs_data.timeo * HZ / 10;
 794         s.retrans = nfs_data.retrans;
 795         strcpy(s.hostname, nfs_data.hostname);
 796 
 797         /*
 798          *      First connect the UDP socket to a server port, then send the packet
 799          *      out, and finally check wether the answer is OK.
 800          */
 801          
 802         if (nfs_inode.u.socket_i.ops->connect &&
 803                 nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 804                 (struct sockaddr *) &server, sizeof(struct sockaddr_in),
 805                 nfs_file.f_flags) < 0)
 806         {
 807                 return NULL;
 808         }
 809 
 810         if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
 811                 return NULL;
 812         return rpc_verify(rpc_packet);
 813 }
 814 
 815 
 816 /*
 817  *      Create an RPC packet header
 818  */
 819  
 820 static int *root_nfs_header(int proc, int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 821 {
 822         int groups[] = { 0, NOGROUP };
 823 
 824         if (rpc_packet == NULL) 
 825         {
 826                 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) 
 827                 {
 828                         printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
 829                         return NULL;
 830                 }
 831         }
 832         strcpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr));
 833         return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 834 }
 835 
 836 
 837 /*
 838  *      Query server portmapper for the port of a daemon program
 839  */
 840 
 841 static int root_nfs_get_port(int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 842 {
 843         int *p;
 844 
 845         /*
 846          *      Prepare header for portmap request
 847          */
 848          
 849         server.sin_port = htons(NFS_PMAP_PORT);
 850         p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
 851         if (!p)
 852                 return -1;
 853 
 854         /*
 855          *      Set arguments for portmapper
 856          */
 857          
 858         *p++ = htonl(program);
 859         *p++ = htonl(version);
 860         *p++ = htonl(IPPROTO_UDP);
 861         *p++ = 0;
 862 
 863         /*
 864          *      Send request to server portmapper
 865          */
 866          
 867         if ((p = root_nfs_call(p)) == NULL)
 868                 return -1;
 869 
 870         return ntohl(*p);
 871 }
 872 
 873 
 874 /*
 875  *      Get portnumbers for mountd and nfsd from server
 876  */
 877  
 878 static int root_nfs_ports(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 879 {
 880         int port;
 881 
 882         if (nfs_port < 0) 
 883         {
 884                 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) 
 885                 {
 886                         printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
 887                         port = NFS_NFS_PORT;
 888                 }
 889                 nfs_port = port;
 890 #ifdef NFSROOT_DEBUG
 891                 printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 892 #endif
 893         }
 894 
 895         if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) 
 896         {
 897                 printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
 898                 port = NFS_MOUNT_PORT;
 899         }
 900         server.sin_port = htons(port);
 901 #ifdef NFSROOT_DEBUG
 902         printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 903 #endif
 904         return 0;
 905 }
 906 
 907 
 908 /*
 909  *      Get a file handle from the server for the directory which is to be mounted
 910  */
 911  
 912 static int root_nfs_get_handle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914         int len, status, *p;
 915 
 916         /*
 917          *      Prepare header for mountd request 
 918          */
 919          
 920         p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
 921         if (!p) 
 922         {
 923                 root_nfs_close(1);
 924                 return -1;
 925         }
 926 
 927         /*
 928          *      Set arguments for mountd
 929          */
 930 
 931         len = strlen(nfs_path);
 932         *p++ = htonl(len);
 933         memcpy(p, nfs_path, len);
 934         len = (len + 3) >> 2;
 935         p[len] = 0;
 936         p += len;
 937 
 938         /*
 939          *      Send request to server portmapper 
 940          */
 941 
 942         if ((p = root_nfs_call(p)) == NULL)
 943         {
 944                 root_nfs_close(1);
 945                 return -1;
 946         }
 947 
 948         status = ntohl(*p++);
 949         if (status == 0) 
 950         {
 951                 nfs_data.root = *((struct nfs_fh *) p);
 952         } 
 953         else
 954         {
 955                 printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
 956                         status, nfs_path);
 957                 root_nfs_close(1);
 958                 return -1;
 959         }
 960         return 0;
 961 }
 962 
 963 
 964 /*
 965  *      Now actually mount the given directory
 966  */
 967 
 968 static int root_nfs_do_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 969 {
 970         /*
 971          *      First connect to the nfsd port on the server 
 972          */
 973 
 974         server.sin_port = htons(nfs_port);
 975         nfs_data.addr = server;
 976         if (nfs_inode.u.socket_i.ops->connect &&
 977                 nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 978                 (struct sockaddr *) &server, sizeof(struct sockaddr_in),
 979                 nfs_file.f_flags) < 0) 
 980         {
 981                 root_nfs_close(1);
 982                 return -1;
 983         }
 984 
 985         /*
 986          *      Now (finally ;-)) read the super block for mounting
 987          */
 988 
 989         if (nfs_read_super(sb, &nfs_data, 1) == NULL) 
 990         {
 991                 root_nfs_close(1);
 992                 return -1;
 993         }
 994 
 995         return 0;
 996 }
 997 
 998 
 999 /*
1000  *      Get the NFS port numbers and file handle, and then read the super-
1001  *      block for mounting.
1002  */
1003 
1004 int nfs_root_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
1005 {
1006         if (root_nfs_open() < 0)
1007                 return -1;
1008         if (root_nfs_bind() < 0)
1009                 return -1;
1010         if (root_nfs_ports() < 0)
1011                 return -1;
1012         if (root_nfs_get_handle() < 0)
1013                 return -1;
1014         if (root_nfs_do_mount(sb) < 0)
1015                 return -1;
1016         root_nfs_close(0);
1017         return 0;
1018 }

/* [previous][next][first][last][top][bottom][index][help] */