diff options
Diffstat (limited to 'fs/afs/cmservice.c')
-rw-r--r-- | fs/afs/cmservice.c | 19 |
1 files changed, 19 insertions, 0 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 | ||