aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 19:45:23 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 12:04:41 -0400
commit044c7768841f1ef39f951972d3c1e6537a535030 (patch)
treedaf783f7b345fe34fb1c9ee5b921c111deadc143
parent21c003687e2d1c589cf177a3ba17fd439af94850 (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>
-rw-r--r--net/9p/trans_fd.c149
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
108struct p9_req;
109typedef 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
227static 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
233static void p9_conn_rpc_cb(struct p9_req *req);
234
235static 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
270static 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
794static struct p9_req *p9_send_request(struct p9_conn *m, 837static 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
857static 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
863static 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
902static int 896static int
903p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) 897p9_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
944static 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);