diff options
Diffstat (limited to 'net/9p/trans_fd.c')
| -rw-r--r-- | net/9p/trans_fd.c | 116 | 
1 files changed, 53 insertions, 63 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 3ffda1b3799..80d08f6664c 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -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);  	}  } @@ -244,10 +240,10 @@ p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)  	if (!ts)  		return -EREMOTEIO; -	if (!ts->rd->f_op || !ts->rd->f_op->poll) +	if (!ts->rd->f_op->poll)  		return -EIO; -	if (!ts->wr->f_op || !ts->wr->f_op->poll) +	if (!ts->wr->f_op->poll)  		return -EIO;  	ret = ts->rd->f_op->poll(ts->rd, pt); @@ -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;  } @@ -1048,11 +1035,12 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)  static struct p9_trans_module p9_tcp_trans = {  	.name = "tcp",  	.maxsize = MAX_SOCK_BUF, -	.def = 1, +	.def = 0,  	.create = p9_fd_create_tcp,  	.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,  };  | 
