|
@@ -66,20 +66,6 @@ struct p9_fd_opts {
|
|
|
int privport;
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
- * struct p9_trans_fd - transport state
|
|
|
- * @rd: reference to file to read from
|
|
|
- * @wr: reference of file to write to
|
|
|
- * @conn: connection state reference
|
|
|
- *
|
|
|
- */
|
|
|
-
|
|
|
-struct p9_trans_fd {
|
|
|
- struct file *rd;
|
|
|
- struct file *wr;
|
|
|
- struct p9_conn *conn;
|
|
|
-};
|
|
|
-
|
|
|
/*
|
|
|
* Option Parsing (code inspired by NFS code)
|
|
|
* - a little lazy - parse all fd-transport options
|
|
@@ -159,6 +145,20 @@ struct p9_conn {
|
|
|
unsigned long wsched;
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * struct p9_trans_fd - transport state
|
|
|
+ * @rd: reference to file to read from
|
|
|
+ * @wr: reference of file to write to
|
|
|
+ * @conn: connection state reference
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+struct p9_trans_fd {
|
|
|
+ struct file *rd;
|
|
|
+ struct file *wr;
|
|
|
+ struct p9_conn conn;
|
|
|
+};
|
|
|
+
|
|
|
static void p9_poll_workfn(struct work_struct *work);
|
|
|
|
|
|
static DEFINE_SPINLOCK(p9_poll_lock);
|
|
@@ -212,15 +212,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
|
|
|
m->err = err;
|
|
|
|
|
|
list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
|
|
|
- req->status = REQ_STATUS_ERROR;
|
|
|
- if (!req->t_err)
|
|
|
- req->t_err = err;
|
|
|
list_move(&req->req_list, &cancel_list);
|
|
|
}
|
|
|
list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
|
|
|
- req->status = REQ_STATUS_ERROR;
|
|
|
- if (!req->t_err)
|
|
|
- req->t_err = err;
|
|
|
list_move(&req->req_list, &cancel_list);
|
|
|
}
|
|
|
spin_unlock_irqrestore(&m->client->lock, flags);
|
|
@@ -228,7 +222,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
|
|
|
list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
|
|
|
p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
|
|
|
list_del(&req->req_list);
|
|
|
- p9_client_cb(m->client, req);
|
|
|
+ if (!req->t_err)
|
|
|
+ req->t_err = err;
|
|
|
+ p9_client_cb(m->client, req, REQ_STATUS_ERROR);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -302,6 +298,7 @@ static void p9_read_work(struct work_struct *work)
|
|
|
{
|
|
|
int n, err;
|
|
|
struct p9_conn *m;
|
|
|
+ int status = REQ_STATUS_ERROR;
|
|
|
|
|
|
m = container_of(work, struct p9_conn, rq);
|
|
|
|
|
@@ -348,8 +345,7 @@ static void p9_read_work(struct work_struct *work)
|
|
|
"mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
|
|
|
|
|
|
m->req = p9_tag_lookup(m->client, tag);
|
|
|
- if (!m->req || (m->req->status != REQ_STATUS_SENT &&
|
|
|
- m->req->status != REQ_STATUS_FLSH)) {
|
|
|
+ if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
|
|
|
p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
|
|
|
tag);
|
|
|
err = -EIO;
|
|
@@ -375,10 +371,10 @@ static void p9_read_work(struct work_struct *work)
|
|
|
p9_debug(P9_DEBUG_TRANS, "got new packet\n");
|
|
|
spin_lock(&m->client->lock);
|
|
|
if (m->req->status != REQ_STATUS_ERROR)
|
|
|
- m->req->status = REQ_STATUS_RCVD;
|
|
|
+ status = REQ_STATUS_RCVD;
|
|
|
list_del(&m->req->req_list);
|
|
|
spin_unlock(&m->client->lock);
|
|
|
- p9_client_cb(m->client, m->req);
|
|
|
+ p9_client_cb(m->client, m->req, status);
|
|
|
m->rbuf = NULL;
|
|
|
m->rpos = 0;
|
|
|
m->rsize = 0;
|
|
@@ -573,21 +569,19 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * p9_conn_create - allocate and initialize the per-session mux data
|
|
|
+ * p9_conn_create - initialize the per-session mux data
|
|
|
* @client: client instance
|
|
|
*
|
|
|
* Note: Creates the polling task if this is the first session.
|
|
|
*/
|
|
|
|
|
|
-static struct p9_conn *p9_conn_create(struct p9_client *client)
|
|
|
+static void p9_conn_create(struct p9_client *client)
|
|
|
{
|
|
|
int n;
|
|
|
- struct p9_conn *m;
|
|
|
+ struct p9_trans_fd *ts = client->trans;
|
|
|
+ struct p9_conn *m = &ts->conn;
|
|
|
|
|
|
p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize);
|
|
|
- m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
|
|
|
- if (!m)
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
INIT_LIST_HEAD(&m->mux_list);
|
|
|
m->client = client;
|
|
@@ -609,8 +603,6 @@ static struct p9_conn *p9_conn_create(struct p9_client *client)
|
|
|
p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
|
|
|
set_bit(Wpending, &m->wsched);
|
|
|
}
|
|
|
-
|
|
|
- return m;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -669,7 +661,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
|
|
|
{
|
|
|
int n;
|
|
|
struct p9_trans_fd *ts = client->trans;
|
|
|
- struct p9_conn *m = ts->conn;
|
|
|
+ struct p9_conn *m = &ts->conn;
|
|
|
|
|
|
p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
|
|
|
m, current, req->tc, req->tc->id);
|
|
@@ -704,14 +696,26 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
|
|
|
list_del(&req->req_list);
|
|
|
req->status = REQ_STATUS_FLSHD;
|
|
|
ret = 0;
|
|
|
- } else if (req->status == REQ_STATUS_SENT)
|
|
|
- req->status = REQ_STATUS_FLSH;
|
|
|
-
|
|
|
+ }
|
|
|
spin_unlock(&client->lock);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
|
|
|
+{
|
|
|
+ p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
|
|
|
+
|
|
|
+ /* we haven't received a response for oldreq,
|
|
|
+ * remove it from the list.
|
|
|
+ */
|
|
|
+ spin_lock(&client->lock);
|
|
|
+ list_del(&req->req_list);
|
|
|
+ spin_unlock(&client->lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* parse_opts - parse mount options into p9_fd_opts structure
|
|
|
* @params: options string passed from mount
|
|
@@ -780,7 +784,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
|
|
|
|
|
|
static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
|
|
|
{
|
|
|
- struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
|
|
|
+ struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd),
|
|
|
GFP_KERNEL);
|
|
|
if (!ts)
|
|
|
return -ENOMEM;
|
|
@@ -806,9 +810,8 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
|
|
|
{
|
|
|
struct p9_trans_fd *p;
|
|
|
struct file *file;
|
|
|
- int ret;
|
|
|
|
|
|
- p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
|
|
|
+ p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
|
|
|
if (!p)
|
|
|
return -ENOMEM;
|
|
|
|
|
@@ -829,20 +832,12 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
|
|
|
|
|
|
p->rd->f_flags |= O_NONBLOCK;
|
|
|
|
|
|
- p->conn = p9_conn_create(client);
|
|
|
- if (IS_ERR(p->conn)) {
|
|
|
- ret = PTR_ERR(p->conn);
|
|
|
- p->conn = NULL;
|
|
|
- kfree(p);
|
|
|
- sockfd_put(csocket);
|
|
|
- sockfd_put(csocket);
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ p9_conn_create(client);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * p9_mux_destroy - cancels all pending requests and frees mux resources
|
|
|
+ * p9_mux_destroy - cancels all pending requests of mux
|
|
|
* @m: mux to destroy
|
|
|
*
|
|
|
*/
|
|
@@ -859,7 +854,6 @@ static void p9_conn_destroy(struct p9_conn *m)
|
|
|
p9_conn_cancel(m, -ECONNRESET);
|
|
|
|
|
|
m->client = NULL;
|
|
|
- kfree(m);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -881,7 +875,7 @@ static void p9_fd_close(struct p9_client *client)
|
|
|
|
|
|
client->status = Disconnected;
|
|
|
|
|
|
- p9_conn_destroy(ts->conn);
|
|
|
+ p9_conn_destroy(&ts->conn);
|
|
|
|
|
|
if (ts->rd)
|
|
|
fput(ts->rd);
|
|
@@ -1033,14 +1027,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
|
|
|
return err;
|
|
|
|
|
|
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;
|
|
|
- fput(p->rd);
|
|
|
- fput(p->wr);
|
|
|
- return err;
|
|
|
- }
|
|
|
+ p9_conn_create(client);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1053,6 +1040,7 @@ static struct p9_trans_module p9_tcp_trans = {
|
|
|
.close = p9_fd_close,
|
|
|
.request = p9_fd_request,
|
|
|
.cancel = p9_fd_cancel,
|
|
|
+ .cancelled = p9_fd_cancelled,
|
|
|
.owner = THIS_MODULE,
|
|
|
};
|
|
|
|
|
@@ -1064,6 +1052,7 @@ static struct p9_trans_module p9_unix_trans = {
|
|
|
.close = p9_fd_close,
|
|
|
.request = p9_fd_request,
|
|
|
.cancel = p9_fd_cancel,
|
|
|
+ .cancelled = p9_fd_cancelled,
|
|
|
.owner = THIS_MODULE,
|
|
|
};
|
|
|
|
|
@@ -1075,6 +1064,7 @@ static struct p9_trans_module p9_fd_trans = {
|
|
|
.close = p9_fd_close,
|
|
|
.request = p9_fd_request,
|
|
|
.cancel = p9_fd_cancel,
|
|
|
+ .cancelled = p9_fd_cancelled,
|
|
|
.owner = THIS_MODULE,
|
|
|
};
|
|
|
|