diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-25 15:40:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-25 15:40:36 -0400 |
commit | db1003f23189cdbb2d450dff1edbc8e318797344 (patch) | |
tree | 5e304a271618ae987b556ac48fcbc841755d8e11 /fs | |
parent | ef0d2c1686aa256a5f7a4a5f55415563c1ab184c (diff) | |
parent | 656f88ddf1ec3abf2cd20b8b4028c44e8e95f56d (diff) |
Merge branch 'afs' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes and cleanups from David Howells:
"Here are some patches to the AFS filesystem:
1) Fix problems in the clean-up parts of the cache manager service
handler.
2) Split afs_end_call() introduced in (1) and replace some identical
code elsewhere with a call to the first half of the split function.
3) Fix an error introduced in the workqueue PREPARE_WORK() elimination
commits.
4) Clean up argument passing to functions called from the workqueue as
there's now an insulating layer between them and the workqueue.
This is possible from (3)"
* 'afs' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
AFS: Pass an afs_call* to call->async_workfn() instead of a work_struct*
AFS: Fix kafs module unloading
AFS: Part of afs_end_call() is identical to code elsewhere, so split it
AFS: Fix cache manager service handlers
Diffstat (limited to 'fs')
-rw-r--r-- | fs/afs/cmservice.c | 19 | ||||
-rw-r--r-- | fs/afs/internal.h | 2 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 86 |
3 files changed, 63 insertions, 44 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/internal.h b/fs/afs/internal.h index be75b500005d..590b55f46d61 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -75,7 +75,7 @@ struct afs_call { | |||
75 | const struct afs_call_type *type; /* type of call */ | 75 | const struct afs_call_type *type; /* type of call */ |
76 | const struct afs_wait_mode *wait_mode; /* completion wait mode */ | 76 | const struct afs_wait_mode *wait_mode; /* completion wait mode */ |
77 | wait_queue_head_t waitq; /* processes awaiting completion */ | 77 | wait_queue_head_t waitq; /* processes awaiting completion */ |
78 | work_func_t async_workfn; | 78 | void (*async_workfn)(struct afs_call *call); /* asynchronous work function */ |
79 | struct work_struct async_work; /* asynchronous work processor */ | 79 | struct work_struct async_work; /* asynchronous work processor */ |
80 | struct work_struct work; /* actual work processor */ | 80 | struct work_struct work; /* actual work processor */ |
81 | struct sk_buff_head rx_queue; /* received packets */ | 81 | struct sk_buff_head rx_queue; /* received packets */ |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index ef943df73b8c..03a3beb17004 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -25,7 +25,7 @@ static void afs_wake_up_call_waiter(struct afs_call *); | |||
25 | static int afs_wait_for_call_to_complete(struct afs_call *); | 25 | static int afs_wait_for_call_to_complete(struct afs_call *); |
26 | static void afs_wake_up_async_call(struct afs_call *); | 26 | static void afs_wake_up_async_call(struct afs_call *); |
27 | static int afs_dont_wait_for_call_to_complete(struct afs_call *); | 27 | static int afs_dont_wait_for_call_to_complete(struct afs_call *); |
28 | static void afs_process_async_call(struct work_struct *); | 28 | static void afs_process_async_call(struct afs_call *); |
29 | static void afs_rx_interceptor(struct sock *, unsigned long, struct sk_buff *); | 29 | static void afs_rx_interceptor(struct sock *, unsigned long, struct sk_buff *); |
30 | static int afs_deliver_cm_op_id(struct afs_call *, struct sk_buff *, bool); | 30 | static int afs_deliver_cm_op_id(struct afs_call *, struct sk_buff *, bool); |
31 | 31 | ||
@@ -58,6 +58,13 @@ static void afs_collect_incoming_call(struct work_struct *); | |||
58 | static struct sk_buff_head afs_incoming_calls; | 58 | static struct sk_buff_head afs_incoming_calls; |
59 | static DECLARE_WORK(afs_collect_incoming_call_work, afs_collect_incoming_call); | 59 | static DECLARE_WORK(afs_collect_incoming_call_work, afs_collect_incoming_call); |
60 | 60 | ||
61 | static void afs_async_workfn(struct work_struct *work) | ||
62 | { | ||
63 | struct afs_call *call = container_of(work, struct afs_call, async_work); | ||
64 | |||
65 | call->async_workfn(call); | ||
66 | } | ||
67 | |||
61 | /* | 68 | /* |
62 | * open an RxRPC socket and bind it to be a server for callback notifications | 69 | * open an RxRPC socket and bind it to be a server for callback notifications |
63 | * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT | 70 | * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT |
@@ -184,6 +191,28 @@ static void afs_free_call(struct afs_call *call) | |||
184 | } | 191 | } |
185 | 192 | ||
186 | /* | 193 | /* |
194 | * End a call but do not free it | ||
195 | */ | ||
196 | static void afs_end_call_nofree(struct afs_call *call) | ||
197 | { | ||
198 | if (call->rxcall) { | ||
199 | rxrpc_kernel_end_call(call->rxcall); | ||
200 | call->rxcall = NULL; | ||
201 | } | ||
202 | if (call->type->destructor) | ||
203 | call->type->destructor(call); | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * End a call and free it | ||
208 | */ | ||
209 | static void afs_end_call(struct afs_call *call) | ||
210 | { | ||
211 | afs_end_call_nofree(call); | ||
212 | afs_free_call(call); | ||
213 | } | ||
214 | |||
215 | /* | ||
187 | * allocate a call with flat request and reply buffers | 216 | * allocate a call with flat request and reply buffers |
188 | */ | 217 | */ |
189 | struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, | 218 | struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, |
@@ -326,7 +355,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
326 | atomic_read(&afs_outstanding_calls)); | 355 | atomic_read(&afs_outstanding_calls)); |
327 | 356 | ||
328 | call->wait_mode = wait_mode; | 357 | call->wait_mode = wait_mode; |
329 | INIT_WORK(&call->async_work, afs_process_async_call); | 358 | call->async_workfn = afs_process_async_call; |
359 | INIT_WORK(&call->async_work, afs_async_workfn); | ||
330 | 360 | ||
331 | memset(&srx, 0, sizeof(srx)); | 361 | memset(&srx, 0, sizeof(srx)); |
332 | srx.srx_family = AF_RXRPC; | 362 | srx.srx_family = AF_RXRPC; |
@@ -383,11 +413,8 @@ error_do_abort: | |||
383 | rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); | 413 | rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); |
384 | while ((skb = skb_dequeue(&call->rx_queue))) | 414 | while ((skb = skb_dequeue(&call->rx_queue))) |
385 | afs_free_skb(skb); | 415 | afs_free_skb(skb); |
386 | rxrpc_kernel_end_call(rxcall); | ||
387 | call->rxcall = NULL; | ||
388 | error_kill_call: | 416 | error_kill_call: |
389 | call->type->destructor(call); | 417 | afs_end_call(call); |
390 | afs_free_call(call); | ||
391 | _leave(" = %d", ret); | 418 | _leave(" = %d", ret); |
392 | return ret; | 419 | return ret; |
393 | } | 420 | } |
@@ -509,12 +536,8 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
509 | if (call->state >= AFS_CALL_COMPLETE) { | 536 | if (call->state >= AFS_CALL_COMPLETE) { |
510 | while ((skb = skb_dequeue(&call->rx_queue))) | 537 | while ((skb = skb_dequeue(&call->rx_queue))) |
511 | afs_free_skb(skb); | 538 | afs_free_skb(skb); |
512 | if (call->incoming) { | 539 | if (call->incoming) |
513 | rxrpc_kernel_end_call(call->rxcall); | 540 | afs_end_call(call); |
514 | call->rxcall = NULL; | ||
515 | call->type->destructor(call); | ||
516 | afs_free_call(call); | ||
517 | } | ||
518 | } | 541 | } |
519 | 542 | ||
520 | _leave(""); | 543 | _leave(""); |
@@ -564,10 +587,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) | |||
564 | } | 587 | } |
565 | 588 | ||
566 | _debug("call complete"); | 589 | _debug("call complete"); |
567 | rxrpc_kernel_end_call(call->rxcall); | 590 | afs_end_call(call); |
568 | call->rxcall = NULL; | ||
569 | call->type->destructor(call); | ||
570 | afs_free_call(call); | ||
571 | _leave(" = %d", ret); | 591 | _leave(" = %d", ret); |
572 | return ret; | 592 | return ret; |
573 | } | 593 | } |
@@ -603,11 +623,8 @@ static int afs_dont_wait_for_call_to_complete(struct afs_call *call) | |||
603 | /* | 623 | /* |
604 | * delete an asynchronous call | 624 | * delete an asynchronous call |
605 | */ | 625 | */ |
606 | static void afs_delete_async_call(struct work_struct *work) | 626 | static void afs_delete_async_call(struct afs_call *call) |
607 | { | 627 | { |
608 | struct afs_call *call = | ||
609 | container_of(work, struct afs_call, async_work); | ||
610 | |||
611 | _enter(""); | 628 | _enter(""); |
612 | 629 | ||
613 | afs_free_call(call); | 630 | afs_free_call(call); |
@@ -620,11 +637,8 @@ static void afs_delete_async_call(struct work_struct *work) | |||
620 | * - on a multiple-thread workqueue this work item may try to run on several | 637 | * - on a multiple-thread workqueue this work item may try to run on several |
621 | * CPUs at the same time | 638 | * CPUs at the same time |
622 | */ | 639 | */ |
623 | static void afs_process_async_call(struct work_struct *work) | 640 | static void afs_process_async_call(struct afs_call *call) |
624 | { | 641 | { |
625 | struct afs_call *call = | ||
626 | container_of(work, struct afs_call, async_work); | ||
627 | |||
628 | _enter(""); | 642 | _enter(""); |
629 | 643 | ||
630 | if (!skb_queue_empty(&call->rx_queue)) | 644 | if (!skb_queue_empty(&call->rx_queue)) |
@@ -637,10 +651,7 @@ static void afs_process_async_call(struct work_struct *work) | |||
637 | call->reply = NULL; | 651 | call->reply = NULL; |
638 | 652 | ||
639 | /* kill the call */ | 653 | /* kill the call */ |
640 | rxrpc_kernel_end_call(call->rxcall); | 654 | afs_end_call_nofree(call); |
641 | call->rxcall = NULL; | ||
642 | if (call->type->destructor) | ||
643 | call->type->destructor(call); | ||
644 | 655 | ||
645 | /* we can't just delete the call because the work item may be | 656 | /* we can't just delete the call because the work item may be |
646 | * queued */ | 657 | * queued */ |
@@ -663,13 +674,6 @@ void afs_transfer_reply(struct afs_call *call, struct sk_buff *skb) | |||
663 | call->reply_size += len; | 674 | call->reply_size += len; |
664 | } | 675 | } |
665 | 676 | ||
666 | static void afs_async_workfn(struct work_struct *work) | ||
667 | { | ||
668 | struct afs_call *call = container_of(work, struct afs_call, async_work); | ||
669 | |||
670 | call->async_workfn(work); | ||
671 | } | ||
672 | |||
673 | /* | 677 | /* |
674 | * accept the backlog of incoming calls | 678 | * accept the backlog of incoming calls |
675 | */ | 679 | */ |
@@ -790,10 +794,7 @@ void afs_send_empty_reply(struct afs_call *call) | |||
790 | _debug("oom"); | 794 | _debug("oom"); |
791 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); | 795 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); |
792 | default: | 796 | default: |
793 | rxrpc_kernel_end_call(call->rxcall); | 797 | afs_end_call(call); |
794 | call->rxcall = NULL; | ||
795 | call->type->destructor(call); | ||
796 | afs_free_call(call); | ||
797 | _leave(" [error]"); | 798 | _leave(" [error]"); |
798 | return; | 799 | return; |
799 | } | 800 | } |
@@ -823,17 +824,16 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) | |||
823 | call->state = AFS_CALL_AWAIT_ACK; | 824 | call->state = AFS_CALL_AWAIT_ACK; |
824 | n = rxrpc_kernel_send_data(call->rxcall, &msg, len); | 825 | n = rxrpc_kernel_send_data(call->rxcall, &msg, len); |
825 | if (n >= 0) { | 826 | if (n >= 0) { |
827 | /* Success */ | ||
826 | _leave(" [replied]"); | 828 | _leave(" [replied]"); |
827 | return; | 829 | return; |
828 | } | 830 | } |
831 | |||
829 | if (n == -ENOMEM) { | 832 | if (n == -ENOMEM) { |
830 | _debug("oom"); | 833 | _debug("oom"); |
831 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); | 834 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); |
832 | } | 835 | } |
833 | rxrpc_kernel_end_call(call->rxcall); | 836 | afs_end_call(call); |
834 | call->rxcall = NULL; | ||
835 | call->type->destructor(call); | ||
836 | afs_free_call(call); | ||
837 | _leave(" [error]"); | 837 | _leave(" [error]"); |
838 | } | 838 | } |
839 | 839 | ||