diff options
author | Eric Van Hensbergen <ericvh@gmail.com> | 2008-10-13 19:45:23 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2008-10-17 12:04:41 -0400 |
commit | 044c7768841f1ef39f951972d3c1e6537a535030 (patch) | |
tree | daf783f7b345fe34fb1c9ee5b921c111deadc143 /net/9p/trans_fd.c | |
parent | 21c003687e2d1c589cf177a3ba17fd439af94850 (diff) |
9p: eliminate callback complexity
The current trans_fd rpc mechanisms use a dynamic callback mechanism which
introduces a lot of complexity which only accomodates a single special case.
This patch removes much of that complexity in favor of a simple exception
mechanism to deal with flushes.
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net/9p/trans_fd.c')
-rw-r--r-- | net/9p/trans_fd.c | 149 |
1 files changed, 66 insertions, 83 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index dbb057d7fa5f..180163b3e8f9 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -105,9 +105,6 @@ enum { | |||
105 | Flushed, | 105 | Flushed, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | struct p9_req; | ||
109 | typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); | ||
110 | |||
111 | /** | 108 | /** |
112 | * struct p9_req - fd mux encoding of an rpc transaction | 109 | * struct p9_req - fd mux encoding of an rpc transaction |
113 | * @lock: protects req_list | 110 | * @lock: protects req_list |
@@ -115,8 +112,6 @@ typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); | |||
115 | * @tcall: request &p9_fcall structure | 112 | * @tcall: request &p9_fcall structure |
116 | * @rcall: response &p9_fcall structure | 113 | * @rcall: response &p9_fcall structure |
117 | * @err: error state | 114 | * @err: error state |
118 | * @cb: callback for when response is received | ||
119 | * @cba: argument to pass to callback | ||
120 | * @flush: flag to indicate RPC has been flushed | 115 | * @flush: flag to indicate RPC has been flushed |
121 | * @req_list: list link for higher level objects to chain requests | 116 | * @req_list: list link for higher level objects to chain requests |
122 | * @m: connection this request was issued on | 117 | * @m: connection this request was issued on |
@@ -130,8 +125,6 @@ struct p9_req { | |||
130 | struct p9_fcall *tcall; | 125 | struct p9_fcall *tcall; |
131 | struct p9_fcall *rcall; | 126 | struct p9_fcall *rcall; |
132 | int err; | 127 | int err; |
133 | p9_conn_req_callback cb; | ||
134 | void *cba; | ||
135 | int flush; | 128 | int flush; |
136 | struct list_head req_list; | 129 | struct list_head req_list; |
137 | struct p9_conn *m; | 130 | struct p9_conn *m; |
@@ -231,6 +224,65 @@ static void p9_mux_poll_stop(struct p9_conn *m) | |||
231 | spin_unlock_irqrestore(&p9_poll_lock, flags); | 224 | spin_unlock_irqrestore(&p9_poll_lock, flags); |
232 | } | 225 | } |
233 | 226 | ||
227 | static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) | ||
228 | { | ||
229 | p9_mux_put_tag(m, req->tag); | ||
230 | kfree(req); | ||
231 | } | ||
232 | |||
233 | static void p9_conn_rpc_cb(struct p9_req *req); | ||
234 | |||
235 | static void p9_mux_flush_cb(struct p9_req *freq) | ||
236 | { | ||
237 | int tag; | ||
238 | struct p9_conn *m = freq->m; | ||
239 | struct p9_req *req, *rreq, *rptr; | ||
240 | |||
241 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, | ||
242 | freq->tcall, freq->rcall, freq->err, | ||
243 | freq->tcall->params.tflush.oldtag); | ||
244 | |||
245 | spin_lock(&m->lock); | ||
246 | tag = freq->tcall->params.tflush.oldtag; | ||
247 | req = NULL; | ||
248 | list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) { | ||
249 | if (rreq->tag == tag) { | ||
250 | req = rreq; | ||
251 | list_del(&req->req_list); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | spin_unlock(&m->lock); | ||
256 | |||
257 | if (req) { | ||
258 | spin_lock(&req->lock); | ||
259 | req->flush = Flushed; | ||
260 | spin_unlock(&req->lock); | ||
261 | |||
262 | p9_conn_rpc_cb(req); | ||
263 | } | ||
264 | |||
265 | kfree(freq->tcall); | ||
266 | kfree(freq->rcall); | ||
267 | p9_mux_free_request(m, freq); | ||
268 | } | ||
269 | |||
270 | static void p9_conn_rpc_cb(struct p9_req *req) | ||
271 | { | ||
272 | P9_DPRINTK(P9_DEBUG_MUX, "req %p\n", req); | ||
273 | |||
274 | if (req->tcall->id == P9_TFLUSH) { /* flush callback */ | ||
275 | P9_DPRINTK(P9_DEBUG_MUX, "flush req %p\n", req); | ||
276 | p9_mux_flush_cb(req); | ||
277 | } else { /* normal wakeup path */ | ||
278 | P9_DPRINTK(P9_DEBUG_MUX, "normal req %p\n", req); | ||
279 | if (req->flush != None && !req->err) | ||
280 | req->err = -ERESTARTSYS; | ||
281 | |||
282 | wake_up(&req->wqueue); | ||
283 | } | ||
284 | } | ||
285 | |||
234 | /** | 286 | /** |
235 | * p9_conn_cancel - cancel all pending requests with error | 287 | * p9_conn_cancel - cancel all pending requests with error |
236 | * @m: mux data | 288 | * @m: mux data |
@@ -259,10 +311,7 @@ void p9_conn_cancel(struct p9_conn *m, int err) | |||
259 | if (!req->err) | 311 | if (!req->err) |
260 | req->err = err; | 312 | req->err = err; |
261 | 313 | ||
262 | if (req->cb) | 314 | p9_conn_rpc_cb(req); |
263 | (*req->cb) (req, req->cba); | ||
264 | else | ||
265 | kfree(req->rcall); | ||
266 | } | 315 | } |
267 | } | 316 | } |
268 | 317 | ||
@@ -472,12 +521,8 @@ static void p9_read_work(struct work_struct *work) | |||
472 | req->rcall = rcall; | 521 | req->rcall = rcall; |
473 | process_request(m, req); | 522 | process_request(m, req); |
474 | 523 | ||
475 | if (req->flush != Flushing) { | 524 | if (req->flush != Flushing) |
476 | if (req->cb) | 525 | p9_conn_rpc_cb(req); |
477 | (*req->cb) (req, req->cba); | ||
478 | else | ||
479 | kfree(req->rcall); | ||
480 | } | ||
481 | } else { | 526 | } else { |
482 | if (err >= 0 && rcall->id != P9_RFLUSH) | 527 | if (err >= 0 && rcall->id != P9_RFLUSH) |
483 | P9_DPRINTK(P9_DEBUG_ERROR, | 528 | P9_DPRINTK(P9_DEBUG_ERROR, |
@@ -786,14 +831,10 @@ static void p9_poll_mux(struct p9_conn *m) | |||
786 | * | 831 | * |
787 | * @m: mux data | 832 | * @m: mux data |
788 | * @tc: request to be sent | 833 | * @tc: request to be sent |
789 | * @cb: callback function to call when response is received | ||
790 | * @cba: parameter to pass to the callback function | ||
791 | * | 834 | * |
792 | */ | 835 | */ |
793 | 836 | ||
794 | static struct p9_req *p9_send_request(struct p9_conn *m, | 837 | static struct p9_req *p9_send_request(struct p9_conn *m, struct p9_fcall *tc) |
795 | struct p9_fcall *tc, | ||
796 | p9_conn_req_callback cb, void *cba) | ||
797 | { | 838 | { |
798 | int n; | 839 | int n; |
799 | struct p9_req *req; | 840 | struct p9_req *req; |
@@ -835,8 +876,6 @@ static struct p9_req *p9_send_request(struct p9_conn *m, | |||
835 | req->tcall = tc; | 876 | req->tcall = tc; |
836 | req->rcall = NULL; | 877 | req->rcall = NULL; |
837 | req->err = 0; | 878 | req->err = 0; |
838 | req->cb = cb; | ||
839 | req->cba = cba; | ||
840 | req->flush = None; | 879 | req->flush = None; |
841 | 880 | ||
842 | spin_lock(&m->lock); | 881 | spin_lock(&m->lock); |
@@ -854,51 +893,6 @@ static struct p9_req *p9_send_request(struct p9_conn *m, | |||
854 | return req; | 893 | return req; |
855 | } | 894 | } |
856 | 895 | ||
857 | static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) | ||
858 | { | ||
859 | p9_mux_put_tag(m, req->tag); | ||
860 | kfree(req); | ||
861 | } | ||
862 | |||
863 | static void p9_mux_flush_cb(struct p9_req *freq, void *a) | ||
864 | { | ||
865 | int tag; | ||
866 | struct p9_conn *m; | ||
867 | struct p9_req *req, *rreq, *rptr; | ||
868 | |||
869 | m = a; | ||
870 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, | ||
871 | freq->tcall, freq->rcall, freq->err, | ||
872 | freq->tcall->params.tflush.oldtag); | ||
873 | |||
874 | spin_lock(&m->lock); | ||
875 | tag = freq->tcall->params.tflush.oldtag; | ||
876 | req = NULL; | ||
877 | list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) { | ||
878 | if (rreq->tag == tag) { | ||
879 | req = rreq; | ||
880 | list_del(&req->req_list); | ||
881 | break; | ||
882 | } | ||
883 | } | ||
884 | spin_unlock(&m->lock); | ||
885 | |||
886 | if (req) { | ||
887 | spin_lock(&req->lock); | ||
888 | req->flush = Flushed; | ||
889 | spin_unlock(&req->lock); | ||
890 | |||
891 | if (req->cb) | ||
892 | (*req->cb) (req, req->cba); | ||
893 | else | ||
894 | kfree(req->rcall); | ||
895 | } | ||
896 | |||
897 | kfree(freq->tcall); | ||
898 | kfree(freq->rcall); | ||
899 | p9_mux_free_request(m, freq); | ||
900 | } | ||
901 | |||
902 | static int | 896 | static int |
903 | p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) | 897 | p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) |
904 | { | 898 | { |
@@ -928,8 +922,7 @@ p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) | |||
928 | list_del(&rreq->req_list); | 922 | list_del(&rreq->req_list); |
929 | req->flush = Flushed; | 923 | req->flush = Flushed; |
930 | spin_unlock(&m->lock); | 924 | spin_unlock(&m->lock); |
931 | if (req->cb) | 925 | p9_conn_rpc_cb(req); |
932 | (*req->cb) (req, req->cba); | ||
933 | return 0; | 926 | return 0; |
934 | } | 927 | } |
935 | } | 928 | } |
@@ -937,20 +930,10 @@ p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) | |||
937 | 930 | ||
938 | clear_thread_flag(TIF_SIGPENDING); | 931 | clear_thread_flag(TIF_SIGPENDING); |
939 | fc = p9_create_tflush(req->tag); | 932 | fc = p9_create_tflush(req->tag); |
940 | p9_send_request(m, fc, p9_mux_flush_cb, m); | 933 | p9_send_request(m, fc); |
941 | return 1; | 934 | return 1; |
942 | } | 935 | } |
943 | 936 | ||
944 | static void p9_conn_rpc_cb(struct p9_req *req, void *a) | ||
945 | { | ||
946 | P9_DPRINTK(P9_DEBUG_MUX, "req %p arg %p\n", req, a); | ||
947 | |||
948 | if (req->flush != None && !req->err) | ||
949 | req->err = -ERESTARTSYS; | ||
950 | |||
951 | wake_up(&req->wqueue); | ||
952 | } | ||
953 | |||
954 | /** | 937 | /** |
955 | * p9_fd_rpc- sends 9P request and waits until a response is available. | 938 | * p9_fd_rpc- sends 9P request and waits until a response is available. |
956 | * The function can be interrupted. | 939 | * The function can be interrupted. |
@@ -978,7 +961,7 @@ p9_fd_rpc(struct p9_client *client, struct p9_fcall *tc, struct p9_fcall **rc) | |||
978 | clear_thread_flag(TIF_SIGPENDING); | 961 | clear_thread_flag(TIF_SIGPENDING); |
979 | } | 962 | } |
980 | 963 | ||
981 | req = p9_send_request(m, tc, p9_conn_rpc_cb, NULL); | 964 | req = p9_send_request(m, tc); |
982 | if (IS_ERR(req)) { | 965 | if (IS_ERR(req)) { |
983 | err = PTR_ERR(req); | 966 | err = PTR_ERR(req); |
984 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); | 967 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); |