NFS: Add new 'mountaddr=' mount option
[cascardo/linux.git] / fs / nfs / super.c
index 4613900..a955821 100644 (file)
@@ -73,6 +73,7 @@ struct nfs_parsed_mount_data {
 
        struct {
                struct sockaddr_in      address;
+               char                    *hostname;
                unsigned int            program;
                unsigned int            version;
                unsigned short          port;
@@ -116,7 +117,7 @@ enum {
 
        /* Mount options that take string arguments */
        Opt_sec, Opt_proto, Opt_mountproto,
-       Opt_addr, Opt_mounthost, Opt_clientaddr,
+       Opt_addr, Opt_mountaddr, Opt_clientaddr,
 
        /* Mount options that are ignored */
        Opt_userspace, Opt_deprecated,
@@ -175,7 +176,8 @@ static match_table_t nfs_mount_option_tokens = {
        { Opt_mountproto, "mountproto=%s" },
        { Opt_addr, "addr=%s" },
        { Opt_clientaddr, "clientaddr=%s" },
-       { Opt_mounthost, "mounthost=%s" },
+       { Opt_userspace, "mounthost=%s" },
+       { Opt_mountaddr, "mountaddr=%s" },
 
        { Opt_err, NULL }
 };
@@ -345,8 +347,8 @@ void __exit unregister_nfs_fs(void)
        unregister_shrinker(&acl_shrinker);
 #ifdef CONFIG_NFS_V4
        unregister_filesystem(&nfs4_fs_type);
-       nfs_unregister_sysctl();
 #endif
+       nfs_unregister_sysctl();
        unregister_filesystem(&nfs_fs_type);
 }
 
@@ -506,8 +508,8 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
 
        nfs_show_mount_options(m, nfss, 0);
 
-       seq_puts(m, ",addr=");
-       seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\");
+       seq_printf(m, ",addr="NIPQUAD_FMT,
+               NIPQUAD(nfss->nfs_client->cl_addr.sin_addr));
 
        return 0;
 }
@@ -911,13 +913,13 @@ static int nfs_parse_mount_options(char *raw,
                        kfree(string);
 
                        switch (token) {
-                       case Opt_udp:
+                       case Opt_xprt_udp:
                                mnt->flags &= ~NFS_MOUNT_TCP;
                                mnt->nfs_server.protocol = IPPROTO_UDP;
                                mnt->timeo = 7;
                                mnt->retrans = 5;
                                break;
-                       case Opt_tcp:
+                       case Opt_xprt_tcp:
                                mnt->flags |= NFS_MOUNT_TCP;
                                mnt->nfs_server.protocol = IPPROTO_TCP;
                                mnt->timeo = 600;
@@ -936,10 +938,10 @@ static int nfs_parse_mount_options(char *raw,
                        kfree(string);
 
                        switch (token) {
-                       case Opt_udp:
+                       case Opt_xprt_udp:
                                mnt->mount_server.protocol = IPPROTO_UDP;
                                break;
-                       case Opt_tcp:
+                       case Opt_xprt_tcp:
                                mnt->mount_server.protocol = IPPROTO_TCP;
                                break;
                        default:
@@ -961,7 +963,7 @@ static int nfs_parse_mount_options(char *raw,
                                goto out_nomem;
                        mnt->client_address = string;
                        break;
-               case Opt_mounthost:
+               case Opt_mountaddr:
                        string = match_strdup(args);
                        if (string == NULL)
                                goto out_nomem;
@@ -1027,16 +1029,10 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
                sin = args->mount_server.address;
        else
                sin = args->nfs_server.address;
-       if (args->mount_server.port == 0) {
-               status = rpcb_getport_sync(&sin,
-                                          args->mount_server.program,
-                                          args->mount_server.version,
-                                          args->mount_server.protocol);
-               if (status < 0)
-                       goto out_err;
-               sin.sin_port = htons(status);
-       } else
-               sin.sin_port = htons(args->mount_server.port);
+       /*
+        * autobind will be used if mount_server.port == 0
+        */
+       sin.sin_port = htons(args->mount_server.port);
 
        /*
         * Now ask the mount server to map our export path
@@ -1049,14 +1045,11 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
                           args->mount_server.version,
                           args->mount_server.protocol,
                           root_fh);
-       if (status < 0)
-               goto out_err;
-
-       return status;
+       if (status == 0)
+               return 0;
 
-out_err:
-       dfprintk(MOUNT, "NFS: unable to contact server on host "
-                NIPQUAD_FMT "\n", NIPQUAD(sin.sin_addr.s_addr));
+       dfprintk(MOUNT, "NFS: unable to mount server " NIPQUAD_FMT
+                       ", error %d\n", NIPQUAD(sin.sin_addr.s_addr), status);
        return status;
 }
 
@@ -1153,20 +1146,20 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
                c = strchr(dev_name, ':');
                if (c == NULL)
                        return -EINVAL;
-               len = c - dev_name - 1;
+               len = c - dev_name;
                if (len > sizeof(data->hostname))
-                       return -EINVAL;
+                       return -ENAMETOOLONG;
                strncpy(data->hostname, dev_name, len);
                args.nfs_server.hostname = data->hostname;
 
                c++;
                if (strlen(c) > NFS_MAXPATHLEN)
-                       return -EINVAL;
+                       return -ENAMETOOLONG;
                args.nfs_server.export_path = c;
 
                status = nfs_try_mount(&args, mntfh);
                if (status)
-                       return -EINVAL;
+                       return status;
 
                /*
                 * Translate to nfs_mount_data, which nfs_fill_super
@@ -1677,7 +1670,7 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
                /* while calculating len, pretend ':' is '\0' */
                len = c - dev_name;
                if (len > NFS4_MAXNAMLEN)
-                       return -EINVAL;
+                       return -ENAMETOOLONG;
                *hostname = kzalloc(len, GFP_KERNEL);
                if (*hostname == NULL)
                        return -ENOMEM;
@@ -1686,7 +1679,7 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
                c++;                    /* step over the ':' */
                len = strlen(c);
                if (len > NFS4_MAXPATHLEN)
-                       return -EINVAL;
+                       return -ENAMETOOLONG;
                *mntpath = kzalloc(len + 1, GFP_KERNEL);
                if (*mntpath == NULL)
                        return -ENOMEM;