diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-09-08 19:50:03 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-09-08 19:50:03 -0400 |
commit | 764302ccb88dd0df062eccd507b6c6de24f1c560 (patch) | |
tree | 00f9f1e80c07495e6649eccb17faf7b3d4f2a25a /fs/nfs | |
parent | a6fe23be90aa78783523a25330e09bfaa43a1581 (diff) |
NFS: Allow the "nfs" file system type to support NFSv4
When mounting an "nfs" type file system, recognize "v4," "vers=4," or
"nfsvers=4" mount options, and convert the file system to "nfs4" under
the covers.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[trondmy: fixed up binary mount code so it sets the 'version' field too]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/internal.h | 1 | ||||
-rw-r--r-- | fs/nfs/super.c | 48 |
2 files changed, 47 insertions, 2 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 5e686a4d744e..e21b1bb9972f 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -68,6 +68,7 @@ struct nfs_parsed_mount_data { | |||
68 | unsigned int auth_flavor_len; | 68 | unsigned int auth_flavor_len; |
69 | rpc_authflavor_t auth_flavors[1]; | 69 | rpc_authflavor_t auth_flavors[1]; |
70 | char *client_address; | 70 | char *client_address; |
71 | unsigned int version; | ||
71 | unsigned int minorversion; | 72 | unsigned int minorversion; |
72 | char *fscache_uniq; | 73 | char *fscache_uniq; |
73 | 74 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c105e12197c2..34b1ccf51adf 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -73,7 +73,7 @@ enum { | |||
73 | Opt_cto, Opt_nocto, | 73 | Opt_cto, Opt_nocto, |
74 | Opt_ac, Opt_noac, | 74 | Opt_ac, Opt_noac, |
75 | Opt_lock, Opt_nolock, | 75 | Opt_lock, Opt_nolock, |
76 | Opt_v2, Opt_v3, | 76 | Opt_v2, Opt_v3, Opt_v4, |
77 | Opt_udp, Opt_tcp, Opt_rdma, | 77 | Opt_udp, Opt_tcp, Opt_rdma, |
78 | Opt_acl, Opt_noacl, | 78 | Opt_acl, Opt_noacl, |
79 | Opt_rdirplus, Opt_nordirplus, | 79 | Opt_rdirplus, Opt_nordirplus, |
@@ -127,6 +127,7 @@ static const match_table_t nfs_mount_option_tokens = { | |||
127 | { Opt_nolock, "nolock" }, | 127 | { Opt_nolock, "nolock" }, |
128 | { Opt_v2, "v2" }, | 128 | { Opt_v2, "v2" }, |
129 | { Opt_v3, "v3" }, | 129 | { Opt_v3, "v3" }, |
130 | { Opt_v4, "v4" }, | ||
130 | { Opt_udp, "udp" }, | 131 | { Opt_udp, "udp" }, |
131 | { Opt_tcp, "tcp" }, | 132 | { Opt_tcp, "tcp" }, |
132 | { Opt_rdma, "rdma" }, | 133 | { Opt_rdma, "rdma" }, |
@@ -934,10 +935,18 @@ static int nfs_parse_mount_options(char *raw, | |||
934 | break; | 935 | break; |
935 | case Opt_v2: | 936 | case Opt_v2: |
936 | mnt->flags &= ~NFS_MOUNT_VER3; | 937 | mnt->flags &= ~NFS_MOUNT_VER3; |
938 | mnt->version = 2; | ||
937 | break; | 939 | break; |
938 | case Opt_v3: | 940 | case Opt_v3: |
939 | mnt->flags |= NFS_MOUNT_VER3; | 941 | mnt->flags |= NFS_MOUNT_VER3; |
942 | mnt->version = 3; | ||
940 | break; | 943 | break; |
944 | #ifdef CONFIG_NFS_V4 | ||
945 | case Opt_v4: | ||
946 | mnt->flags &= ~NFS_MOUNT_VER3; | ||
947 | mnt->version = 4; | ||
948 | break; | ||
949 | #endif | ||
941 | case Opt_udp: | 950 | case Opt_udp: |
942 | mnt->flags &= ~NFS_MOUNT_TCP; | 951 | mnt->flags &= ~NFS_MOUNT_TCP; |
943 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 952 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
@@ -1151,10 +1160,18 @@ static int nfs_parse_mount_options(char *raw, | |||
1151 | switch (option) { | 1160 | switch (option) { |
1152 | case NFS2_VERSION: | 1161 | case NFS2_VERSION: |
1153 | mnt->flags &= ~NFS_MOUNT_VER3; | 1162 | mnt->flags &= ~NFS_MOUNT_VER3; |
1163 | mnt->version = 2; | ||
1154 | break; | 1164 | break; |
1155 | case NFS3_VERSION: | 1165 | case NFS3_VERSION: |
1156 | mnt->flags |= NFS_MOUNT_VER3; | 1166 | mnt->flags |= NFS_MOUNT_VER3; |
1167 | mnt->version = 3; | ||
1168 | break; | ||
1169 | #ifdef CONFIG_NFS_V4 | ||
1170 | case NFS4_VERSION: | ||
1171 | mnt->flags &= ~NFS_MOUNT_VER3; | ||
1172 | mnt->version = 4; | ||
1157 | break; | 1173 | break; |
1174 | #endif | ||
1158 | default: | 1175 | default: |
1159 | goto out_invalid_value; | 1176 | goto out_invalid_value; |
1160 | } | 1177 | } |
@@ -1629,6 +1646,7 @@ static int nfs_validate_mount_data(void *options, | |||
1629 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1646 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
1630 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 1647 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
1631 | args->auth_flavor_len = 1; | 1648 | args->auth_flavor_len = 1; |
1649 | args->minorversion = 0; | ||
1632 | 1650 | ||
1633 | switch (data->version) { | 1651 | switch (data->version) { |
1634 | case 1: | 1652 | case 1: |
@@ -1650,8 +1668,11 @@ static int nfs_validate_mount_data(void *options, | |||
1650 | if (data->root.size > NFS3_FHSIZE || data->root.size == 0) | 1668 | if (data->root.size > NFS3_FHSIZE || data->root.size == 0) |
1651 | goto out_invalid_fh; | 1669 | goto out_invalid_fh; |
1652 | mntfh->size = data->root.size; | 1670 | mntfh->size = data->root.size; |
1653 | } else | 1671 | args->version = 3; |
1672 | } else { | ||
1654 | mntfh->size = NFS2_FHSIZE; | 1673 | mntfh->size = NFS2_FHSIZE; |
1674 | args->version = 2; | ||
1675 | } | ||
1655 | 1676 | ||
1656 | 1677 | ||
1657 | memcpy(mntfh->data, data->root.data, mntfh->size); | 1678 | memcpy(mntfh->data, data->root.data, mntfh->size); |
@@ -1726,6 +1747,14 @@ static int nfs_validate_mount_data(void *options, | |||
1726 | if (!nfs_verify_server_address(sap)) | 1747 | if (!nfs_verify_server_address(sap)) |
1727 | goto out_no_address; | 1748 | goto out_no_address; |
1728 | 1749 | ||
1750 | if (args->version == 4) | ||
1751 | #ifdef CONFIG_NFS_V4 | ||
1752 | return nfs4_validate_text_mount_data(options, | ||
1753 | args, dev_name); | ||
1754 | #else | ||
1755 | goto out_v4_not_compiled; | ||
1756 | #endif | ||
1757 | |||
1729 | nfs_set_default_port(sap, args->nfs_server.port, 0); | 1758 | nfs_set_default_port(sap, args->nfs_server.port, 0); |
1730 | 1759 | ||
1731 | nfs_set_mount_transport_protocol(args); | 1760 | nfs_set_mount_transport_protocol(args); |
@@ -1774,6 +1803,12 @@ out_v3_not_compiled: | |||
1774 | return -EPROTONOSUPPORT; | 1803 | return -EPROTONOSUPPORT; |
1775 | #endif /* !CONFIG_NFS_V3 */ | 1804 | #endif /* !CONFIG_NFS_V3 */ |
1776 | 1805 | ||
1806 | #ifndef CONFIG_NFS_V4 | ||
1807 | out_v4_not_compiled: | ||
1808 | dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); | ||
1809 | return -EPROTONOSUPPORT; | ||
1810 | #endif /* !CONFIG_NFS_V4 */ | ||
1811 | |||
1777 | out_nomem: | 1812 | out_nomem: |
1778 | dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); | 1813 | dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); |
1779 | return -ENOMEM; | 1814 | return -ENOMEM; |
@@ -2069,6 +2104,14 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2069 | if (error < 0) | 2104 | if (error < 0) |
2070 | goto out; | 2105 | goto out; |
2071 | 2106 | ||
2107 | #ifdef CONFIG_NFS_V4 | ||
2108 | if (data->version == 4) { | ||
2109 | error = nfs4_try_mount(flags, dev_name, data, mnt); | ||
2110 | kfree(data->client_address); | ||
2111 | goto out; | ||
2112 | } | ||
2113 | #endif /* CONFIG_NFS_V4 */ | ||
2114 | |||
2072 | /* Get a volume representation */ | 2115 | /* Get a volume representation */ |
2073 | server = nfs_create_server(data, mntfh); | 2116 | server = nfs_create_server(data, mntfh); |
2074 | if (IS_ERR(server)) { | 2117 | if (IS_ERR(server)) { |
@@ -2320,6 +2363,7 @@ static int nfs4_validate_mount_data(void *options, | |||
2320 | args->nfs_server.port = NFS_UNSPEC_PORT; | 2363 | args->nfs_server.port = NFS_UNSPEC_PORT; |
2321 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 2364 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
2322 | args->auth_flavor_len = 1; | 2365 | args->auth_flavor_len = 1; |
2366 | args->version = 4; | ||
2323 | args->minorversion = 0; | 2367 | args->minorversion = 0; |
2324 | 2368 | ||
2325 | switch (data->version) { | 2369 | switch (data->version) { |