Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit db1003f

Browse files
committed
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
2 parents ef0d2c1 + 656f88d commit db1003f

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

fs/afs/cmservice.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ static void afs_cm_destructor(struct afs_call *call)
130130
{
131131
_enter("");
132132

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+
133142
afs_put_server(call->server);
134143
call->server = NULL;
135144
kfree(call->buffer);
@@ -272,6 +281,16 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
272281
_debug("trailer");
273282
if (skb->len != 0)
274283
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:
275294
break;
276295
}
277296

fs/afs/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct afs_call {
7575
const struct afs_call_type *type; /* type of call */
7676
const struct afs_wait_mode *wait_mode; /* completion wait mode */
7777
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 */
7979
struct work_struct async_work; /* asynchronous work processor */
8080
struct work_struct work; /* actual work processor */
8181
struct sk_buff_head rx_queue; /* received packets */

fs/afs/rxrpc.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static void afs_wake_up_call_waiter(struct afs_call *);
2525
static int afs_wait_for_call_to_complete(struct afs_call *);
2626
static void afs_wake_up_async_call(struct afs_call *);
2727
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 *);
2929
static void afs_rx_interceptor(struct sock *, unsigned long, struct sk_buff *);
3030
static int afs_deliver_cm_op_id(struct afs_call *, struct sk_buff *, bool);
3131

@@ -58,6 +58,13 @@ static void afs_collect_incoming_call(struct work_struct *);
5858
static struct sk_buff_head afs_incoming_calls;
5959
static DECLARE_WORK(afs_collect_incoming_call_work, afs_collect_incoming_call);
6060

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+
6168
/*
6269
* open an RxRPC socket and bind it to be a server for callback notifications
6370
* - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
@@ -183,6 +190,28 @@ static void afs_free_call(struct afs_call *call)
183190
kfree(call);
184191
}
185192

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+
186215
/*
187216
* allocate a call with flat request and reply buffers
188217
*/
@@ -326,7 +355,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
326355
atomic_read(&afs_outstanding_calls));
327356

328357
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);
330360

331361
memset(&srx, 0, sizeof(srx));
332362
srx.srx_family = AF_RXRPC;
@@ -383,11 +413,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
383413
rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT);
384414
while ((skb = skb_dequeue(&call->rx_queue)))
385415
afs_free_skb(skb);
386-
rxrpc_kernel_end_call(rxcall);
387-
call->rxcall = NULL;
388416
error_kill_call:
389-
call->type->destructor(call);
390-
afs_free_call(call);
417+
afs_end_call(call);
391418
_leave(" = %d", ret);
392419
return ret;
393420
}
@@ -509,12 +536,8 @@ static void afs_deliver_to_call(struct afs_call *call)
509536
if (call->state >= AFS_CALL_COMPLETE) {
510537
while ((skb = skb_dequeue(&call->rx_queue)))
511538
afs_free_skb(skb);
512-
if (call->incoming) {
513-
rxrpc_kernel_end_call(call->rxcall);
514-
call->rxcall = NULL;
515-
call->type->destructor(call);
516-
afs_free_call(call);
517-
}
539+
if (call->incoming)
540+
afs_end_call(call);
518541
}
519542

520543
_leave("");
@@ -564,10 +587,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
564587
}
565588

566589
_debug("call complete");
567-
rxrpc_kernel_end_call(call->rxcall);
568-
call->rxcall = NULL;
569-
call->type->destructor(call);
570-
afs_free_call(call);
590+
afs_end_call(call);
571591
_leave(" = %d", ret);
572592
return ret;
573593
}
@@ -603,11 +623,8 @@ static int afs_dont_wait_for_call_to_complete(struct afs_call *call)
603623
/*
604624
* delete an asynchronous call
605625
*/
606-
static void afs_delete_async_call(struct work_struct *work)
626+
static void afs_delete_async_call(struct afs_call *call)
607627
{
608-
struct afs_call *call =
609-
container_of(work, struct afs_call, async_work);
610-
611628
_enter("");
612629

613630
afs_free_call(call);
@@ -620,11 +637,8 @@ static void afs_delete_async_call(struct work_struct *work)
620637
* - on a multiple-thread workqueue this work item may try to run on several
621638
* CPUs at the same time
622639
*/
623-
static void afs_process_async_call(struct work_struct *work)
640+
static void afs_process_async_call(struct afs_call *call)
624641
{
625-
struct afs_call *call =
626-
container_of(work, struct afs_call, async_work);
627-
628642
_enter("");
629643

630644
if (!skb_queue_empty(&call->rx_queue))
@@ -637,10 +651,7 @@ static void afs_process_async_call(struct work_struct *work)
637651
call->reply = NULL;
638652

639653
/* kill the call */
640-
rxrpc_kernel_end_call(call->rxcall);
641-
call->rxcall = NULL;
642-
if (call->type->destructor)
643-
call->type->destructor(call);
654+
afs_end_call_nofree(call);
644655

645656
/* we can't just delete the call because the work item may be
646657
* queued */
@@ -663,13 +674,6 @@ void afs_transfer_reply(struct afs_call *call, struct sk_buff *skb)
663674
call->reply_size += len;
664675
}
665676

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-
673677
/*
674678
* accept the backlog of incoming calls
675679
*/
@@ -790,10 +794,7 @@ void afs_send_empty_reply(struct afs_call *call)
790794
_debug("oom");
791795
rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT);
792796
default:
793-
rxrpc_kernel_end_call(call->rxcall);
794-
call->rxcall = NULL;
795-
call->type->destructor(call);
796-
afs_free_call(call);
797+
afs_end_call(call);
797798
_leave(" [error]");
798799
return;
799800
}
@@ -823,17 +824,16 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
823824
call->state = AFS_CALL_AWAIT_ACK;
824825
n = rxrpc_kernel_send_data(call->rxcall, &msg, len);
825826
if (n >= 0) {
827+
/* Success */
826828
_leave(" [replied]");
827829
return;
828830
}
831+
829832
if (n == -ENOMEM) {
830833
_debug("oom");
831834
rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT);
832835
}
833-
rxrpc_kernel_end_call(call->rxcall);
834-
call->rxcall = NULL;
835-
call->type->destructor(call);
836-
afs_free_call(call);
836+
afs_end_call(call);
837837
_leave(" [error]");
838838
}
839839

0 commit comments

Comments
 (0)