|
@@ -175,14 +175,16 @@ static const match_table_t nfs_mount_option_tokens = {
|
|
|
};
|
|
|
|
|
|
enum {
|
|
|
- Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma,
|
|
|
+ Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma,
|
|
|
|
|
|
Opt_xprt_err
|
|
|
};
|
|
|
|
|
|
static const match_table_t nfs_xprt_protocol_tokens = {
|
|
|
{ Opt_xprt_udp, "udp" },
|
|
|
+ { Opt_xprt_udp6, "udp6" },
|
|
|
{ Opt_xprt_tcp, "tcp" },
|
|
|
+ { Opt_xprt_tcp6, "tcp6" },
|
|
|
{ Opt_xprt_rdma, "rdma" },
|
|
|
|
|
|
{ Opt_xprt_err, NULL }
|
|
@@ -492,6 +494,45 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
|
|
|
return sec_flavours[i].str;
|
|
|
}
|
|
|
|
|
|
+static void nfs_show_mountd_netid(struct seq_file *m, struct nfs_server *nfss,
|
|
|
+ int showdefaults)
|
|
|
+{
|
|
|
+ struct sockaddr *sap = (struct sockaddr *) &nfss->mountd_address;
|
|
|
+
|
|
|
+ seq_printf(m, ",mountproto=");
|
|
|
+ switch (sap->sa_family) {
|
|
|
+ case AF_INET:
|
|
|
+ switch (nfss->mountd_protocol) {
|
|
|
+ case IPPROTO_UDP:
|
|
|
+ seq_printf(m, RPCBIND_NETID_UDP);
|
|
|
+ break;
|
|
|
+ case IPPROTO_TCP:
|
|
|
+ seq_printf(m, RPCBIND_NETID_TCP);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (showdefaults)
|
|
|
+ seq_printf(m, "auto");
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case AF_INET6:
|
|
|
+ switch (nfss->mountd_protocol) {
|
|
|
+ case IPPROTO_UDP:
|
|
|
+ seq_printf(m, RPCBIND_NETID_UDP6);
|
|
|
+ break;
|
|
|
+ case IPPROTO_TCP:
|
|
|
+ seq_printf(m, RPCBIND_NETID_TCP6);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (showdefaults)
|
|
|
+ seq_printf(m, "auto");
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (showdefaults)
|
|
|
+ seq_printf(m, "auto");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
|
|
|
int showdefaults)
|
|
|
{
|
|
@@ -505,7 +546,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
|
|
|
}
|
|
|
case AF_INET6: {
|
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
|
|
|
- seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr);
|
|
|
+ seq_printf(m, ",mountaddr=%pI6c", &sin6->sin6_addr);
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
@@ -518,17 +559,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
|
|
|
if (nfss->mountd_port || showdefaults)
|
|
|
seq_printf(m, ",mountport=%u", nfss->mountd_port);
|
|
|
|
|
|
- switch (nfss->mountd_protocol) {
|
|
|
- case IPPROTO_UDP:
|
|
|
- seq_printf(m, ",mountproto=udp");
|
|
|
- break;
|
|
|
- case IPPROTO_TCP:
|
|
|
- seq_printf(m, ",mountproto=tcp");
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (showdefaults)
|
|
|
- seq_printf(m, ",mountproto=auto");
|
|
|
- }
|
|
|
+ nfs_show_mountd_netid(m, nfss, showdefaults);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -578,7 +609,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
|
|
|
seq_puts(m, nfs_infop->nostr);
|
|
|
}
|
|
|
seq_printf(m, ",proto=%s",
|
|
|
- rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO));
|
|
|
+ rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID));
|
|
|
if (version == 4) {
|
|
|
if (nfss->port != NFS_PORT)
|
|
|
seq_printf(m, ",port=%u", nfss->port);
|
|
@@ -714,8 +745,6 @@ static void nfs_umount_begin(struct super_block *sb)
|
|
|
struct nfs_server *server;
|
|
|
struct rpc_clnt *rpc;
|
|
|
|
|
|
- lock_kernel();
|
|
|
-
|
|
|
server = NFS_SB(sb);
|
|
|
/* -EIO all pending I/O */
|
|
|
rpc = server->client_acl;
|
|
@@ -724,8 +753,6 @@ static void nfs_umount_begin(struct super_block *sb)
|
|
|
rpc = server->client;
|
|
|
if (!IS_ERR(rpc))
|
|
|
rpc_killall_tasks(rpc);
|
|
|
-
|
|
|
- unlock_kernel();
|
|
|
}
|
|
|
|
|
|
static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
|
|
@@ -734,8 +761,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
|
|
|
|
|
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
|
|
if (data) {
|
|
|
- data->rsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
- data->wsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
data->acregmin = NFS_DEF_ACREGMIN;
|
|
|
data->acregmax = NFS_DEF_ACREGMAX;
|
|
|
data->acdirmin = NFS_DEF_ACDIRMIN;
|
|
@@ -887,6 +912,8 @@ static int nfs_parse_mount_options(char *raw,
|
|
|
{
|
|
|
char *p, *string, *secdata;
|
|
|
int rc, sloppy = 0, invalid_option = 0;
|
|
|
+ unsigned short protofamily = AF_UNSPEC;
|
|
|
+ unsigned short mountfamily = AF_UNSPEC;
|
|
|
|
|
|
if (!raw) {
|
|
|
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
|
|
@@ -1232,12 +1259,17 @@ static int nfs_parse_mount_options(char *raw,
|
|
|
token = match_token(string,
|
|
|
nfs_xprt_protocol_tokens, args);
|
|
|
|
|
|
+ protofamily = AF_INET;
|
|
|
switch (token) {
|
|
|
+ case Opt_xprt_udp6:
|
|
|
+ protofamily = AF_INET6;
|
|
|
case Opt_xprt_udp:
|
|
|
mnt->flags &= ~NFS_MOUNT_TCP;
|
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
|
|
|
kfree(string);
|
|
|
break;
|
|
|
+ case Opt_xprt_tcp6:
|
|
|
+ protofamily = AF_INET6;
|
|
|
case Opt_xprt_tcp:
|
|
|
mnt->flags |= NFS_MOUNT_TCP;
|
|
|
mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
|
|
@@ -1265,10 +1297,15 @@ static int nfs_parse_mount_options(char *raw,
|
|
|
nfs_xprt_protocol_tokens, args);
|
|
|
kfree(string);
|
|
|
|
|
|
+ mountfamily = AF_INET;
|
|
|
switch (token) {
|
|
|
+ case Opt_xprt_udp6:
|
|
|
+ mountfamily = AF_INET6;
|
|
|
case Opt_xprt_udp:
|
|
|
mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
|
|
|
break;
|
|
|
+ case Opt_xprt_tcp6:
|
|
|
+ mountfamily = AF_INET6;
|
|
|
case Opt_xprt_tcp:
|
|
|
mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
|
|
|
break;
|
|
@@ -1367,8 +1404,33 @@ static int nfs_parse_mount_options(char *raw,
|
|
|
if (!sloppy && invalid_option)
|
|
|
return 0;
|
|
|
|
|
|
+ /*
|
|
|
+ * verify that any proto=/mountproto= options match the address
|
|
|
+ * familiies in the addr=/mountaddr= options.
|
|
|
+ */
|
|
|
+ if (protofamily != AF_UNSPEC &&
|
|
|
+ protofamily != mnt->nfs_server.address.ss_family)
|
|
|
+ goto out_proto_mismatch;
|
|
|
+
|
|
|
+ if (mountfamily != AF_UNSPEC) {
|
|
|
+ if (mnt->mount_server.addrlen) {
|
|
|
+ if (mountfamily != mnt->mount_server.address.ss_family)
|
|
|
+ goto out_mountproto_mismatch;
|
|
|
+ } else {
|
|
|
+ if (mountfamily != mnt->nfs_server.address.ss_family)
|
|
|
+ goto out_mountproto_mismatch;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return 1;
|
|
|
|
|
|
+out_mountproto_mismatch:
|
|
|
+ printk(KERN_INFO "NFS: mount server address does not match mountproto= "
|
|
|
+ "option\n");
|
|
|
+ return 0;
|
|
|
+out_proto_mismatch:
|
|
|
+ printk(KERN_INFO "NFS: server address does not match proto= option\n");
|
|
|
+ return 0;
|
|
|
out_invalid_address:
|
|
|
printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
|
|
|
return 0;
|
|
@@ -1881,7 +1943,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
|
|
if (data == NULL)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- lock_kernel();
|
|
|
/* fill out struct with values from existing mount */
|
|
|
data->flags = nfss->flags;
|
|
|
data->rsize = nfss->rsize;
|
|
@@ -1907,7 +1968,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
|
|
error = nfs_compare_remount_data(nfss, data);
|
|
|
out:
|
|
|
kfree(data);
|
|
|
- unlock_kernel();
|
|
|
return error;
|
|
|
}
|
|
|
|