aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-12-10 14:59:28 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:05:57 -0500
commit4c5680177012a2b5c0f3fdf58f4375dd84a1da67 (patch)
treed3d9e599291b4f9b738d02c3913b13541b100487 /fs/nfs/super.c
parent9412b92772c1d80ea8284583b6aad0260e13515f (diff)
NFS: Support non-IPv4 addresses in nfs_parsed_mount_data
Replace the nfs_server and mount_server address fields in the nfs_parsed_mount_data structure with a "struct sockaddr_storage" instead of a "struct sockaddr_in". Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 041fe9e9b74d..7efc6a34b56b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -649,15 +649,18 @@ static int nfs_verify_server_address(struct sockaddr *addr)
649 * to punt the mount. 649 * to punt the mount.
650 */ 650 */
651static void nfs_parse_server_address(char *value, 651static void nfs_parse_server_address(char *value,
652 struct sockaddr *sap) 652 struct sockaddr *sap,
653 size_t *len)
653{ 654{
654 struct sockaddr_in *ap = (void *)sap; 655 struct sockaddr_in *ap = (void *)sap;
655 656
656 ap->sin_family = AF_INET; 657 ap->sin_family = AF_INET;
658 *len = sizeof(*ap);
657 if (in4_pton(value, -1, (u8 *)&ap->sin_addr.s_addr, '\0', NULL)) 659 if (in4_pton(value, -1, (u8 *)&ap->sin_addr.s_addr, '\0', NULL))
658 return; 660 return;
659 661
660 sap->sa_family = AF_UNSPEC; 662 sap->sa_family = AF_UNSPEC;
663 *len = 0;
661} 664}
662 665
663/* 666/*
@@ -984,7 +987,8 @@ static int nfs_parse_mount_options(char *raw,
984 if (string == NULL) 987 if (string == NULL)
985 goto out_nomem; 988 goto out_nomem;
986 nfs_parse_server_address(string, (struct sockaddr *) 989 nfs_parse_server_address(string, (struct sockaddr *)
987 &mnt->nfs_server.address); 990 &mnt->nfs_server.address,
991 &mnt->nfs_server.addrlen);
988 kfree(string); 992 kfree(string);
989 break; 993 break;
990 case Opt_clientaddr: 994 case Opt_clientaddr:
@@ -1004,7 +1008,8 @@ static int nfs_parse_mount_options(char *raw,
1004 if (string == NULL) 1008 if (string == NULL)
1005 goto out_nomem; 1009 goto out_nomem;
1006 nfs_parse_server_address(string, (struct sockaddr *) 1010 nfs_parse_server_address(string, (struct sockaddr *)
1007 &mnt->mount_server.address); 1011 &mnt->mount_server.address,
1012 &mnt->mount_server.addrlen);
1008 kfree(string); 1013 kfree(string);
1009 break; 1014 break;
1010 1015
@@ -1049,9 +1054,9 @@ out_unknown:
1049static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1054static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1050 struct nfs_fh *root_fh) 1055 struct nfs_fh *root_fh)
1051{ 1056{
1052 struct sockaddr_in sin; 1057 struct sockaddr *sap = (struct sockaddr *)&args->mount_server.address;
1053 int status;
1054 char *hostname; 1058 char *hostname;
1059 int status;
1055 1060
1056 if (args->mount_server.version == 0) { 1061 if (args->mount_server.version == 0) {
1057 if (args->flags & NFS_MOUNT_VER3) 1062 if (args->flags & NFS_MOUNT_VER3)
@@ -1068,21 +1073,23 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1068 /* 1073 /*
1069 * Construct the mount server's address. 1074 * Construct the mount server's address.
1070 */ 1075 */
1071 if (args->mount_server.address.sin_addr.s_addr != INADDR_ANY) 1076 if (args->mount_server.address.ss_family == AF_UNSPEC) {
1072 sin = args->mount_server.address; 1077 memcpy(sap, &args->nfs_server.address,
1073 else 1078 args->nfs_server.addrlen);
1074 sin = args->nfs_server.address; 1079 args->mount_server.addrlen = args->nfs_server.addrlen;
1080 }
1081
1075 /* 1082 /*
1076 * autobind will be used if mount_server.port == 0 1083 * autobind will be used if mount_server.port == 0
1077 */ 1084 */
1078 nfs_set_port((struct sockaddr *)&sin, args->mount_server.port); 1085 nfs_set_port(sap, args->mount_server.port);
1079 1086
1080 /* 1087 /*
1081 * Now ask the mount server to map our export path 1088 * Now ask the mount server to map our export path
1082 * to a file handle. 1089 * to a file handle.
1083 */ 1090 */
1084 status = nfs_mount((struct sockaddr *) &sin, 1091 status = nfs_mount(sap,
1085 sizeof(sin), 1092 args->mount_server.addrlen,
1086 hostname, 1093 hostname,
1087 args->nfs_server.export_path, 1094 args->nfs_server.export_path,
1088 args->mount_server.version, 1095 args->mount_server.version,
@@ -1165,9 +1172,6 @@ static int nfs_validate_mount_data(void *options,
1165 memset(mntfh->data + mntfh->size, 0, 1172 memset(mntfh->data + mntfh->size, 0,
1166 sizeof(mntfh->data) - mntfh->size); 1173 sizeof(mntfh->data) - mntfh->size);
1167 1174
1168 if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
1169 goto out_no_address;
1170
1171 /* 1175 /*
1172 * Translate to nfs_parsed_mount_data, which nfs_fill_super 1176 * Translate to nfs_parsed_mount_data, which nfs_fill_super
1173 * can deal with. 1177 * can deal with.
@@ -1182,7 +1186,14 @@ static int nfs_validate_mount_data(void *options,
1182 args->acregmax = data->acregmax; 1186 args->acregmax = data->acregmax;
1183 args->acdirmin = data->acdirmin; 1187 args->acdirmin = data->acdirmin;
1184 args->acdirmax = data->acdirmax; 1188 args->acdirmax = data->acdirmax;
1185 args->nfs_server.address = data->addr; 1189
1190 memcpy(&args->nfs_server.address, &data->addr,
1191 sizeof(data->addr));
1192 args->nfs_server.addrlen = sizeof(data->addr);
1193 if (!nfs_verify_server_address((struct sockaddr *)
1194 &args->nfs_server.address))
1195 goto out_no_address;
1196
1186 if (!(data->flags & NFS_MOUNT_TCP)) 1197 if (!(data->flags & NFS_MOUNT_TCP))
1187 args->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1198 args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1188 /* N.B. caller will free nfs_server.hostname in all cases */ 1199 /* N.B. caller will free nfs_server.hostname in all cases */
@@ -1655,6 +1666,7 @@ static int nfs4_validate_mount_data(void *options,
1655 struct nfs_parsed_mount_data *args, 1666 struct nfs_parsed_mount_data *args,
1656 const char *dev_name) 1667 const char *dev_name)
1657{ 1668{
1669 struct sockaddr_in *ap;
1658 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; 1670 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
1659 char *c; 1671 char *c;
1660 1672
@@ -1675,11 +1687,13 @@ static int nfs4_validate_mount_data(void *options,
1675 1687
1676 switch (data->version) { 1688 switch (data->version) {
1677 case 1: 1689 case 1:
1678 if (data->host_addrlen != sizeof(args->nfs_server.address)) 1690 ap = (struct sockaddr_in *)&args->nfs_server.address;
1691 if (data->host_addrlen > sizeof(args->nfs_server.address))
1692 goto out_no_address;
1693 if (data->host_addrlen == 0)
1679 goto out_no_address; 1694 goto out_no_address;
1680 if (copy_from_user(&args->nfs_server.address, 1695 args->nfs_server.addrlen = data->host_addrlen;
1681 data->host_addr, 1696 if (copy_from_user(ap, data->host_addr, data->host_addrlen))
1682 sizeof(args->nfs_server.address)))
1683 return -EFAULT; 1697 return -EFAULT;
1684 if (!nfs_verify_server_address((struct sockaddr *) 1698 if (!nfs_verify_server_address((struct sockaddr *)
1685 &args->nfs_server.address)) 1699 &args->nfs_server.address))