* [PATCH 09/13] NFS: Implement NFSv2/3 in-kernel mount option parsing
@ 2007-05-21 16:10 Chuck Lever
0 siblings, 0 replies; only message in thread
From: Chuck Lever @ 2007-05-21 16:10 UTC (permalink / raw)
To: akpm; +Cc: linux-fsdevel
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/super.c | 130 +++++++++++++++++++++++++++++++++++---------------------
1 files changed, 82 insertions(+), 48 deletions(-)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a9f698b..7b7cacb 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -935,8 +935,6 @@ static struct nfs_mount_data *nfs_convert_mount_opts(const char *options)
if (args == NULL)
return ERR_PTR(-ENOMEM);
- args->nmd.version = 7;
-
args->nmd.flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
args->nmd.rsize = NFS_MAX_FILE_IO_SIZE;
args->nmd.wsize = NFS_MAX_FILE_IO_SIZE;
@@ -989,71 +987,74 @@ out_invalid:
* Validate the NFS2/NFS3 mount data
* - fills in the mount root filehandle
*/
-static int nfs_validate_mount_data(struct nfs_mount_data *data,
- struct nfs_fh *mntfh)
+static int nfs_validate_mount_data(struct nfs_mount_data **options,
+ struct nfs_fh *mntfh,
+ const char *dev_name)
{
- if (data == NULL) {
- dprintk("%s: missing data argument\n", __FUNCTION__);
- return -EINVAL;
- }
+ struct nfs_mount_data *data = *options;
+ unsigned int len;
+ char *c;
+ int status;
- if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
- dprintk("%s: bad mount version\n", __FUNCTION__);
- return -EINVAL;
- }
+ if (data == NULL)
+ goto out_no_data;
switch (data->version) {
- case 1:
- data->namlen = 0;
- case 2:
- data->bsize = 0;
- case 3:
- if (data->flags & NFS_MOUNT_VER3) {
- dprintk("%s: mount structure version %d does not support NFSv3\n",
- __FUNCTION__,
- data->version);
- return -EINVAL;
- }
- data->root.size = NFS2_FHSIZE;
- memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
- case 4:
- if (data->flags & NFS_MOUNT_SECFLAVOUR) {
- dprintk("%s: mount structure version %d does not support strong security\n",
- __FUNCTION__,
- data->version);
- return -EINVAL;
- }
- case 5:
- memset(data->context, 0, sizeof(data->context));
+ case 1:
+ data->namlen = 0;
+ case 2:
+ data->bsize = 0;
+ case 3:
+ if (data->flags & NFS_MOUNT_VER3)
+ goto out_no_v3;
+ data->root.size = NFS2_FHSIZE;
+ memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
+ case 4:
+ if (data->flags & NFS_MOUNT_SECFLAVOUR)
+ goto out_no_sec;
+ case 5:
+ memset(data->context, 0, sizeof(data->context));
+ case 6:
+ break;
+ default:
+ data = nfs_convert_mount_opts((char *) data);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+ *options = data;
+
+ c = strchr(dev_name, ':');
+ if (c == NULL)
+ return -EINVAL;
+ len = c - dev_name - 1;
+ if (len > 256)
+ return -EINVAL;
+ strncpy(data->hostname, dev_name, len);
+
+ status = nfs_try_mount(data, ++c);
+ if (status)
+ return -EINVAL;
}
- /* Set the pseudoflavor */
if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
data->pseudoflavor = RPC_AUTH_UNIX;
#ifndef CONFIG_NFS_V3
- /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
- if (data->flags & NFS_MOUNT_VER3) {
- dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
- return -EPROTONOSUPPORT;
- }
-#endif /* CONFIG_NFS_V3 */
+ if (data->flags & NFS_MOUNT_VER3)
+ goto out_v3_not_compiled;
+#endif /* !CONFIG_NFS_V3 */
/* We now require that the mount process passes the remote address */
if (!nfs_verify_server_address((struct sockaddr *) &data->addr,
sizeof(data->addr)))
return -EINVAL;
- /* Prepare the root filehandle */
if (data->flags & NFS_MOUNT_VER3)
mntfh->size = data->root.size;
else
mntfh->size = NFS2_FHSIZE;
- if (mntfh->size > sizeof(mntfh->data)) {
- dprintk("%s: invalid root filehandle\n", __FUNCTION__);
- return -EINVAL;
- }
+ if (mntfh->size > sizeof(mntfh->data))
+ goto out_invalid_fh;
memcpy(mntfh->data, data->root.data, mntfh->size);
if (mntfh->size < sizeof(mntfh->data))
@@ -1061,6 +1062,30 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data,
sizeof(mntfh->data) - mntfh->size);
return 0;
+
+out_no_data:
+ dprintk("NFS: mount program didn't pass any mount data\n");
+ return -EINVAL;
+
+out_no_v3:
+ dprintk("NFS: nfs_mount_data version %d does not support NFSv3\n",
+ data->version);
+ return -EINVAL;
+
+out_no_sec:
+ dprintk("NFS: nfs_mount_data version %d supports only AUTH_SYS\n",
+ data->version);
+ return -EINVAL;
+
+#ifndef CONFIG_NFS_V3
+out_v3_not_compiled:
+ dprintk("NFS: NFSv3 is not compiled into kernel\n");
+ return -EPROTONOSUPPORT;
+#endif /* !CONFIG_NFS_V3 */
+
+out_invalid_fh:
+ dprintk("NFS: invalid root filehandle\n");
+ return -EINVAL;
}
/*
@@ -1168,9 +1193,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
int error;
/* Validate the mount data */
- error = nfs_validate_mount_data(data, &mntfh);
- if (error < 0)
+ error = nfs_validate_mount_data(&data, &mntfh, dev_name);
+ if (error < 0) {
+ if (data != raw_data)
+ kfree(data);
return error;
+ }
/* Get a volume representation */
server = nfs_create_server(data, &mntfh);
@@ -1206,16 +1234,22 @@ static int nfs_get_sb(struct file_system_type *fs_type,
s->s_flags |= MS_ACTIVE;
mnt->mnt_sb = s;
mnt->mnt_root = mntroot;
+ if (data != raw_data)
+ kfree(data);
return 0;
out_err_nosb:
nfs_free_server(server);
out_err_noserver:
+ if (data != raw_data)
+ kfree(data);
return error;
error_splat_super:
up_write(&s->s_umount);
deactivate_super(s);
+ if (data != raw_data)
+ kfree(data);
return error;
}
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2007-05-21 16:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-21 16:10 [PATCH 09/13] NFS: Implement NFSv2/3 in-kernel mount option parsing Chuck Lever
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).