9p: Implement show_options

Implement the show_options superblock op for 9p as part of a bid to get
rid of s_options and generic_show_options() to make it easier to implement
a context-based mount where the mount options can be passed individually
over a file descriptor.

Signed-off-by: David Howells <[email protected]>
cc: Eric Van Hensbergen <[email protected]>
cc: Ron Minnich <[email protected]>
cc: Latchesar Ionkov <[email protected]>
cc: [email protected]
Signed-off-by: Al Viro <[email protected]>
This commit is contained in:
David Howells 2017-07-05 16:25:37 +01:00 • committed by Al Viro
commit c4fac91004
8 changed files with 161 additions and 10 deletions

View file

@ -37,6 +37,7 @@
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
#include <linux/seq_file.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include "protocol.h"
@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
}
EXPORT_SYMBOL(p9_is_proto_dotu);
int p9_show_client_options(struct seq_file *m, struct p9_client *clnt)
{
if (clnt->msize != 8192)
seq_printf(m, ",msize=%u", clnt->msize);
seq_printf(m, "trans=%s", clnt->trans_mod->name);
switch (clnt->proto_version) {
case p9_proto_legacy:
seq_puts(m, ",noextend");
break;
case p9_proto_2000u:
seq_puts(m, ",version=9p2000.u");
break;
case p9_proto_2000L:
/* Default */
break;
}
if (clnt->trans_mod->show_options)
return clnt->trans_mod->show_options(m, clnt);
return 0;
}
EXPORT_SYMBOL(p9_show_client_options);
/*
* Some error codes are taken directly from the server replies,
* make sure they are valid.

View file

@ -41,6 +41,7 @@
#include <linux/file.h>
#include <linux/parser.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
@ -51,6 +52,9 @@
#define MAX_SOCK_BUF (64*1024)
#define MAXPOLLWADDR 2
static struct p9_trans_module p9_tcp_trans;
static struct p9_trans_module p9_fd_trans;
/**
* struct p9_fd_opts - per-transport options
* @rfd: file descriptor for reading (trans=fd)
@ -63,7 +67,7 @@ struct p9_fd_opts {
int rfd;
int wfd;
u16 port;
int privport;
bool privport;
};
/*
@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
return 0;
}
static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
{
if (clnt->trans_mod == &p9_tcp_trans) {
if (clnt->trans_opts.tcp.port != P9_PORT)
seq_printf(m, "port=%u", clnt->trans_opts.tcp.port);
} else if (clnt->trans_mod == &p9_fd_trans) {
if (clnt->trans_opts.fd.rfd != ~0)
seq_printf(m, "rfd=%u", clnt->trans_opts.fd.rfd);
if (clnt->trans_opts.fd.wfd != ~0)
seq_printf(m, "wfd=%u", clnt->trans_opts.fd.wfd);
}
return 0;
}
/**
* parse_opts - parse mount options into p9_fd_opts structure
* @params: options string passed from mount
@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->port = P9_PORT;
opts->rfd = ~0;
opts->wfd = ~0;
opts->privport = 0;
opts->privport = false;
if (!params)
return 0;
@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->wfd = option;
break;
case Opt_privport:
opts->privport = 1;
opts->privport = true;
break;
default:
continue;
@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
csocket = NULL;
client->trans_opts.tcp.port = opts.port;
client->trans_opts.tcp.privport = opts.privport;
sin_server.sin_family = AF_INET;
sin_server.sin_addr.s_addr = in_aton(addr);
sin_server.sin_port = htons(opts.port);
@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
struct p9_fd_opts opts;
parse_opts(args, &opts);
client->trans_opts.fd.rfd = opts.rfd;
client->trans_opts.fd.wfd = opts.wfd;
if (opts.rfd == ~0 || opts.wfd == ~0) {
pr_err("Insufficient options for proto=fd\n");
@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = {
.request = p9_fd_request,
.cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE,
};
@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = {
.request = p9_fd_request,
.cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE,
};
@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = {
.request = p9_fd_request,
.cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE,
};

View file

@ -43,6 +43,7 @@
#include <linux/parser.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
@ -70,6 +71,8 @@
* @dm_mr: DMA Memory Region pointer
* @lkey: The local access only memory region key
* @timeout: Number of uSecs to wait for connection management events
* @privport: Whether a privileged port may be used
* @port: The port to use
* @sq_depth: The depth of the Send Queue
* @sq_sem: Semaphore for the SQ
* @rq_depth: The depth of the Receive Queue.
@ -95,6 +98,8 @@ struct p9_trans_rdma {
struct ib_qp *qp;
struct ib_cq *cq;
long timeout;
bool privport;
u16 port;
int sq_depth;
struct semaphore sq_sem;
int rq_depth;
@ -133,10 +138,10 @@ struct p9_rdma_context {
*/
struct p9_rdma_opts {
short port;
bool privport;
int sq_depth;
int rq_depth;
long timeout;
int privport;
};
/*
@ -159,6 +164,23 @@ static match_table_t tokens = {
{Opt_err, NULL},
};
static int p9_rdma_show_options(struct seq_file *m, struct p9_client *clnt)
{
struct p9_trans_rdma *rdma = clnt->trans;
if (rdma->port != P9_PORT)
seq_printf(m, ",port=%u", rdma->port);
if (rdma->sq_depth != P9_RDMA_SQ_DEPTH)
seq_printf(m, ",sq=%u", rdma->sq_depth);
if (rdma->rq_depth != P9_RDMA_RQ_DEPTH)
seq_printf(m, ",rq=%u", rdma->rq_depth);
if (rdma->timeout != P9_RDMA_TIMEOUT)
seq_printf(m, ",timeout=%lu", rdma->timeout);
if (rdma->privport)
seq_puts(m, ",privport");
return 0;
}
/**
* parse_opts - parse mount options into rdma options structure
* @params: options string passed from mount
@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->sq_depth = P9_RDMA_SQ_DEPTH;
opts->rq_depth = P9_RDMA_RQ_DEPTH;
opts->timeout = P9_RDMA_TIMEOUT;
opts->privport = 0;
opts->privport = false;
if (!params)
return 0;
@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->timeout = option;
break;
case Opt_privport:
opts->privport = 1;
opts->privport = true;
break;
default:
continue;
@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
if (!rdma)
return NULL;
rdma->port = opts->port;
rdma->privport = opts->privport;
rdma->sq_depth = opts->sq_depth;
rdma->rq_depth = opts->rq_depth;
rdma->timeout = opts->timeout;
@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = {
.request = rdma_request,
.cancel = rdma_cancel,
.cancelled = rdma_cancelled,
.show_options = p9_rdma_show_options,
};
/**