diff options
-rw-r--r-- | fs/afs/cmservice.c | 19 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 43 |
2 files changed, 40 insertions, 22 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 1c8c6cc6de30..4b0eff6da674 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -130,6 +130,15 @@ static void afs_cm_destructor(struct afs_call *call) | |||
130 | { | 130 | { |
131 | _enter(""); | 131 | _enter(""); |
132 | 132 | ||
133 | /* Break the callbacks here so that we do it after the final ACK is | ||
134 | * received. The step number here must match the final number in | ||
135 | * afs_deliver_cb_callback(). | ||
136 | */ | ||
137 | if (call->unmarshall == 6) { | ||
138 | ASSERT(call->server && call->count && call->request); | ||
139 | afs_break_callbacks(call->server, call->count, call->request); | ||
140 | } | ||
141 | |||
133 | afs_put_server(call->server); | 142 | afs_put_server(call->server); |
134 | call->server = NULL; | 143 | call->server = NULL; |
135 | kfree(call->buffer); | 144 | kfree(call->buffer); |
@@ -272,6 +281,16 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, | |||
272 | _debug("trailer"); | 281 | _debug("trailer"); |
273 | if (skb->len != 0) | 282 | if (skb->len != 0) |
274 | return -EBADMSG; | 283 | return -EBADMSG; |
284 | |||
285 | /* Record that the message was unmarshalled successfully so | ||
286 | * that the call destructor can know do the callback breaking | ||
287 | * work, even if the final ACK isn't received. | ||
288 | * | ||
289 | * If the step number changes, then afs_cm_destructor() must be | ||
290 | * updated also. | ||
291 | */ | ||
292 | call->unmarshall++; | ||
293 | case 6: | ||
275 | break; | 294 | break; |
276 | } | 295 | } |
277 | 296 | ||
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index ef943df73b8c..9226a6674d7f 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -184,6 +184,19 @@ static void afs_free_call(struct afs_call *call) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | /* | 186 | /* |
187 | * End a call | ||
188 | */ | ||
189 | static void afs_end_call(struct afs_call *call) | ||
190 | { | ||
191 | if (call->rxcall) { | ||
192 | rxrpc_kernel_end_call(call->rxcall); | ||
193 | call->rxcall = NULL; | ||
194 | } | ||
195 | call->type->destructor(call); | ||
196 | afs_free_call(call); | ||
197 | } | ||
198 | |||
199 | /* | ||
187 | * allocate a call with flat request and reply buffers | 200 | * allocate a call with flat request and reply buffers |
188 | */ | 201 | */ |
189 | struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, | 202 | struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, |
@@ -383,11 +396,8 @@ error_do_abort: | |||
383 | rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); | 396 | rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); |
384 | while ((skb = skb_dequeue(&call->rx_queue))) | 397 | while ((skb = skb_dequeue(&call->rx_queue))) |
385 | afs_free_skb(skb); | 398 | afs_free_skb(skb); |
386 | rxrpc_kernel_end_call(rxcall); | ||
387 | call->rxcall = NULL; | ||
388 | error_kill_call: | 399 | error_kill_call: |
389 | call->type->destructor(call); | 400 | afs_end_call(call); |
390 | afs_free_call(call); | ||
391 | _leave(" = %d", ret); | 401 | _leave(" = %d", ret); |
392 | return ret; | 402 | return ret; |
393 | } | 403 | } |
@@ -509,12 +519,8 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
509 | if (call->state >= AFS_CALL_COMPLETE) { | 519 | if (call->state >= AFS_CALL_COMPLETE) { |
510 | while ((skb = skb_dequeue(&call->rx_queue))) | 520 | while ((skb = skb_dequeue(&call->rx_queue))) |
511 | afs_free_skb(skb); | 521 | afs_free_skb(skb); |
512 | if (call->incoming) { | 522 | if (call->incoming) |
513 | rxrpc_kernel_end_call(call->rxcall); | 523 | afs_end_call(call); |
514 | call->rxcall = NULL; | ||
515 | call->type->destructor(call); | ||
516 | afs_free_call(call); | ||
517 | } | ||
518 | } | 524 | } |
519 | 525 | ||
520 | _leave(""); | 526 | _leave(""); |
@@ -564,10 +570,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) | |||
564 | } | 570 | } |
565 | 571 | ||
566 | _debug("call complete"); | 572 | _debug("call complete"); |
567 | rxrpc_kernel_end_call(call->rxcall); | 573 | afs_end_call(call); |
568 | call->rxcall = NULL; | ||
569 | call->type->destructor(call); | ||
570 | afs_free_call(call); | ||
571 | _leave(" = %d", ret); | 574 | _leave(" = %d", ret); |
572 | return ret; | 575 | return ret; |
573 | } | 576 | } |
@@ -790,10 +793,7 @@ void afs_send_empty_reply(struct afs_call *call) | |||
790 | _debug("oom"); | 793 | _debug("oom"); |
791 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); | 794 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); |
792 | default: | 795 | default: |
793 | rxrpc_kernel_end_call(call->rxcall); | 796 | afs_end_call(call); |
794 | call->rxcall = NULL; | ||
795 | call->type->destructor(call); | ||
796 | afs_free_call(call); | ||
797 | _leave(" [error]"); | 797 | _leave(" [error]"); |
798 | return; | 798 | return; |
799 | } | 799 | } |
@@ -823,17 +823,16 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) | |||
823 | call->state = AFS_CALL_AWAIT_ACK; | 823 | call->state = AFS_CALL_AWAIT_ACK; |
824 | n = rxrpc_kernel_send_data(call->rxcall, &msg, len); | 824 | n = rxrpc_kernel_send_data(call->rxcall, &msg, len); |
825 | if (n >= 0) { | 825 | if (n >= 0) { |
826 | /* Success */ | ||
826 | _leave(" [replied]"); | 827 | _leave(" [replied]"); |
827 | return; | 828 | return; |
828 | } | 829 | } |
830 | |||
829 | if (n == -ENOMEM) { | 831 | if (n == -ENOMEM) { |
830 | _debug("oom"); | 832 | _debug("oom"); |
831 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); | 833 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); |
832 | } | 834 | } |
833 | rxrpc_kernel_end_call(call->rxcall); | 835 | afs_end_call(call); |
834 | call->rxcall = NULL; | ||
835 | call->type->destructor(call); | ||
836 | afs_free_call(call); | ||
837 | _leave(" [error]"); | 836 | _leave(" [error]"); |
838 | } | 837 | } |
839 | 838 | ||