|
@@ -90,6 +90,7 @@ enum {
|
|
Opt_mountport,
|
|
Opt_mountport,
|
|
Opt_mountvers,
|
|
Opt_mountvers,
|
|
Opt_nfsvers,
|
|
Opt_nfsvers,
|
|
|
|
+ Opt_minorversion,
|
|
|
|
|
|
/* Mount options that take string arguments */
|
|
/* Mount options that take string arguments */
|
|
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
|
|
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
|
|
@@ -139,22 +140,23 @@ static const match_table_t nfs_mount_option_tokens = {
|
|
{ Opt_fscache_uniq, "fsc=%s" },
|
|
{ Opt_fscache_uniq, "fsc=%s" },
|
|
{ Opt_nofscache, "nofsc" },
|
|
{ Opt_nofscache, "nofsc" },
|
|
|
|
|
|
- { Opt_port, "port=%u" },
|
|
|
|
- { Opt_rsize, "rsize=%u" },
|
|
|
|
- { Opt_wsize, "wsize=%u" },
|
|
|
|
- { Opt_bsize, "bsize=%u" },
|
|
|
|
- { Opt_timeo, "timeo=%u" },
|
|
|
|
- { Opt_retrans, "retrans=%u" },
|
|
|
|
- { Opt_acregmin, "acregmin=%u" },
|
|
|
|
- { Opt_acregmax, "acregmax=%u" },
|
|
|
|
- { Opt_acdirmin, "acdirmin=%u" },
|
|
|
|
- { Opt_acdirmax, "acdirmax=%u" },
|
|
|
|
- { Opt_actimeo, "actimeo=%u" },
|
|
|
|
- { Opt_namelen, "namlen=%u" },
|
|
|
|
- { Opt_mountport, "mountport=%u" },
|
|
|
|
- { Opt_mountvers, "mountvers=%u" },
|
|
|
|
- { Opt_nfsvers, "nfsvers=%u" },
|
|
|
|
- { Opt_nfsvers, "vers=%u" },
|
|
|
|
|
|
+ { Opt_port, "port=%s" },
|
|
|
|
+ { Opt_rsize, "rsize=%s" },
|
|
|
|
+ { Opt_wsize, "wsize=%s" },
|
|
|
|
+ { Opt_bsize, "bsize=%s" },
|
|
|
|
+ { Opt_timeo, "timeo=%s" },
|
|
|
|
+ { Opt_retrans, "retrans=%s" },
|
|
|
|
+ { Opt_acregmin, "acregmin=%s" },
|
|
|
|
+ { Opt_acregmax, "acregmax=%s" },
|
|
|
|
+ { Opt_acdirmin, "acdirmin=%s" },
|
|
|
|
+ { Opt_acdirmax, "acdirmax=%s" },
|
|
|
|
+ { Opt_actimeo, "actimeo=%s" },
|
|
|
|
+ { Opt_namelen, "namlen=%s" },
|
|
|
|
+ { Opt_mountport, "mountport=%s" },
|
|
|
|
+ { Opt_mountvers, "mountvers=%s" },
|
|
|
|
+ { Opt_nfsvers, "nfsvers=%s" },
|
|
|
|
+ { Opt_nfsvers, "vers=%s" },
|
|
|
|
+ { Opt_minorversion, "minorversion=%u" },
|
|
|
|
|
|
{ Opt_sec, "sec=%s" },
|
|
{ Opt_sec, "sec=%s" },
|
|
{ Opt_proto, "proto=%s" },
|
|
{ Opt_proto, "proto=%s" },
|
|
@@ -514,7 +516,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
|
|
const char *nostr;
|
|
const char *nostr;
|
|
} nfs_info[] = {
|
|
} nfs_info[] = {
|
|
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
|
|
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
|
|
- { NFS_MOUNT_INTR, ",intr", ",nointr" },
|
|
|
|
{ NFS_MOUNT_POSIX, ",posix", "" },
|
|
{ NFS_MOUNT_POSIX, ",posix", "" },
|
|
{ NFS_MOUNT_NOCTO, ",nocto", "" },
|
|
{ NFS_MOUNT_NOCTO, ",nocto", "" },
|
|
{ NFS_MOUNT_NOAC, ",noac", "" },
|
|
{ NFS_MOUNT_NOAC, ",noac", "" },
|
|
@@ -943,11 +944,6 @@ static int nfs_parse_security_flavors(char *value,
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static void nfs_parse_invalid_value(const char *option)
|
|
|
|
-{
|
|
|
|
- dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Error-check and convert a string of mount options from user space into
|
|
* Error-check and convert a string of mount options from user space into
|
|
* a data structure. The whole mount string is processed; bad options are
|
|
* a data structure. The whole mount string is processed; bad options are
|
|
@@ -958,7 +954,7 @@ static int nfs_parse_mount_options(char *raw,
|
|
struct nfs_parsed_mount_data *mnt)
|
|
struct nfs_parsed_mount_data *mnt)
|
|
{
|
|
{
|
|
char *p, *string, *secdata;
|
|
char *p, *string, *secdata;
|
|
- int rc, sloppy = 0, errors = 0;
|
|
|
|
|
|
+ int rc, sloppy = 0, invalid_option = 0;
|
|
|
|
|
|
if (!raw) {
|
|
if (!raw) {
|
|
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
|
|
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
|
|
@@ -982,7 +978,9 @@ static int nfs_parse_mount_options(char *raw,
|
|
|
|
|
|
while ((p = strsep(&raw, ",")) != NULL) {
|
|
while ((p = strsep(&raw, ",")) != NULL) {
|
|
substring_t args[MAX_OPT_ARGS];
|
|
substring_t args[MAX_OPT_ARGS];
|
|
- int option, token;
|
|
|
|
|
|
+ unsigned long option;
|
|
|
|
+ int int_option;
|
|
|
|
+ int token;
|
|
|
|
|
|
if (!*p)
|
|
if (!*p)
|
|
continue;
|
|
continue;
|
|
@@ -1091,114 +1089,156 @@ static int nfs_parse_mount_options(char *raw,
|
|
* options that take numeric values
|
|
* options that take numeric values
|
|
*/
|
|
*/
|
|
case Opt_port:
|
|
case Opt_port:
|
|
- if (match_int(args, &option) ||
|
|
|
|
- option < 0 || option > USHORT_MAX) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("port");
|
|
|
|
- } else
|
|
|
|
- mnt->nfs_server.port = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0 || option > USHORT_MAX)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->nfs_server.port = option;
|
|
break;
|
|
break;
|
|
case Opt_rsize:
|
|
case Opt_rsize:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("rsize");
|
|
|
|
- } else
|
|
|
|
- mnt->rsize = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->rsize = option;
|
|
break;
|
|
break;
|
|
case Opt_wsize:
|
|
case Opt_wsize:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("wsize");
|
|
|
|
- } else
|
|
|
|
- mnt->wsize = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->wsize = option;
|
|
break;
|
|
break;
|
|
case Opt_bsize:
|
|
case Opt_bsize:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("bsize");
|
|
|
|
- } else
|
|
|
|
- mnt->bsize = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->bsize = option;
|
|
break;
|
|
break;
|
|
case Opt_timeo:
|
|
case Opt_timeo:
|
|
- if (match_int(args, &option) || option <= 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("timeo");
|
|
|
|
- } else
|
|
|
|
- mnt->timeo = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0 || option == 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->timeo = option;
|
|
break;
|
|
break;
|
|
case Opt_retrans:
|
|
case Opt_retrans:
|
|
- if (match_int(args, &option) || option <= 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("retrans");
|
|
|
|
- } else
|
|
|
|
- mnt->retrans = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0 || option == 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->retrans = option;
|
|
break;
|
|
break;
|
|
case Opt_acregmin:
|
|
case Opt_acregmin:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("acregmin");
|
|
|
|
- } else
|
|
|
|
- mnt->acregmin = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->acregmin = option;
|
|
break;
|
|
break;
|
|
case Opt_acregmax:
|
|
case Opt_acregmax:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("acregmax");
|
|
|
|
- } else
|
|
|
|
- mnt->acregmax = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->acregmax = option;
|
|
break;
|
|
break;
|
|
case Opt_acdirmin:
|
|
case Opt_acdirmin:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("acdirmin");
|
|
|
|
- } else
|
|
|
|
- mnt->acdirmin = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->acdirmin = option;
|
|
break;
|
|
break;
|
|
case Opt_acdirmax:
|
|
case Opt_acdirmax:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("acdirmax");
|
|
|
|
- } else
|
|
|
|
- mnt->acdirmax = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->acdirmax = option;
|
|
break;
|
|
break;
|
|
case Opt_actimeo:
|
|
case Opt_actimeo:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("actimeo");
|
|
|
|
- } else
|
|
|
|
- mnt->acregmin = mnt->acregmax =
|
|
|
|
- mnt->acdirmin = mnt->acdirmax = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->acregmin = mnt->acregmax =
|
|
|
|
+ mnt->acdirmin = mnt->acdirmax = option;
|
|
break;
|
|
break;
|
|
case Opt_namelen:
|
|
case Opt_namelen:
|
|
- if (match_int(args, &option) || option < 0) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("namlen");
|
|
|
|
- } else
|
|
|
|
- mnt->namlen = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->namlen = option;
|
|
break;
|
|
break;
|
|
case Opt_mountport:
|
|
case Opt_mountport:
|
|
- if (match_int(args, &option) ||
|
|
|
|
- option < 0 || option > USHORT_MAX) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("mountport");
|
|
|
|
- } else
|
|
|
|
- mnt->mount_server.port = option;
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0 || option > USHORT_MAX)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->mount_server.port = option;
|
|
break;
|
|
break;
|
|
case Opt_mountvers:
|
|
case Opt_mountvers:
|
|
- if (match_int(args, &option) ||
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0 ||
|
|
option < NFS_MNT_VERSION ||
|
|
option < NFS_MNT_VERSION ||
|
|
- option > NFS_MNT3_VERSION) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("mountvers");
|
|
|
|
- } else
|
|
|
|
- mnt->mount_server.version = option;
|
|
|
|
|
|
+ option > NFS_MNT3_VERSION)
|
|
|
|
+ goto out_invalid_value;
|
|
|
|
+ mnt->mount_server.version = option;
|
|
break;
|
|
break;
|
|
case Opt_nfsvers:
|
|
case Opt_nfsvers:
|
|
- if (match_int(args, &option)) {
|
|
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("nfsvers");
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ string = match_strdup(args);
|
|
|
|
+ if (string == NULL)
|
|
|
|
+ goto out_nomem;
|
|
|
|
+ rc = strict_strtoul(string, 10, &option);
|
|
|
|
+ kfree(string);
|
|
|
|
+ if (rc != 0)
|
|
|
|
+ goto out_invalid_value;
|
|
switch (option) {
|
|
switch (option) {
|
|
case NFS2_VERSION:
|
|
case NFS2_VERSION:
|
|
mnt->flags &= ~NFS_MOUNT_VER3;
|
|
mnt->flags &= ~NFS_MOUNT_VER3;
|
|
@@ -1207,10 +1247,16 @@ static int nfs_parse_mount_options(char *raw,
|
|
mnt->flags |= NFS_MOUNT_VER3;
|
|
mnt->flags |= NFS_MOUNT_VER3;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- errors++;
|
|
|
|
- nfs_parse_invalid_value("nfsvers");
|
|
|
|
|
|
+ goto out_invalid_value;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case Opt_minorversion:
|
|
|
|
+ if (match_int(args, &int_option))
|
|
|
|
+ return 0;
|
|
|
|
+ if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION)
|
|
|
|
+ return 0;
|
|
|
|
+ mnt->minorversion = int_option;
|
|
|
|
+ break;
|
|
|
|
|
|
/*
|
|
/*
|
|
* options that take text values
|
|
* options that take text values
|
|
@@ -1222,9 +1268,9 @@ static int nfs_parse_mount_options(char *raw,
|
|
rc = nfs_parse_security_flavors(string, mnt);
|
|
rc = nfs_parse_security_flavors(string, mnt);
|
|
kfree(string);
|
|
kfree(string);
|
|
if (!rc) {
|
|
if (!rc) {
|
|
- errors++;
|
|
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
"security flavor\n");
|
|
"security flavor\n");
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case Opt_proto:
|
|
case Opt_proto:
|
|
@@ -1238,23 +1284,25 @@ static int nfs_parse_mount_options(char *raw,
|
|
case Opt_xprt_udp:
|
|
case Opt_xprt_udp:
|
|
mnt->flags &= ~NFS_MOUNT_TCP;
|
|
mnt->flags &= ~NFS_MOUNT_TCP;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
|
|
|
|
+ kfree(string);
|
|
break;
|
|
break;
|
|
case Opt_xprt_tcp:
|
|
case Opt_xprt_tcp:
|
|
mnt->flags |= NFS_MOUNT_TCP;
|
|
mnt->flags |= NFS_MOUNT_TCP;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
|
|
|
|
+ kfree(string);
|
|
break;
|
|
break;
|
|
case Opt_xprt_rdma:
|
|
case Opt_xprt_rdma:
|
|
/* vector side protocols to TCP */
|
|
/* vector side protocols to TCP */
|
|
mnt->flags |= NFS_MOUNT_TCP;
|
|
mnt->flags |= NFS_MOUNT_TCP;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
|
|
xprt_load_transport(string);
|
|
xprt_load_transport(string);
|
|
|
|
+ kfree(string);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- errors++;
|
|
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
"transport protocol\n");
|
|
"transport protocol\n");
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
- kfree(string);
|
|
|
|
break;
|
|
break;
|
|
case Opt_mountproto:
|
|
case Opt_mountproto:
|
|
string = match_strdup(args);
|
|
string = match_strdup(args);
|
|
@@ -1273,9 +1321,9 @@ static int nfs_parse_mount_options(char *raw,
|
|
break;
|
|
break;
|
|
case Opt_xprt_rdma: /* not used for side protocols */
|
|
case Opt_xprt_rdma: /* not used for side protocols */
|
|
default:
|
|
default:
|
|
- errors++;
|
|
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
dfprintk(MOUNT, "NFS: unrecognized "
|
|
"transport protocol\n");
|
|
"transport protocol\n");
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case Opt_addr:
|
|
case Opt_addr:
|
|
@@ -1331,9 +1379,9 @@ static int nfs_parse_mount_options(char *raw,
|
|
mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
|
|
mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- errors++;
|
|
|
|
dfprintk(MOUNT, "NFS: invalid "
|
|
dfprintk(MOUNT, "NFS: invalid "
|
|
"lookupcache argument\n");
|
|
"lookupcache argument\n");
|
|
|
|
+ return 0;
|
|
};
|
|
};
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -1351,20 +1399,20 @@ static int nfs_parse_mount_options(char *raw,
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
- errors++;
|
|
|
|
|
|
+ invalid_option = 1;
|
|
dfprintk(MOUNT, "NFS: unrecognized mount option "
|
|
dfprintk(MOUNT, "NFS: unrecognized mount option "
|
|
"'%s'\n", p);
|
|
"'%s'\n", p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (errors > 0) {
|
|
|
|
- dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n",
|
|
|
|
- errors, (errors == 1 ? "" : "s"));
|
|
|
|
- if (!sloppy)
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!sloppy && invalid_option)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
|
|
+out_invalid_value:
|
|
|
|
+ printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
|
|
|
|
+ return 0;
|
|
out_nomem:
|
|
out_nomem:
|
|
printk(KERN_INFO "NFS: not enough memory to parse option\n");
|
|
printk(KERN_INFO "NFS: not enough memory to parse option\n");
|
|
return 0;
|
|
return 0;
|
|
@@ -1381,6 +1429,7 @@ out_security_failure:
|
|
static int nfs_try_mount(struct nfs_parsed_mount_data *args,
|
|
static int nfs_try_mount(struct nfs_parsed_mount_data *args,
|
|
struct nfs_fh *root_fh)
|
|
struct nfs_fh *root_fh)
|
|
{
|
|
{
|
|
|
|
+ unsigned int auth_flavor_len = 0;
|
|
struct nfs_mount_request request = {
|
|
struct nfs_mount_request request = {
|
|
.sap = (struct sockaddr *)
|
|
.sap = (struct sockaddr *)
|
|
&args->mount_server.address,
|
|
&args->mount_server.address,
|
|
@@ -1388,6 +1437,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
|
|
.protocol = args->mount_server.protocol,
|
|
.protocol = args->mount_server.protocol,
|
|
.fh = root_fh,
|
|
.fh = root_fh,
|
|
.noresvport = args->flags & NFS_MOUNT_NORESVPORT,
|
|
.noresvport = args->flags & NFS_MOUNT_NORESVPORT,
|
|
|
|
+ .auth_flav_len = &auth_flavor_len,
|
|
};
|
|
};
|
|
int status;
|
|
int status;
|
|
|
|
|
|
@@ -2240,6 +2290,11 @@ static void nfs4_fill_super(struct super_block *sb)
|
|
nfs_initialise_sb(sb);
|
|
nfs_initialise_sb(sb);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
|
|
|
|
+{
|
|
|
|
+ args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Validate NFSv4 mount options
|
|
* Validate NFSv4 mount options
|
|
*/
|
|
*/
|
|
@@ -2263,6 +2318,7 @@ static int nfs4_validate_mount_data(void *options,
|
|
args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
|
|
args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
|
|
args->auth_flavors[0] = RPC_AUTH_UNIX;
|
|
args->auth_flavors[0] = RPC_AUTH_UNIX;
|
|
args->auth_flavor_len = 0;
|
|
args->auth_flavor_len = 0;
|
|
|
|
+ args->minorversion = 0;
|
|
|
|
|
|
switch (data->version) {
|
|
switch (data->version) {
|
|
case 1:
|
|
case 1:
|
|
@@ -2336,6 +2392,8 @@ static int nfs4_validate_mount_data(void *options,
|
|
|
|
|
|
nfs_validate_transport_protocol(args);
|
|
nfs_validate_transport_protocol(args);
|
|
|
|
|
|
|
|
+ nfs4_validate_mount_flags(args);
|
|
|
|
+
|
|
if (args->auth_flavor_len > 1)
|
|
if (args->auth_flavor_len > 1)
|
|
goto out_inval_auth;
|
|
goto out_inval_auth;
|
|
|
|
|
|
@@ -2477,12 +2535,13 @@ static void nfs4_kill_super(struct super_block *sb)
|
|
{
|
|
{
|
|
struct nfs_server *server = NFS_SB(sb);
|
|
struct nfs_server *server = NFS_SB(sb);
|
|
|
|
|
|
|
|
+ dprintk("--> %s\n", __func__);
|
|
nfs_super_return_all_delegations(sb);
|
|
nfs_super_return_all_delegations(sb);
|
|
kill_anon_super(sb);
|
|
kill_anon_super(sb);
|
|
-
|
|
|
|
nfs4_renewd_prepare_shutdown(server);
|
|
nfs4_renewd_prepare_shutdown(server);
|
|
nfs_fscache_release_super_cookie(sb);
|
|
nfs_fscache_release_super_cookie(sb);
|
|
nfs_free_server(server);
|
|
nfs_free_server(server);
|
|
|
|
+ dprintk("<-- %s\n", __func__);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|