aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/v9fs.c2
-rw-r--r--include/net/9p/client.h19
-rw-r--r--include/net/9p/transport.h55
-rw-r--r--net/9p/client.c21
-rw-r--r--net/9p/mod.c1
-rw-r--r--net/9p/trans_fd.c205
-rw-r--r--net/9p/trans_virtio.c50
7 files changed, 146 insertions, 207 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index c061c3f..b6b85cf 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -30,8 +30,8 @@
#include <linux/parser.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
-#include <net/9p/transport.h>
#include <net/9p/client.h>
+#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index c936dd1..c35fb54 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -27,6 +27,22 @@
#define NET_9P_CLIENT_H
/**
+ * enum p9_trans_status - different states of underlying transports
+ * @Connected: transport is connected and healthy
+ * @Disconnected: transport has been disconnected
+ * @Hung: transport is connected by wedged
+ *
+ * This enumeration details the various states a transport
+ * instatiation can be in.
+ */
+
+enum p9_trans_status {
+ Connected,
+ Disconnected,
+ Hung,
+};
+
+/**
* struct p9_client - per client instance state
* @lock: protect @fidlist
* @msize: maximum data size negotiated by protocol
@@ -48,7 +64,8 @@ struct p9_client {
int msize;
unsigned char dotu;
struct p9_trans_module *trans_mod;
- struct p9_trans *trans;
+ enum p9_trans_status status;
+ void *trans;
struct p9_conn *conn;
struct p9_idpool *fidpool;
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
index 3ca7371..3e0f2f6 100644
--- a/include/net/9p/transport.h
+++ b/include/net/9p/transport.h
@@ -26,52 +26,6 @@
#ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H
-#include <linux/module.h>
-
-/**
- * enum p9_trans_status - different states of underlying transports
- * @Connected: transport is connected and healthy
- * @Disconnected: transport has been disconnected
- * @Hung: transport is connected by wedged
- *
- * This enumeration details the various states a transport
- * instatiation can be in.
- */
-
-enum p9_trans_status {
- Connected,
- Disconnected,
- Hung,
-};
-
-/**
- * struct p9_trans - per-transport state and API
- * @status: transport &p9_trans_status
- * @msize: negotiated maximum packet size (duplicate from client)
- * @extended: negotiated protocol extensions (duplicate from client)
- * @priv: transport private data
- * @close: member function to disconnect and close the transport
- * @rpc: member function to issue a request to the transport
- *
- * This is the basic API for a transport instance. It is used as
- * a handle by the client to issue requests. This interface is currently
- * in flux during reorganization.
- *
- * Bugs: there is lots of duplicated data here and its not clear that
- * the member functions need to be per-instance versus per transport
- * module.
- */
-
-struct p9_trans {
- enum p9_trans_status status;
- int msize;
- unsigned char extended;
- void *priv;
- void (*close) (struct p9_trans *);
- int (*rpc) (struct p9_trans *t, struct p9_fcall *tc,
- struct p9_fcall **rc);
-};
-
/**
* struct p9_trans_module - transport module interface
* @list: used to maintain a list of currently available transports
@@ -79,12 +33,14 @@ struct p9_trans {
* @maxsize: transport provided maximum packet size
* @def: set if this transport should be considered the default
* @create: member function to create a new connection on this transport
+ * @close: member function to disconnect and close the transport
+ * @rpc: member function to issue a request to the transport
*
* This is the basic API for a transport module which is registered by the
* transport module with the 9P core network module and used by the client
* to instantiate a new connection on a transport.
*
- * Bugs: the transport module list isn't protected.
+ * BUGS: the transport module list isn't protected.
*/
struct p9_trans_module {
@@ -92,8 +48,11 @@ struct p9_trans_module {
char *name; /* name of transport */
int maxsize; /* max message size of transport */
int def; /* this transport should be default */
- struct p9_trans * (*create)(const char *, char *, int, unsigned char);
struct module *owner;
+ int (*create)(struct p9_client *, const char *, char *);
+ void (*close) (struct p9_client *);
+ int (*rpc) (struct p9_client *t, struct p9_fcall *tc,
+ struct p9_fcall **rc);
};
void v9fs_register_trans(struct p9_trans_module *m);
diff --git a/net/9p/client.c b/net/9p/client.c
index e053e06..f1a52a7 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -33,8 +33,8 @@
#include <linux/uaccess.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
-#include <net/9p/transport.h>
#include <net/9p/client.h>
+#include <net/9p/transport.h>
static struct p9_fid *p9_fid_create(struct p9_client *clnt);
static void p9_fid_destroy(struct p9_fid *fid);
@@ -136,7 +136,7 @@ int
p9_client_rpc(struct p9_client *c, struct p9_fcall *tc,
struct p9_fcall **rc)
{
- return c->trans->rpc(c->trans, tc, rc);
+ return c->trans_mod->rpc(c, tc, rc);
}
struct p9_client *p9_client_create(const char *dev_name, char *options)
@@ -179,13 +179,9 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
- clnt->trans = clnt->trans_mod->create(dev_name, options, clnt->msize,
- clnt->dotu);
- if (IS_ERR(clnt->trans)) {
- err = PTR_ERR(clnt->trans);
- clnt->trans = NULL;
+ err = clnt->trans_mod->create(clnt, dev_name, options);
+ if (err)
goto error;
- }
if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
@@ -233,11 +229,8 @@ void p9_client_destroy(struct p9_client *clnt)
P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
- if (clnt->trans) {
- clnt->trans->close(clnt->trans);
- kfree(clnt->trans);
- clnt->trans = NULL;
- }
+ if (clnt->trans_mod)
+ clnt->trans_mod->close(clnt);
v9fs_put_trans(clnt->trans_mod);
@@ -254,7 +247,7 @@ EXPORT_SYMBOL(p9_client_destroy);
void p9_client_disconnect(struct p9_client *clnt)
{
P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
- clnt->trans->status = Disconnected;
+ clnt->status = Disconnected;
}
EXPORT_SYMBOL(p9_client_disconnect);
diff --git a/net/9p/mod.c b/net/9p/mod.c
index 1084feb..cf8a412 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -29,6 +29,7 @@
#include <net/9p/9p.h>
#include <linux/fs.h>
#include <linux/parser.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index f845923..d09389f 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -39,6 +39,7 @@
#include <linux/file.h>
#include <linux/parser.h>
#include <net/9p/9p.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#define P9_PORT 564
@@ -146,7 +147,7 @@ struct p9_poll_wait {
* @mux_list: list link for mux to manage multiple connections (?)
* @msize: maximum size for connection (dup)
* @extended: 9p2000.u flag (dup)
- * @trans: reference to transport instance for this connection
+ * @client: reference to client instance for this connection
* @tagpool: id accounting for transactions
* @err: error state
* @req_list: accounting for requests which have been sent
@@ -171,7 +172,7 @@ struct p9_conn {
struct list_head mux_list;
int msize;
unsigned char extended;
- struct p9_trans *trans;
+ struct p9_client *client;
struct p9_idpool *tagpool;
int err;
struct list_head req_list;
@@ -214,8 +215,8 @@ static void p9_read_work(struct work_struct *work);
static void p9_write_work(struct work_struct *work);
static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address,
poll_table *p);
-static int p9_fd_write(struct p9_trans *trans, void *v, int len);
-static int p9_fd_read(struct p9_trans *trans, void *v, int len);
+static int p9_fd_write(struct p9_client *client, void *v, int len);
+static int p9_fd_read(struct p9_client *client, void *v, int len);
static DEFINE_SPINLOCK(p9_poll_lock);
static LIST_HEAD(p9_poll_pending_list);
@@ -223,7 +224,7 @@ static struct workqueue_struct *p9_mux_wq;
static struct task_struct *p9_poll_task;
static void p9_conn_destroy(struct p9_conn *);
-static unsigned int p9_fd_poll(struct p9_trans *trans,
+static unsigned int p9_fd_poll(struct p9_client *client,
struct poll_table_struct *pt);
#ifdef P9_NONBLOCK
@@ -271,27 +272,26 @@ static void p9_mux_poll_stop(struct p9_conn *m)
/**
* p9_conn_create - allocate and initialize the per-session mux data
- * @trans: transport structure
+ * @client: client instance
*
* Note: Creates the polling task if this is the first session.
*/
-static struct p9_conn *p9_conn_create(struct p9_trans *trans)
+static struct p9_conn *p9_conn_create(struct p9_client *client)
{
int i, n;
struct p9_conn *m;
- P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans,
- trans->msize);
+ P9_DPRINTK(P9_DEBUG_MUX, "client %p msize %d\n", client, client->msize);
m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
if (!m)
return ERR_PTR(-ENOMEM);
spin_lock_init(&m->lock);
INIT_LIST_HEAD(&m->mux_list);
- m->msize = trans->msize;
- m->extended = trans->extended;
- m->trans = trans;
+ m->msize = client->msize;
+ m->extended = client->dotu;
+ m->client = client;
m->tagpool = p9_idpool_create();
if (IS_ERR(m->tagpool)) {
kfree(m);
@@ -305,7 +305,7 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
INIT_LIST_HEAD(&m->poll_pending_link);
init_poll_funcptr(&m->pt, p9_pollwait);
- n = p9_fd_poll(trans, &m->pt);
+ n = p9_fd_poll(client, &m->pt);
if (n & POLLIN) {
P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
set_bit(Rpending, &m->wsched);
@@ -345,7 +345,7 @@ static void p9_conn_destroy(struct p9_conn *m)
p9_conn_cancel(m, -ECONNRESET);
- m->trans = NULL;
+ m->client = NULL;
p9_idpool_destroy(m->tagpool);
kfree(m);
}
@@ -420,7 +420,7 @@ static void p9_poll_mux(struct p9_conn *m)
if (m->err < 0)
return;
- n = p9_fd_poll(m->trans, NULL);
+ n = p9_fd_poll(m->client, NULL);
if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n);
if (n >= 0)
@@ -533,7 +533,7 @@ again:
P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos,
m->wsize);
clear_bit(Wpending, &m->wsched);
- err = p9_fd_write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos);
+ err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
if (err == -EAGAIN) {
clear_bit(Wworksched, &m->wsched);
@@ -555,7 +555,7 @@ again:
if (test_and_clear_bit(Wpending, &m->wsched))
n = POLLOUT;
else
- n = p9_fd_poll(m->trans, NULL);
+ n = p9_fd_poll(m->client, NULL);
if (n & POLLOUT) {
P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m);
@@ -640,7 +640,7 @@ static void p9_read_work(struct work_struct *work)
}
clear_bit(Rpending, &m->wsched);
- err = p9_fd_read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos);
+ err = p9_fd_read(m->client, m->rbuf + m->rpos, m->msize - m->rpos);
P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err);
if (err == -EAGAIN) {
clear_bit(Rworksched, &m->wsched);
@@ -735,7 +735,7 @@ static void p9_read_work(struct work_struct *work)
if (test_and_clear_bit(Rpending, &m->wsched))
n = POLLIN;
else
- n = p9_fd_poll(m->trans, NULL);
+ n = p9_fd_poll(m->client, NULL);
if (n & POLLIN) {
P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
@@ -819,7 +819,7 @@ static struct p9_req *p9_send_request(struct p9_conn *m,
if (test_and_clear_bit(Wpending, &m->wsched))
n = POLLOUT;
else
- n = p9_fd_poll(m->trans, NULL);
+ n = p9_fd_poll(m->client, NULL);
if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
queue_work(p9_mux_wq, &m->wq);
@@ -933,16 +933,16 @@ p9_conn_rpc_cb(struct p9_req *req, void *a)
/**
* p9_fd_rpc- sends 9P request and waits until a response is available.
* The function can be interrupted.
- * @t: transport data
+ * @client: client instance
* @tc: request to be sent
* @rc: pointer where a pointer to the response is stored
*
*/
int
-p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+p9_fd_rpc(struct p9_client *client, struct p9_fcall *tc, struct p9_fcall **rc)
{
- struct p9_trans_fd *p = t->priv;
+ struct p9_trans_fd *p = client->trans;
struct p9_conn *m = p->conn;
int err, sigpending;
unsigned long flags;
@@ -975,7 +975,7 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
if (r.err < 0)
err = r.err;
- if (err == -ERESTARTSYS && m->trans->status == Connected
+ if (err == -ERESTARTSYS && client->status == Connected
&& m->err == 0) {
if (p9_mux_flush_request(m, req)) {
/* wait until we get response of the flush message */
@@ -984,7 +984,7 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
err = wait_event_interruptible(r.wqueue,
r.rcall || r.err);
} while (!r.rcall && !r.err && err == -ERESTARTSYS &&
- m->trans->status == Connected && !m->err);
+ client->status == Connected && !m->err);
err = -ERESTARTSYS;
}
@@ -1133,7 +1133,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
return 0;
}
-static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
+static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
{
struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
GFP_KERNEL);
@@ -1151,13 +1151,13 @@ static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
return -EIO;
}
- trans->priv = ts;
- trans->status = Connected;
+ client->trans = ts;
+ client->status = Connected;
return 0;
}
-static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
+static int p9_socket_open(struct p9_client *client, struct socket *csocket)
{
int fd, ret;
@@ -1168,33 +1168,33 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
return fd;
}
- ret = p9_fd_open(trans, fd, fd);
+ ret = p9_fd_open(client, fd, fd);
if (ret < 0) {
P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
sockfd_put(csocket);
return ret;
}
- ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK;
+ ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
return 0;
}
/**
* p9_fd_read- read from a fd
- * @trans: transport instance state
+ * @client: client instance
* @v: buffer to receive data into
* @len: size of receive buffer
*
*/
-static int p9_fd_read(struct p9_trans *trans, void *v, int len)
+static int p9_fd_read(struct p9_client *client, void *v, int len)
{
int ret;
struct p9_trans_fd *ts = NULL;
- if (trans && trans->status != Disconnected)
- ts = trans->priv;
+ if (client && client->status != Disconnected)
+ ts = client->trans;
if (!ts)
return -EREMOTEIO;
@@ -1204,26 +1204,26 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len)
ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- trans->status = Disconnected;
+ client->status = Disconnected;
return ret;
}
/**
* p9_fd_write - write to a socket
- * @trans: transport instance state
+ * @client: client instance
* @v: buffer to send data from
* @len: size of send buffer
*
*/
-static int p9_fd_write(struct p9_trans *trans, void *v, int len)
+static int p9_fd_write(struct p9_client *client, void *v, int len)
{
int ret;
mm_segment_t oldfs;
struct p9_trans_fd *ts = NULL;
- if (trans && trans->status != Disconnected)
- ts = trans->priv;
+ if (client && client->status != Disconnected)
+ ts = client->trans;
if (!ts)
return -EREMOTEIO;
@@ -1238,18 +1238,18 @@ static int p9_fd_write(struct p9_trans *trans, void *v, int len)
set_fs(oldfs);
if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- trans->status = Disconnected;
+ client->status = Disconnected;
return ret;
}
static unsigned int
-p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
{
int ret, n;
struct p9_trans_fd *ts = NULL;
- if (trans && trans->status == Connected)
- ts = trans->priv;
+ if (client && client->status == Connected)
+ ts = client->trans;
if (!ts)
return -EREMOTEIO;
@@ -1275,30 +1275,31 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
}
/**
- * p9_fd_close - shutdown socket
- * @trans: private socket structure
+ * p9_fd_close - shutdown file descriptor transport
+ * @client: client instance
*
*/
-static void p9_fd_close(struct p9_trans *trans)
+static void p9_fd_close(struct p9_client *client)
{
struct p9_trans_fd *ts;
- if (!trans)
+ if (!client)
return;
- ts = xchg(&trans->priv, NULL);
-
+ ts = client->trans;
if (!ts)
return;
+ client->status = Disconnected;
+
p9_conn_destroy(ts->conn);
- trans->status = Disconnected;
if (ts->rd)
fput(ts->rd);
if (ts->wr)
fput(ts->wr);
+
kfree(ts);
}
@@ -1319,31 +1320,23 @@ static inline int valid_ipaddr4(const char *buf)
return 0;
}
-static struct p9_trans *
-p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
+static int
+p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
{
int err;
- struct p9_trans *trans;
struct socket *csocket;
struct sockaddr_in sin_server;
struct p9_fd_opts opts;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
err = parse_opts(args, &opts);
if (err < 0)
- return ERR_PTR(err);
+ return err;
if (valid_ipaddr4(addr) < 0)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
csocket = NULL;
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
- trans->msize = msize;
- trans->extended = dotu;
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
sin_server.sin_family = AF_INET;
sin_server.sin_addr.s_addr = in_aton(addr);
@@ -1366,45 +1359,38 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
goto error;
}
- err = p9_socket_open(trans, csocket);
+ err = p9_socket_open(client, csocket);
if (err < 0)
goto error;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
if (csocket)
sock_release(csocket);
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+
+ return err;
}
-static struct p9_trans *
-p9_trans_create_unix(const char *addr, char *args, int msize,
- unsigned char dotu)
+static int
+p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
{
int err;
struct socket *csocket;
struct sockaddr_un sun_server;
- struct p9_trans *trans;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
csocket = NULL;
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
if (strlen(addr) > UNIX_PATH_MAX) {
P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
@@ -1425,79 +1411,68 @@ p9_trans_create_unix(const char *addr, char *args, int msize,
goto error;
}
- err = p9_socket_open(trans, csocket);
+ err = p9_socket_open(client, csocket);
if (err < 0)
goto error;
- trans->msize = msize;
- trans->extended = dotu;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
if (csocket)
sock_release(csocket);
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+ return err;
}
-static struct p9_trans *
-p9_trans_create_fd(const char *name, char *args, int msize,
- unsigned char extended)
+static int
+p9_fd_create(struct p9_client *client, const char *addr, char *args)
{
int err;
- struct p9_trans *trans;
struct p9_fd_opts opts;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */
parse_opts(args, &opts);
if (opts.rfd == ~0 || opts.wfd == ~0) {
printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
- return ERR_PTR(-ENOPROTOOPT);
+ return -ENOPROTOOPT;
}
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
-
- err = p9_fd_open(trans, opts.rfd, opts.wfd);
+ err = p9_fd_open(client, opts.rfd, opts.wfd);
if (err < 0)
goto error;
- trans->msize = msize;
- trans->extended = extended;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+ return err;
}
static struct p9_trans_module p9_tcp_trans = {
.name = "tcp",
.maxsize = MAX_SOCK_BUF,
.def = 1,
- .create = p9_trans_create_tcp,
+ .create = p9_fd_create_tcp,
+ .close = p9_fd_close,
+ .rpc = p9_fd_rpc,
.owner = THIS_MODULE,
};
@@ -1505,7 +1480,9 @@ static struct p9_trans_module p9_unix_trans = {
.name = "unix",
.maxsize = MAX_SOCK_BUF,
.def = 0,
- .create = p9_trans_create_unix,
+ .create = p9_fd_create_unix,
+ .close = p9_fd_close,
+ .rpc = p9_fd_rpc,
.owner = THIS_MODULE,
};
@@ -1513,7 +1490,9 @@ static struct p9_trans_module p9_fd_trans = {
.name = "fd",
.maxsize = MAX_SOCK_BUF,
.def = 0,
- .create = p9_trans_create_fd,
+ .create = p9_fd_create,
+ .close = p9_fd_close,
+ .rpc = p9_fd_rpc,
.owner = THIS_MODULE,
};
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 94912e0..72493f0 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -41,6 +41,7 @@
#include <linux/file.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/scatterlist.h>
#include <linux/virtio.h>
@@ -55,7 +56,6 @@ static int chan_index;
#define P9_INIT_MAXTAG 16
-
/**
* enum p9_req_status_t - virtio request status
* @REQ_STATUS_IDLE: request slot unused
@@ -197,9 +197,9 @@ static unsigned int rest_of_page(void *data)
*
*/
-static void p9_virtio_close(struct p9_trans *trans)
+static void p9_virtio_close(struct p9_client *client)
{
- struct virtio_chan *chan = trans->priv;
+ struct virtio_chan *chan = client->trans;
int count;
unsigned long flags;
@@ -215,7 +215,7 @@ static void p9_virtio_close(struct p9_trans *trans)
chan->inuse = false;
mutex_unlock(&virtio_9p_lock);
- kfree(trans);
+ client->trans = NULL;
}
/**
@@ -292,17 +292,17 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
*/
static int
-p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+p9_virtio_rpc(struct p9_client *c, struct p9_fcall *tc, struct p9_fcall **rc)
{
int in, out;
int n, err, size;
- struct virtio_chan *chan = t->priv;
+ struct virtio_chan *chan = c->trans;
char *rdata;
struct p9_req_t *req;
unsigned long flags;
if (*rc == NULL) {
- *rc = kmalloc(sizeof(struct p9_fcall) + t->msize, GFP_KERNEL);
+ *rc = kmalloc(sizeof(struct p9_fcall) + c->msize, GFP_KERNEL);
if (!*rc)
return -ENOMEM;
}
@@ -325,7 +325,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n);
out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size);
- in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, t->msize);
+ in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, c->msize);
req->status = REQ_STATUS_SENT;
@@ -341,7 +341,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
size = le32_to_cpu(*(__le32 *) rdata);
- err = p9_deserialize_fcall(rdata, size, *rc, t->extended);
+ err = p9_deserialize_fcall(rdata, size, *rc, c->dotu);
if (err < 0) {
P9_DPRINTK(P9_DEBUG_TRANS,
"9p debug: virtio rpc deserialize returned %d\n", err);
@@ -352,8 +352,8 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
char buf[150];
- p9_printfcall(buf, sizeof(buf), *rc, t->extended);
- printk(KERN_NOTICE ">>> %p %s\n", t, buf);
+ p9_printfcall(buf, sizeof(buf), *rc, c->dotu);
+ printk(KERN_NOTICE ">>> %p %s\n", c, buf);
}
#endif
@@ -422,10 +422,9 @@ fail:
/**
* p9_virtio_create - allocate a new virtio channel
+ * @client: client instance invoking this transport
* @devname: string identifying the channel to connect to (unused)
* @args: args passed from sys_mount() for per-transport options (unused)
- * @msize: requested maximum packet size
- * @extended: 9p2000.u enabled flag
*
* This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up
@@ -441,11 +440,9 @@ fail:
*
*/
-static struct p9_trans *
-p9_virtio_create(const char *devname, char *args, int msize,
- unsigned char extended)
+static int
+p9_virtio_create(struct p9_client *client, const char *devname, char *args)
{
- struct p9_trans *trans;
struct virtio_chan *chan = channels;
int index = 0;
@@ -463,30 +460,21 @@ p9_virtio_create(const char *devname, char *args, int msize,
if (index >= MAX_9P_CHAN) {
printk(KERN_ERR "9p: no channels available\n");
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
}
chan->tagpool = p9_idpool_create();
if (IS_ERR(chan->tagpool)) {
printk(KERN_ERR "9p: couldn't allocate tagpool\n");
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
}
p9_idpool_get(chan->tagpool); /* reserve tag 0 */
chan->max_tag = 0;
chan->reqs = NULL;
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans) {
- printk(KERN_ERR "9p: couldn't allocate transport\n");
- return ERR_PTR(-ENOMEM);
- }
- trans->extended = extended;
- trans->msize = msize;
- trans->close = p9_virtio_close;
- trans->rpc = p9_virtio_rpc;
- trans->priv = chan;
+ client->trans = (void *)chan;
- return trans;
+ return 0;
}
/**
@@ -526,6 +514,8 @@ static struct virtio_driver p9_virtio_drv = {
static struct p9_trans_module p9_virtio_trans = {
.name = "virtio",
.create = p9_virtio_create,
+ .close = p9_virtio_close,
+ .rpc = p9_virtio_rpc,
.maxsize = PAGE_SIZE*16,
.def = 0,
.owner = THIS_MODULE,