diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-07-01 12:13:54 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:48 -0400 |
commit | 136d558ce766967fe3cbf54c3351aba261b5d53b (patch) | |
tree | c1c66b7478149fc2f3ef3cf1a04bd1e22324eedc /fs | |
parent | 0076d7b7bab580ca2e94637d351fa7cd357743a8 (diff) |
NFS: Add final pieces to support in-kernel mount option parsing
Hook in final components required for supporting in-kernel mount option
parsing for NFSv2 and NFSv3 mounts.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/super.c | 105 |
1 files changed, 95 insertions, 10 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 48db52a7067a..757aa3b7e64b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1051,10 +1051,28 @@ out_err: | |||
1051 | /* | 1051 | /* |
1052 | * Validate the NFS2/NFS3 mount data | 1052 | * Validate the NFS2/NFS3 mount data |
1053 | * - fills in the mount root filehandle | 1053 | * - fills in the mount root filehandle |
1054 | * | ||
1055 | * For option strings, user space handles the following behaviors: | ||
1056 | * | ||
1057 | * + DNS: mapping server host name to IP address ("addr=" option) | ||
1058 | * | ||
1059 | * + failure mode: how to behave if a mount request can't be handled | ||
1060 | * immediately ("fg/bg" option) | ||
1061 | * | ||
1062 | * + retry: how often to retry a mount request ("retry=" option) | ||
1063 | * | ||
1064 | * + breaking back: trying proto=udp after proto=tcp, v2 after v3, | ||
1065 | * mountproto=tcp after mountproto=udp, and so on | ||
1066 | * | ||
1067 | * XXX: as far as I can tell, changing the NFS program number is not | ||
1068 | * supported in the NFS client. | ||
1054 | */ | 1069 | */ |
1055 | static int nfs_validate_mount_data(struct nfs_mount_data *data, | 1070 | static int nfs_validate_mount_data(struct nfs_mount_data **options, |
1056 | struct nfs_fh *mntfh) | 1071 | struct nfs_fh *mntfh, |
1072 | const char *dev_name) | ||
1057 | { | 1073 | { |
1074 | struct nfs_mount_data *data = *options; | ||
1075 | |||
1058 | if (data == NULL) | 1076 | if (data == NULL) |
1059 | goto out_no_data; | 1077 | goto out_no_data; |
1060 | 1078 | ||
@@ -1087,8 +1105,78 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data, | |||
1087 | memset(mntfh->data + mntfh->size, 0, | 1105 | memset(mntfh->data + mntfh->size, 0, |
1088 | sizeof(mntfh->data) - mntfh->size); | 1106 | sizeof(mntfh->data) - mntfh->size); |
1089 | break; | 1107 | break; |
1090 | default: | 1108 | default: { |
1091 | goto out_bad_version; | 1109 | unsigned int len; |
1110 | char *c; | ||
1111 | int status; | ||
1112 | struct nfs_parsed_mount_data args = { | ||
1113 | .flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP), | ||
1114 | .rsize = NFS_MAX_FILE_IO_SIZE, | ||
1115 | .wsize = NFS_MAX_FILE_IO_SIZE, | ||
1116 | .timeo = 600, | ||
1117 | .retrans = 2, | ||
1118 | .acregmin = 3, | ||
1119 | .acregmax = 60, | ||
1120 | .acdirmin = 30, | ||
1121 | .acdirmax = 60, | ||
1122 | .mount_server.protocol = IPPROTO_UDP, | ||
1123 | .mount_server.program = NFS_MNT_PROGRAM, | ||
1124 | .nfs_server.protocol = IPPROTO_TCP, | ||
1125 | .nfs_server.program = NFS_PROGRAM, | ||
1126 | }; | ||
1127 | |||
1128 | if (nfs_parse_mount_options((char *) *options, &args) == 0) | ||
1129 | return -EINVAL; | ||
1130 | |||
1131 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1132 | if (data == NULL) | ||
1133 | return -ENOMEM; | ||
1134 | |||
1135 | /* | ||
1136 | * NB: after this point, caller will free "data" | ||
1137 | * if we return an error | ||
1138 | */ | ||
1139 | *options = data; | ||
1140 | |||
1141 | c = strchr(dev_name, ':'); | ||
1142 | if (c == NULL) | ||
1143 | return -EINVAL; | ||
1144 | len = c - dev_name - 1; | ||
1145 | if (len > sizeof(data->hostname)) | ||
1146 | return -EINVAL; | ||
1147 | strncpy(data->hostname, dev_name, len); | ||
1148 | args.nfs_server.hostname = data->hostname; | ||
1149 | |||
1150 | c++; | ||
1151 | if (strlen(c) > NFS_MAXPATHLEN) | ||
1152 | return -EINVAL; | ||
1153 | args.nfs_server.export_path = c; | ||
1154 | |||
1155 | status = nfs_try_mount(&args, mntfh); | ||
1156 | if (status) | ||
1157 | return -EINVAL; | ||
1158 | |||
1159 | /* | ||
1160 | * Translate to nfs_mount_data, which nfs_fill_super | ||
1161 | * can deal with. | ||
1162 | */ | ||
1163 | data->version = 6; | ||
1164 | data->flags = args.flags; | ||
1165 | data->rsize = args.rsize; | ||
1166 | data->wsize = args.wsize; | ||
1167 | data->timeo = args.timeo; | ||
1168 | data->retrans = args.retrans; | ||
1169 | data->acregmin = args.acregmin; | ||
1170 | data->acregmax = args.acregmax; | ||
1171 | data->acdirmin = args.acdirmin; | ||
1172 | data->acdirmax = args.acdirmax; | ||
1173 | data->addr = args.nfs_server.address; | ||
1174 | data->namlen = args.namlen; | ||
1175 | data->bsize = args.bsize; | ||
1176 | data->pseudoflavor = args.auth_flavors[0]; | ||
1177 | |||
1178 | break; | ||
1179 | } | ||
1092 | } | 1180 | } |
1093 | 1181 | ||
1094 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) | 1182 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) |
@@ -1117,11 +1205,6 @@ out_no_sec: | |||
1117 | dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); | 1205 | dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); |
1118 | return -EINVAL; | 1206 | return -EINVAL; |
1119 | 1207 | ||
1120 | out_bad_version: | ||
1121 | dfprintk(MOUNT, "NFS: bad nfs_mount_data version %d\n", | ||
1122 | data->version); | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | #ifndef CONFIG_NFS_V3 | 1208 | #ifndef CONFIG_NFS_V3 |
1126 | out_v3_not_compiled: | 1209 | out_v3_not_compiled: |
1127 | dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n"); | 1210 | dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n"); |
@@ -1242,7 +1325,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1242 | int error; | 1325 | int error; |
1243 | 1326 | ||
1244 | /* Validate the mount data */ | 1327 | /* Validate the mount data */ |
1245 | error = nfs_validate_mount_data(data, &mntfh); | 1328 | error = nfs_validate_mount_data(&data, &mntfh, dev_name); |
1246 | if (error < 0) | 1329 | if (error < 0) |
1247 | goto out; | 1330 | goto out; |
1248 | 1331 | ||
@@ -1283,6 +1366,8 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1283 | error = 0; | 1366 | error = 0; |
1284 | 1367 | ||
1285 | out: | 1368 | out: |
1369 | if (data != raw_data) | ||
1370 | kfree(data); | ||
1286 | return error; | 1371 | return error; |
1287 | 1372 | ||
1288 | out_err_nosb: | 1373 | out_err_nosb: |