Commit c4fac910 authored by David Howells's avatar David Howells Committed by Al Viro

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: default avatarDavid Howells <dhowells@redhat.com>
cc: Eric Van Hensbergen <ericvh@gmail.com>
cc: Ron Minnich <rminnich@sandia.gov>
cc: Latchesar Ionkov <lucho@ionkov.net>
cc: v9fs-developer@lists.sourceforge.net
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 86a1da6d
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -82,6 +83,13 @@ static const match_table_t tokens = { ...@@ -82,6 +83,13 @@ static const match_table_t tokens = {
{Opt_err, NULL} {Opt_err, NULL}
}; };
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
[CACHE_NONE] = "none",
[CACHE_MMAP] = "mmap",
[CACHE_LOOSE] = "loose",
[CACHE_FSCACHE] = "fscache",
};
/* Interpret mount options for cache mode */ /* Interpret mount options for cache mode */
static int get_cache_mode(char *s) static int get_cache_mode(char *s)
{ {
...@@ -104,6 +112,58 @@ static int get_cache_mode(char *s) ...@@ -104,6 +112,58 @@ static int get_cache_mode(char *s)
return version; return version;
} }
/*
* Display the mount options in /proc/mounts.
*/
int v9fs_show_options(struct seq_file *m, struct dentry *root)
{
struct v9fs_session_info *v9ses = root->d_sb->s_fs_info;
if (v9ses->debug)
seq_printf(m, ",debug=%x", v9ses->debug);
if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID))
seq_printf(m, ",dfltuid=%u",
from_kuid_munged(&init_user_ns, v9ses->dfltuid));
if (!gid_eq(v9ses->dfltgid, V9FS_DEFGID))
seq_printf(m, ",dfltgid=%u",
from_kgid_munged(&init_user_ns, v9ses->dfltgid));
if (v9ses->afid != ~0)
seq_printf(m, ",afid=%u", v9ses->afid);
if (strcmp(v9ses->uname, V9FS_DEFUSER) != 0)
seq_printf(m, ",uname=%s", v9ses->uname);
if (strcmp(v9ses->aname, V9FS_DEFANAME) != 0)
seq_printf(m, ",aname=%s", v9ses->aname);
if (v9ses->nodev)
seq_puts(m, ",nodevmap");
if (v9ses->cache)
seq_printf(m, ",%s", v9fs_cache_modes[v9ses->cache]);
#ifdef CONFIG_9P_FSCACHE
if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE)
seq_printf(m, ",cachetag=%s", v9ses->cachetag);
#endif
switch (v9ses->flags & V9FS_ACCESS_MASK) {
case V9FS_ACCESS_USER:
seq_puts(m, ",access=user");
break;
case V9FS_ACCESS_ANY:
seq_puts(m, ",access=any");
break;
case V9FS_ACCESS_CLIENT:
seq_puts(m, ",access=client");
break;
case V9FS_ACCESS_SINGLE:
seq_printf(m, ",access=%u",
from_kuid_munged(&init_user_ns, v9ses->uid));
break;
}
if (v9ses->flags & V9FS_POSIX_ACL)
seq_puts(m, ",posixacl");
return p9_show_client_options(m, v9ses->clnt);
}
/** /**
* v9fs_parse_options - parse mount options into session structure * v9fs_parse_options - parse mount options into session structure
* @v9ses: existing v9fs session information * @v9ses: existing v9fs session information
...@@ -230,6 +290,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) ...@@ -230,6 +290,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
break; break;
case Opt_cachetag: case Opt_cachetag:
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
kfree(v9ses->cachetag);
v9ses->cachetag = match_strdup(&args[0]); v9ses->cachetag = match_strdup(&args[0]);
#endif #endif
break; break;
......
...@@ -67,6 +67,7 @@ enum p9_cache_modes { ...@@ -67,6 +67,7 @@ enum p9_cache_modes {
CACHE_MMAP, CACHE_MMAP,
CACHE_LOOSE, CACHE_LOOSE,
CACHE_FSCACHE, CACHE_FSCACHE,
nr__p9_cache_modes
}; };
/** /**
...@@ -137,6 +138,8 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode) ...@@ -137,6 +138,8 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
return container_of(inode, struct v9fs_inode, vfs_inode); return container_of(inode, struct v9fs_inode, vfs_inode);
} }
extern int v9fs_show_options(struct seq_file *m, struct dentry *root);
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
char *); char *);
extern void v9fs_session_close(struct v9fs_session_info *v9ses); extern void v9fs_session_close(struct v9fs_session_info *v9ses);
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -104,7 +103,6 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, ...@@ -104,7 +103,6 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
sb->s_flags |= MS_POSIXACL; sb->s_flags |= MS_POSIXACL;
#endif #endif
save_mount_options(sb, data);
return 0; return 0;
} }
...@@ -349,7 +347,7 @@ static const struct super_operations v9fs_super_ops = { ...@@ -349,7 +347,7 @@ static const struct super_operations v9fs_super_ops = {
.destroy_inode = v9fs_destroy_inode, .destroy_inode = v9fs_destroy_inode,
.statfs = simple_statfs, .statfs = simple_statfs,
.evict_inode = v9fs_evict_inode, .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options, .show_options = v9fs_show_options,
.umount_begin = v9fs_umount_begin, .umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode, .write_inode = v9fs_write_inode,
}; };
...@@ -360,7 +358,7 @@ static const struct super_operations v9fs_super_ops_dotl = { ...@@ -360,7 +358,7 @@ static const struct super_operations v9fs_super_ops_dotl = {
.statfs = v9fs_statfs, .statfs = v9fs_statfs,
.drop_inode = v9fs_drop_inode, .drop_inode = v9fs_drop_inode,
.evict_inode = v9fs_evict_inode, .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options, .show_options = v9fs_show_options,
.umount_begin = v9fs_umount_begin, .umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode_dotl, .write_inode = v9fs_write_inode_dotl,
}; };
......
...@@ -157,6 +157,18 @@ struct p9_client { ...@@ -157,6 +157,18 @@ struct p9_client {
enum p9_trans_status status; enum p9_trans_status status;
void *trans; void *trans;
union {
struct {
int rfd;
int wfd;
} fd;
struct {
u16 port;
bool privport;
} tcp;
} trans_opts;
struct p9_idpool *fidpool; struct p9_idpool *fidpool;
struct list_head fidlist; struct list_head fidlist;
...@@ -213,6 +225,7 @@ struct p9_dirent { ...@@ -213,6 +225,7 @@ struct p9_dirent {
struct iov_iter; struct iov_iter;
int p9_show_client_options(struct seq_file *m, struct p9_client *clnt);
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid,
const char *name); const char *name);
......
...@@ -62,6 +62,7 @@ struct p9_trans_module { ...@@ -62,6 +62,7 @@ struct p9_trans_module {
int (*cancelled)(struct p9_client *, struct p9_req_t *req); int (*cancelled)(struct p9_client *, struct p9_req_t *req);
int (*zc_request)(struct p9_client *, struct p9_req_t *, int (*zc_request)(struct p9_client *, struct p9_req_t *,
struct iov_iter *, struct iov_iter *, int , int, int); struct iov_iter *, struct iov_iter *, int , int, int);
int (*show_options)(struct seq_file *, struct p9_client *);
}; };
void v9fs_register_trans(struct p9_trans_module *m); void v9fs_register_trans(struct p9_trans_module *m);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/uio.h> #include <linux/uio.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/seq_file.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
#include "protocol.h" #include "protocol.h"
...@@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) ...@@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
} }
EXPORT_SYMBOL(p9_is_proto_dotu); 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, * Some error codes are taken directly from the server replies,
* make sure they are valid. * make sure they are valid.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/file.h> #include <linux/file.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -51,6 +52,9 @@ ...@@ -51,6 +52,9 @@
#define MAX_SOCK_BUF (64*1024) #define MAX_SOCK_BUF (64*1024)
#define MAXPOLLWADDR 2 #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 * struct p9_fd_opts - per-transport options
* @rfd: file descriptor for reading (trans=fd) * @rfd: file descriptor for reading (trans=fd)
...@@ -63,7 +67,7 @@ struct p9_fd_opts { ...@@ -63,7 +67,7 @@ struct p9_fd_opts {
int rfd; int rfd;
int wfd; int wfd;
u16 port; u16 port;
int privport; bool privport;
}; };
/* /*
...@@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) ...@@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
return 0; 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 * parse_opts - parse mount options into p9_fd_opts structure
* @params: options string passed from mount * @params: options string passed from mount
...@@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) ...@@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->port = P9_PORT; opts->port = P9_PORT;
opts->rfd = ~0; opts->rfd = ~0;
opts->wfd = ~0; opts->wfd = ~0;
opts->privport = 0; opts->privport = false;
if (!params) if (!params)
return 0; return 0;
...@@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) ...@@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->wfd = option; opts->wfd = option;
break; break;
case Opt_privport: case Opt_privport:
opts->privport = 1; opts->privport = true;
break; break;
default: default:
continue; continue;
...@@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args) ...@@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
csocket = NULL; 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_family = AF_INET;
sin_server.sin_addr.s_addr = in_aton(addr); sin_server.sin_addr.s_addr = in_aton(addr);
sin_server.sin_port = htons(opts.port); sin_server.sin_port = htons(opts.port);
...@@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) ...@@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
struct p9_fd_opts opts; struct p9_fd_opts opts;
parse_opts(args, &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) { if (opts.rfd == ~0 || opts.wfd == ~0) {
pr_err("Insufficient options for proto=fd\n"); pr_err("Insufficient options for proto=fd\n");
...@@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = { ...@@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = { ...@@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = { ...@@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -70,6 +71,8 @@ ...@@ -70,6 +71,8 @@
* @dm_mr: DMA Memory Region pointer * @dm_mr: DMA Memory Region pointer
* @lkey: The local access only memory region key * @lkey: The local access only memory region key
* @timeout: Number of uSecs to wait for connection management events * @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_depth: The depth of the Send Queue
* @sq_sem: Semaphore for the SQ * @sq_sem: Semaphore for the SQ
* @rq_depth: The depth of the Receive Queue. * @rq_depth: The depth of the Receive Queue.
...@@ -95,6 +98,8 @@ struct p9_trans_rdma { ...@@ -95,6 +98,8 @@ struct p9_trans_rdma {
struct ib_qp *qp; struct ib_qp *qp;
struct ib_cq *cq; struct ib_cq *cq;
long timeout; long timeout;
bool privport;
u16 port;
int sq_depth; int sq_depth;
struct semaphore sq_sem; struct semaphore sq_sem;
int rq_depth; int rq_depth;
...@@ -133,10 +138,10 @@ struct p9_rdma_context { ...@@ -133,10 +138,10 @@ struct p9_rdma_context {
*/ */
struct p9_rdma_opts { struct p9_rdma_opts {
short port; short port;
bool privport;
int sq_depth; int sq_depth;
int rq_depth; int rq_depth;
long timeout; long timeout;
int privport;
}; };
/* /*
...@@ -159,6 +164,23 @@ static match_table_t tokens = { ...@@ -159,6 +164,23 @@ static match_table_t tokens = {
{Opt_err, NULL}, {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 * parse_opts - parse mount options into rdma options structure
* @params: options string passed from mount * @params: options string passed from mount
...@@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) ...@@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->sq_depth = P9_RDMA_SQ_DEPTH; opts->sq_depth = P9_RDMA_SQ_DEPTH;
opts->rq_depth = P9_RDMA_RQ_DEPTH; opts->rq_depth = P9_RDMA_RQ_DEPTH;
opts->timeout = P9_RDMA_TIMEOUT; opts->timeout = P9_RDMA_TIMEOUT;
opts->privport = 0; opts->privport = false;
if (!params) if (!params)
return 0; return 0;
...@@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) ...@@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->timeout = option; opts->timeout = option;
break; break;
case Opt_privport: case Opt_privport:
opts->privport = 1; opts->privport = true;
break; break;
default: default:
continue; continue;
...@@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts) ...@@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
if (!rdma) if (!rdma)
return NULL; return NULL;
rdma->port = opts->port;
rdma->privport = opts->privport;
rdma->sq_depth = opts->sq_depth; rdma->sq_depth = opts->sq_depth;
rdma->rq_depth = opts->rq_depth; rdma->rq_depth = opts->rq_depth;
rdma->timeout = opts->timeout; rdma->timeout = opts->timeout;
...@@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = { ...@@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = {
.request = rdma_request, .request = rdma_request,
.cancel = rdma_cancel, .cancel = rdma_cancel,
.cancelled = rdma_cancelled, .cancelled = rdma_cancelled,
.show_options = p9_rdma_show_options,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment