提交 136d558c 编写于 作者: C Chuck Lever 提交者: Trond Myklebust

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: NChuck Lever <chuck.lever@oracle.com>
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 0076d7b7
......@@ -1051,10 +1051,28 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
/*
* Validate the NFS2/NFS3 mount data
* - fills in the mount root filehandle
*
* For option strings, user space handles the following behaviors:
*
* + DNS: mapping server host name to IP address ("addr=" option)
*
* + failure mode: how to behave if a mount request can't be handled
* immediately ("fg/bg" option)
*
* + retry: how often to retry a mount request ("retry=" option)
*
* + breaking back: trying proto=udp after proto=tcp, v2 after v3,
* mountproto=tcp after mountproto=udp, and so on
*
* XXX: as far as I can tell, changing the NFS program number is not
* supported in the NFS client.
*/
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)
{
struct nfs_mount_data *data = *options;
if (data == NULL)
goto out_no_data;
......@@ -1087,8 +1105,78 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data,
memset(mntfh->data + mntfh->size, 0,
sizeof(mntfh->data) - mntfh->size);
break;
default:
goto out_bad_version;
default: {
unsigned int len;
char *c;
int status;
struct nfs_parsed_mount_data args = {
.flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP),
.rsize = NFS_MAX_FILE_IO_SIZE,
.wsize = NFS_MAX_FILE_IO_SIZE,
.timeo = 600,
.retrans = 2,
.acregmin = 3,
.acregmax = 60,
.acdirmin = 30,
.acdirmax = 60,
.mount_server.protocol = IPPROTO_UDP,
.mount_server.program = NFS_MNT_PROGRAM,
.nfs_server.protocol = IPPROTO_TCP,
.nfs_server.program = NFS_PROGRAM,
};
if (nfs_parse_mount_options((char *) *options, &args) == 0)
return -EINVAL;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
/*
* NB: after this point, caller will free "data"
* if we return an error
*/
*options = data;
c = strchr(dev_name, ':');
if (c == NULL)
return -EINVAL;
len = c - dev_name - 1;
if (len > sizeof(data->hostname))
return -EINVAL;
strncpy(data->hostname, dev_name, len);
args.nfs_server.hostname = data->hostname;
c++;
if (strlen(c) > NFS_MAXPATHLEN)
return -EINVAL;
args.nfs_server.export_path = c;
status = nfs_try_mount(&args, mntfh);
if (status)
return -EINVAL;
/*
* Translate to nfs_mount_data, which nfs_fill_super
* can deal with.
*/
data->version = 6;
data->flags = args.flags;
data->rsize = args.rsize;
data->wsize = args.wsize;
data->timeo = args.timeo;
data->retrans = args.retrans;
data->acregmin = args.acregmin;
data->acregmax = args.acregmax;
data->acdirmin = args.acdirmin;
data->acdirmax = args.acdirmax;
data->addr = args.nfs_server.address;
data->namlen = args.namlen;
data->bsize = args.bsize;
data->pseudoflavor = args.auth_flavors[0];
break;
}
}
if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
......@@ -1117,11 +1205,6 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data,
dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
return -EINVAL;
out_bad_version:
dfprintk(MOUNT, "NFS: bad nfs_mount_data version %d\n",
data->version);
return -EINVAL;
#ifndef CONFIG_NFS_V3
out_v3_not_compiled:
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,
int error;
/* Validate the mount data */
error = nfs_validate_mount_data(data, &mntfh);
error = nfs_validate_mount_data(&data, &mntfh, dev_name);
if (error < 0)
goto out;
......@@ -1283,6 +1366,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
error = 0;
out:
if (data != raw_data)
kfree(data);
return error;
out_err_nosb:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册