Merge branch 'devel-for-2.6.31' into for-2.6.31

Conflicts:
	fs/nfs/client.c
	fs/nfs/super.c
This commit is contained in:
Trond Myklebust
2009-06-17 18:13:00 -07:00
18 changed files with 633 additions and 234 deletions

View File

@ -140,22 +140,22 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_fscache_uniq, "fsc=%s" },
{ 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" },
@ -516,7 +516,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
const char *nostr;
} nfs_info[] = {
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
{ NFS_MOUNT_INTR, ",intr", ",nointr" },
{ NFS_MOUNT_POSIX, ",posix", "" },
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
@ -945,11 +944,6 @@ static int nfs_parse_security_flavors(char *value,
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
* a data structure. The whole mount string is processed; bad options are
@ -960,7 +954,7 @@ static int nfs_parse_mount_options(char *raw,
struct nfs_parsed_mount_data *mnt)
{
char *p, *string, *secdata;
int rc, sloppy = 0, errors = 0;
int rc, sloppy = 0, invalid_option = 0;
if (!raw) {
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@ -984,7 +978,9 @@ static int nfs_parse_mount_options(char *raw,
while ((p = strsep(&raw, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
int option, token;
unsigned long option;
int int_option;
int token;
if (!*p)
continue;
@ -1093,114 +1089,156 @@ static int nfs_parse_mount_options(char *raw,
* options that take numeric values
*/
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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_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;
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) {
case NFS2_VERSION:
mnt->flags &= ~NFS_MOUNT_VER3;
@ -1209,16 +1247,15 @@ static int nfs_parse_mount_options(char *raw,
mnt->flags |= NFS_MOUNT_VER3;
break;
default:
errors++;
nfs_parse_invalid_value("nfsvers");
goto out_invalid_value;
}
break;
case Opt_minorversion:
if (match_int(args, &option))
if (match_int(args, &int_option))
return 0;
if (option < 0 || option > NFS4_MAX_MINOR_VERSION)
if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION)
return 0;
mnt->minorversion = option;
mnt->minorversion = int_option;
break;
/*
@ -1231,9 +1268,9 @@ static int nfs_parse_mount_options(char *raw,
rc = nfs_parse_security_flavors(string, mnt);
kfree(string);
if (!rc) {
errors++;
dfprintk(MOUNT, "NFS: unrecognized "
"security flavor\n");
return 0;
}
break;
case Opt_proto:
@ -1247,23 +1284,25 @@ static int nfs_parse_mount_options(char *raw,
case Opt_xprt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
kfree(string);
break;
case Opt_xprt_tcp:
mnt->flags |= NFS_MOUNT_TCP;
mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
kfree(string);
break;
case Opt_xprt_rdma:
/* vector side protocols to TCP */
mnt->flags |= NFS_MOUNT_TCP;
mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
xprt_load_transport(string);
kfree(string);
break;
default:
errors++;
dfprintk(MOUNT, "NFS: unrecognized "
"transport protocol\n");
return 0;
}
kfree(string);
break;
case Opt_mountproto:
string = match_strdup(args);
@ -1282,9 +1321,9 @@ static int nfs_parse_mount_options(char *raw,
break;
case Opt_xprt_rdma: /* not used for side protocols */
default:
errors++;
dfprintk(MOUNT, "NFS: unrecognized "
"transport protocol\n");
return 0;
}
break;
case Opt_addr:
@ -1340,9 +1379,9 @@ static int nfs_parse_mount_options(char *raw,
mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
break;
default:
errors++;
dfprintk(MOUNT, "NFS: invalid "
"lookupcache argument\n");
return 0;
};
break;
@ -1360,20 +1399,20 @@ static int nfs_parse_mount_options(char *raw,
break;
default:
errors++;
invalid_option = 1;
dfprintk(MOUNT, "NFS: unrecognized mount option "
"'%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;
out_invalid_value:
printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
return 0;
out_nomem:
printk(KERN_INFO "NFS: not enough memory to parse option\n");
return 0;
@ -1390,6 +1429,7 @@ out_security_failure:
static int nfs_try_mount(struct nfs_parsed_mount_data *args,
struct nfs_fh *root_fh)
{
unsigned int auth_flavor_len = 0;
struct nfs_mount_request request = {
.sap = (struct sockaddr *)
&args->mount_server.address,
@ -1397,6 +1437,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
.protocol = args->mount_server.protocol,
.fh = root_fh,
.noresvport = args->flags & NFS_MOUNT_NORESVPORT,
.auth_flav_len = &auth_flavor_len,
};
int status;
@ -2249,6 +2290,11 @@ static void nfs4_fill_super(struct super_block *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
*/
@ -2346,6 +2392,8 @@ static int nfs4_validate_mount_data(void *options,
nfs_validate_transport_protocol(args);
nfs4_validate_mount_flags(args);
if (args->auth_flavor_len > 1)
goto out_inval_auth;