diff options
Diffstat (limited to 'net/9p/trans_fd.c')
-rw-r--r-- | net/9p/trans_fd.c | 110 |
1 files changed, 50 insertions, 60 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index b7bd7f2961bf..80d08f6664cb 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -66,20 +66,6 @@ struct p9_fd_opts { | |||
66 | int privport; | 66 | int privport; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | /** | ||
70 | * struct p9_trans_fd - transport state | ||
71 | * @rd: reference to file to read from | ||
72 | * @wr: reference of file to write to | ||
73 | * @conn: connection state reference | ||
74 | * | ||
75 | */ | ||
76 | |||
77 | struct p9_trans_fd { | ||
78 | struct file *rd; | ||
79 | struct file *wr; | ||
80 | struct p9_conn *conn; | ||
81 | }; | ||
82 | |||
83 | /* | 69 | /* |
84 | * Option Parsing (code inspired by NFS code) | 70 | * Option Parsing (code inspired by NFS code) |
85 | * - a little lazy - parse all fd-transport options | 71 | * - a little lazy - parse all fd-transport options |
@@ -159,6 +145,20 @@ struct p9_conn { | |||
159 | unsigned long wsched; | 145 | unsigned long wsched; |
160 | }; | 146 | }; |
161 | 147 | ||
148 | /** | ||
149 | * struct p9_trans_fd - transport state | ||
150 | * @rd: reference to file to read from | ||
151 | * @wr: reference of file to write to | ||
152 | * @conn: connection state reference | ||
153 | * | ||
154 | */ | ||
155 | |||
156 | struct p9_trans_fd { | ||
157 | struct file *rd; | ||
158 | struct file *wr; | ||
159 | struct p9_conn conn; | ||
160 | }; | ||
161 | |||
162 | static void p9_poll_workfn(struct work_struct *work); | 162 | static void p9_poll_workfn(struct work_struct *work); |
163 | 163 | ||
164 | static DEFINE_SPINLOCK(p9_poll_lock); | 164 | static DEFINE_SPINLOCK(p9_poll_lock); |
@@ -212,15 +212,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
212 | m->err = err; | 212 | m->err = err; |
213 | 213 | ||
214 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { | 214 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { |
215 | req->status = REQ_STATUS_ERROR; | ||
216 | if (!req->t_err) | ||
217 | req->t_err = err; | ||
218 | list_move(&req->req_list, &cancel_list); | 215 | list_move(&req->req_list, &cancel_list); |
219 | } | 216 | } |
220 | list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { | 217 | list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { |
221 | req->status = REQ_STATUS_ERROR; | ||
222 | if (!req->t_err) | ||
223 | req->t_err = err; | ||
224 | list_move(&req->req_list, &cancel_list); | 218 | list_move(&req->req_list, &cancel_list); |
225 | } | 219 | } |
226 | spin_unlock_irqrestore(&m->client->lock, flags); | 220 | spin_unlock_irqrestore(&m->client->lock, flags); |
@@ -228,7 +222,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
228 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { | 222 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { |
229 | p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); | 223 | p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); |
230 | list_del(&req->req_list); | 224 | list_del(&req->req_list); |
231 | p9_client_cb(m->client, req); | 225 | if (!req->t_err) |
226 | req->t_err = err; | ||
227 | p9_client_cb(m->client, req, REQ_STATUS_ERROR); | ||
232 | } | 228 | } |
233 | } | 229 | } |
234 | 230 | ||
@@ -302,6 +298,7 @@ static void p9_read_work(struct work_struct *work) | |||
302 | { | 298 | { |
303 | int n, err; | 299 | int n, err; |
304 | struct p9_conn *m; | 300 | struct p9_conn *m; |
301 | int status = REQ_STATUS_ERROR; | ||
305 | 302 | ||
306 | m = container_of(work, struct p9_conn, rq); | 303 | m = container_of(work, struct p9_conn, rq); |
307 | 304 | ||
@@ -348,8 +345,7 @@ static void p9_read_work(struct work_struct *work) | |||
348 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); | 345 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); |
349 | 346 | ||
350 | m->req = p9_tag_lookup(m->client, tag); | 347 | m->req = p9_tag_lookup(m->client, tag); |
351 | if (!m->req || (m->req->status != REQ_STATUS_SENT && | 348 | if (!m->req || (m->req->status != REQ_STATUS_SENT)) { |
352 | m->req->status != REQ_STATUS_FLSH)) { | ||
353 | p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", | 349 | p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", |
354 | tag); | 350 | tag); |
355 | err = -EIO; | 351 | err = -EIO; |
@@ -375,10 +371,10 @@ static void p9_read_work(struct work_struct *work) | |||
375 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); | 371 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); |
376 | spin_lock(&m->client->lock); | 372 | spin_lock(&m->client->lock); |
377 | if (m->req->status != REQ_STATUS_ERROR) | 373 | if (m->req->status != REQ_STATUS_ERROR) |
378 | m->req->status = REQ_STATUS_RCVD; | 374 | status = REQ_STATUS_RCVD; |
379 | list_del(&m->req->req_list); | 375 | list_del(&m->req->req_list); |
380 | spin_unlock(&m->client->lock); | 376 | spin_unlock(&m->client->lock); |
381 | p9_client_cb(m->client, m->req); | 377 | p9_client_cb(m->client, m->req, status); |
382 | m->rbuf = NULL; | 378 | m->rbuf = NULL; |
383 | m->rpos = 0; | 379 | m->rpos = 0; |
384 | m->rsize = 0; | 380 | m->rsize = 0; |
@@ -573,21 +569,19 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) | |||
573 | } | 569 | } |
574 | 570 | ||
575 | /** | 571 | /** |
576 | * p9_conn_create - allocate and initialize the per-session mux data | 572 | * p9_conn_create - initialize the per-session mux data |
577 | * @client: client instance | 573 | * @client: client instance |
578 | * | 574 | * |
579 | * Note: Creates the polling task if this is the first session. | 575 | * Note: Creates the polling task if this is the first session. |
580 | */ | 576 | */ |
581 | 577 | ||
582 | static struct p9_conn *p9_conn_create(struct p9_client *client) | 578 | static void p9_conn_create(struct p9_client *client) |
583 | { | 579 | { |
584 | int n; | 580 | int n; |
585 | struct p9_conn *m; | 581 | struct p9_trans_fd *ts = client->trans; |
582 | struct p9_conn *m = &ts->conn; | ||
586 | 583 | ||
587 | p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize); | 584 | p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize); |
588 | m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); | ||
589 | if (!m) | ||
590 | return ERR_PTR(-ENOMEM); | ||
591 | 585 | ||
592 | INIT_LIST_HEAD(&m->mux_list); | 586 | INIT_LIST_HEAD(&m->mux_list); |
593 | m->client = client; | 587 | m->client = client; |
@@ -609,8 +603,6 @@ static struct p9_conn *p9_conn_create(struct p9_client *client) | |||
609 | p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m); | 603 | p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m); |
610 | set_bit(Wpending, &m->wsched); | 604 | set_bit(Wpending, &m->wsched); |
611 | } | 605 | } |
612 | |||
613 | return m; | ||
614 | } | 606 | } |
615 | 607 | ||
616 | /** | 608 | /** |
@@ -669,7 +661,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) | |||
669 | { | 661 | { |
670 | int n; | 662 | int n; |
671 | struct p9_trans_fd *ts = client->trans; | 663 | struct p9_trans_fd *ts = client->trans; |
672 | struct p9_conn *m = ts->conn; | 664 | struct p9_conn *m = &ts->conn; |
673 | 665 | ||
674 | p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", | 666 | p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", |
675 | m, current, req->tc, req->tc->id); | 667 | 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) | |||
704 | list_del(&req->req_list); | 696 | list_del(&req->req_list); |
705 | req->status = REQ_STATUS_FLSHD; | 697 | req->status = REQ_STATUS_FLSHD; |
706 | ret = 0; | 698 | ret = 0; |
707 | } else if (req->status == REQ_STATUS_SENT) | 699 | } |
708 | req->status = REQ_STATUS_FLSH; | ||
709 | |||
710 | spin_unlock(&client->lock); | 700 | spin_unlock(&client->lock); |
711 | 701 | ||
712 | return ret; | 702 | return ret; |
713 | } | 703 | } |
714 | 704 | ||
705 | static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) | ||
706 | { | ||
707 | p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); | ||
708 | |||
709 | /* we haven't received a response for oldreq, | ||
710 | * remove it from the list. | ||
711 | */ | ||
712 | spin_lock(&client->lock); | ||
713 | list_del(&req->req_list); | ||
714 | spin_unlock(&client->lock); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
715 | /** | 719 | /** |
716 | * parse_opts - parse mount options into p9_fd_opts structure | 720 | * parse_opts - parse mount options into p9_fd_opts structure |
717 | * @params: options string passed from mount | 721 | * @params: options string passed from mount |
@@ -780,7 +784,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
780 | 784 | ||
781 | static int p9_fd_open(struct p9_client *client, int rfd, int wfd) | 785 | static int p9_fd_open(struct p9_client *client, int rfd, int wfd) |
782 | { | 786 | { |
783 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), | 787 | struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd), |
784 | GFP_KERNEL); | 788 | GFP_KERNEL); |
785 | if (!ts) | 789 | if (!ts) |
786 | return -ENOMEM; | 790 | return -ENOMEM; |
@@ -806,9 +810,8 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) | |||
806 | { | 810 | { |
807 | struct p9_trans_fd *p; | 811 | struct p9_trans_fd *p; |
808 | struct file *file; | 812 | struct file *file; |
809 | int ret; | ||
810 | 813 | ||
811 | p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); | 814 | p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); |
812 | if (!p) | 815 | if (!p) |
813 | return -ENOMEM; | 816 | return -ENOMEM; |
814 | 817 | ||
@@ -829,20 +832,12 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) | |||
829 | 832 | ||
830 | p->rd->f_flags |= O_NONBLOCK; | 833 | p->rd->f_flags |= O_NONBLOCK; |
831 | 834 | ||
832 | p->conn = p9_conn_create(client); | 835 | p9_conn_create(client); |
833 | if (IS_ERR(p->conn)) { | ||
834 | ret = PTR_ERR(p->conn); | ||
835 | p->conn = NULL; | ||
836 | kfree(p); | ||
837 | sockfd_put(csocket); | ||
838 | sockfd_put(csocket); | ||
839 | return ret; | ||
840 | } | ||
841 | return 0; | 836 | return 0; |
842 | } | 837 | } |
843 | 838 | ||
844 | /** | 839 | /** |
845 | * p9_mux_destroy - cancels all pending requests and frees mux resources | 840 | * p9_mux_destroy - cancels all pending requests of mux |
846 | * @m: mux to destroy | 841 | * @m: mux to destroy |
847 | * | 842 | * |
848 | */ | 843 | */ |
@@ -859,7 +854,6 @@ static void p9_conn_destroy(struct p9_conn *m) | |||
859 | p9_conn_cancel(m, -ECONNRESET); | 854 | p9_conn_cancel(m, -ECONNRESET); |
860 | 855 | ||
861 | m->client = NULL; | 856 | m->client = NULL; |
862 | kfree(m); | ||
863 | } | 857 | } |
864 | 858 | ||
865 | /** | 859 | /** |
@@ -881,7 +875,7 @@ static void p9_fd_close(struct p9_client *client) | |||
881 | 875 | ||
882 | client->status = Disconnected; | 876 | client->status = Disconnected; |
883 | 877 | ||
884 | p9_conn_destroy(ts->conn); | 878 | p9_conn_destroy(&ts->conn); |
885 | 879 | ||
886 | if (ts->rd) | 880 | if (ts->rd) |
887 | fput(ts->rd); | 881 | fput(ts->rd); |
@@ -1033,14 +1027,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) | |||
1033 | return err; | 1027 | return err; |
1034 | 1028 | ||
1035 | p = (struct p9_trans_fd *) client->trans; | 1029 | p = (struct p9_trans_fd *) client->trans; |
1036 | p->conn = p9_conn_create(client); | 1030 | p9_conn_create(client); |
1037 | if (IS_ERR(p->conn)) { | ||
1038 | err = PTR_ERR(p->conn); | ||
1039 | p->conn = NULL; | ||
1040 | fput(p->rd); | ||
1041 | fput(p->wr); | ||
1042 | return err; | ||
1043 | } | ||
1044 | 1031 | ||
1045 | return 0; | 1032 | return 0; |
1046 | } | 1033 | } |
@@ -1053,6 +1040,7 @@ static struct p9_trans_module p9_tcp_trans = { | |||
1053 | .close = p9_fd_close, | 1040 | .close = p9_fd_close, |
1054 | .request = p9_fd_request, | 1041 | .request = p9_fd_request, |
1055 | .cancel = p9_fd_cancel, | 1042 | .cancel = p9_fd_cancel, |
1043 | .cancelled = p9_fd_cancelled, | ||
1056 | .owner = THIS_MODULE, | 1044 | .owner = THIS_MODULE, |
1057 | }; | 1045 | }; |
1058 | 1046 | ||
@@ -1064,6 +1052,7 @@ static struct p9_trans_module p9_unix_trans = { | |||
1064 | .close = p9_fd_close, | 1052 | .close = p9_fd_close, |
1065 | .request = p9_fd_request, | 1053 | .request = p9_fd_request, |
1066 | .cancel = p9_fd_cancel, | 1054 | .cancel = p9_fd_cancel, |
1055 | .cancelled = p9_fd_cancelled, | ||
1067 | .owner = THIS_MODULE, | 1056 | .owner = THIS_MODULE, |
1068 | }; | 1057 | }; |
1069 | 1058 | ||
@@ -1075,6 +1064,7 @@ static struct p9_trans_module p9_fd_trans = { | |||
1075 | .close = p9_fd_close, | 1064 | .close = p9_fd_close, |
1076 | .request = p9_fd_request, | 1065 | .request = p9_fd_request, |
1077 | .cancel = p9_fd_cancel, | 1066 | .cancel = p9_fd_cancel, |
1067 | .cancelled = p9_fd_cancelled, | ||
1078 | .owner = THIS_MODULE, | 1068 | .owner = THIS_MODULE, |
1079 | }; | 1069 | }; |
1080 | 1070 | ||