blob: bb1e2caa1720e078574a01cc33e566eb8a52f1d1 [file] [log] [blame]
David Howells08e0e7c2007-04-26 15:55:03 -07001/* Maintain an RxRPC server socket to do AFS communications through
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090012#include <linux/slab.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010013#include <linux/sched/signal.h>
14
David Howells08e0e7c2007-04-26 15:55:03 -070015#include <net/sock.h>
16#include <net/af_rxrpc.h>
David Howells08e0e7c2007-04-26 15:55:03 -070017#include "internal.h"
18#include "afs_cm.h"
19
David Howells8324f0b2016-08-30 09:49:29 +010020struct socket *afs_socket; /* my RxRPC socket */
David Howells08e0e7c2007-04-26 15:55:03 -070021static struct workqueue_struct *afs_async_calls;
David Howells00e90712016-09-08 11:10:12 +010022static struct afs_call *afs_spare_incoming_call;
David Howells341f7412017-01-05 10:38:36 +000023atomic_t afs_outstanding_calls;
David Howells08e0e7c2007-04-26 15:55:03 -070024
David Howellsd0016482016-08-30 20:42:14 +010025static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
David Howells08e0e7c2007-04-26 15:55:03 -070026static int afs_wait_for_call_to_complete(struct afs_call *);
David Howellsd0016482016-08-30 20:42:14 +010027static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
David Howellsd0016482016-08-30 20:42:14 +010028static void afs_process_async_call(struct work_struct *);
David Howells00e90712016-09-08 11:10:12 +010029static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long);
30static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long);
David Howellsd0016482016-08-30 20:42:14 +010031static int afs_deliver_cm_op_id(struct afs_call *);
David Howells08e0e7c2007-04-26 15:55:03 -070032
David Howells08e0e7c2007-04-26 15:55:03 -070033/* asynchronous incoming call initial processing */
34static const struct afs_call_type afs_RXCMxxxx = {
David Howells00d3b7a2007-04-26 15:57:07 -070035 .name = "CB.xxxx",
David Howells08e0e7c2007-04-26 15:55:03 -070036 .deliver = afs_deliver_cm_op_id,
37 .abort_to_error = afs_abort_to_error,
38};
39
David Howells00e90712016-09-08 11:10:12 +010040static void afs_charge_preallocation(struct work_struct *);
David Howells08e0e7c2007-04-26 15:55:03 -070041
David Howells00e90712016-09-08 11:10:12 +010042static DECLARE_WORK(afs_charge_preallocation_work, afs_charge_preallocation);
David Howells08e0e7c2007-04-26 15:55:03 -070043
David Howells2f02f7a2016-04-07 17:23:03 +010044static int afs_wait_atomic_t(atomic_t *p)
45{
46 schedule();
47 return 0;
48}
49
David Howells08e0e7c2007-04-26 15:55:03 -070050/*
51 * open an RxRPC socket and bind it to be a server for callback notifications
52 * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
53 */
54int afs_open_socket(void)
55{
56 struct sockaddr_rxrpc srx;
57 struct socket *socket;
58 int ret;
59
60 _enter("");
61
David Howells0e119b42016-06-10 22:30:37 +010062 ret = -ENOMEM;
Bhaktipriya Shridhar69ad0522016-09-04 20:53:42 +053063 afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0);
David Howells0e119b42016-06-10 22:30:37 +010064 if (!afs_async_calls)
65 goto error_0;
David Howells08e0e7c2007-04-26 15:55:03 -070066
Eric W. Biedermaneeb1bd52015-05-08 21:08:05 -050067 ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket);
David Howells0e119b42016-06-10 22:30:37 +010068 if (ret < 0)
69 goto error_1;
David Howells08e0e7c2007-04-26 15:55:03 -070070
71 socket->sk->sk_allocation = GFP_NOFS;
72
73 /* bind the callback manager's address to make this a server socket */
74 srx.srx_family = AF_RXRPC;
75 srx.srx_service = CM_SERVICE;
76 srx.transport_type = SOCK_DGRAM;
77 srx.transport_len = sizeof(srx.transport.sin);
78 srx.transport.sin.sin_family = AF_INET;
79 srx.transport.sin.sin_port = htons(AFS_CM_PORT);
80 memset(&srx.transport.sin.sin_addr, 0,
81 sizeof(srx.transport.sin.sin_addr));
82
83 ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx));
David Howells0e119b42016-06-10 22:30:37 +010084 if (ret < 0)
85 goto error_2;
86
David Howells00e90712016-09-08 11:10:12 +010087 rxrpc_kernel_new_call_notification(socket, afs_rx_new_call,
88 afs_rx_discard_new_call);
David Howellsd0016482016-08-30 20:42:14 +010089
David Howells0e119b42016-06-10 22:30:37 +010090 ret = kernel_listen(socket, INT_MAX);
91 if (ret < 0)
92 goto error_2;
David Howells08e0e7c2007-04-26 15:55:03 -070093
David Howells08e0e7c2007-04-26 15:55:03 -070094 afs_socket = socket;
David Howells00e90712016-09-08 11:10:12 +010095 afs_charge_preallocation(NULL);
David Howells08e0e7c2007-04-26 15:55:03 -070096 _leave(" = 0");
97 return 0;
David Howells0e119b42016-06-10 22:30:37 +010098
99error_2:
100 sock_release(socket);
101error_1:
102 destroy_workqueue(afs_async_calls);
103error_0:
104 _leave(" = %d", ret);
105 return ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700106}
107
108/*
109 * close the RxRPC socket AFS was using
110 */
111void afs_close_socket(void)
112{
113 _enter("");
114
David Howells341f7412017-01-05 10:38:36 +0000115 kernel_listen(afs_socket, 0);
116 flush_workqueue(afs_async_calls);
117
David Howells00e90712016-09-08 11:10:12 +0100118 if (afs_spare_incoming_call) {
David Howells341f7412017-01-05 10:38:36 +0000119 afs_put_call(afs_spare_incoming_call);
David Howells00e90712016-09-08 11:10:12 +0100120 afs_spare_incoming_call = NULL;
121 }
122
David Howellsd0016482016-08-30 20:42:14 +0100123 _debug("outstanding %u", atomic_read(&afs_outstanding_calls));
David Howells2f02f7a2016-04-07 17:23:03 +0100124 wait_on_atomic_t(&afs_outstanding_calls, afs_wait_atomic_t,
125 TASK_UNINTERRUPTIBLE);
126 _debug("no outstanding calls");
127
David Howells248f2192016-09-08 11:10:12 +0100128 kernel_sock_shutdown(afs_socket, SHUT_RDWR);
129 flush_workqueue(afs_async_calls);
David Howells08e0e7c2007-04-26 15:55:03 -0700130 sock_release(afs_socket);
131
132 _debug("dework");
133 destroy_workqueue(afs_async_calls);
134 _leave("");
135}
136
137/*
David Howells341f7412017-01-05 10:38:36 +0000138 * Allocate a call.
David Howells00d3b7a2007-04-26 15:57:07 -0700139 */
David Howells341f7412017-01-05 10:38:36 +0000140static struct afs_call *afs_alloc_call(const struct afs_call_type *type,
141 gfp_t gfp)
David Howells00d3b7a2007-04-26 15:57:07 -0700142{
David Howells341f7412017-01-05 10:38:36 +0000143 struct afs_call *call;
144 int o;
David Howells00d3b7a2007-04-26 15:57:07 -0700145
David Howells341f7412017-01-05 10:38:36 +0000146 call = kzalloc(sizeof(*call), gfp);
147 if (!call)
148 return NULL;
David Howells00d3b7a2007-04-26 15:57:07 -0700149
David Howells341f7412017-01-05 10:38:36 +0000150 call->type = type;
151 atomic_set(&call->usage, 1);
152 INIT_WORK(&call->async_work, afs_process_async_call);
153 init_waitqueue_head(&call->waitq);
David Howells2f02f7a2016-04-07 17:23:03 +0100154
David Howells341f7412017-01-05 10:38:36 +0000155 o = atomic_inc_return(&afs_outstanding_calls);
156 trace_afs_call(call, afs_call_trace_alloc, 1, o,
157 __builtin_return_address(0));
158 return call;
David Howells00d3b7a2007-04-26 15:57:07 -0700159}
160
161/*
David Howells341f7412017-01-05 10:38:36 +0000162 * Dispose of a reference on a call.
David Howells6c67c7c2014-05-21 14:48:05 +0100163 */
David Howells341f7412017-01-05 10:38:36 +0000164void afs_put_call(struct afs_call *call)
David Howells6c67c7c2014-05-21 14:48:05 +0100165{
David Howells341f7412017-01-05 10:38:36 +0000166 int n = atomic_dec_return(&call->usage);
167 int o = atomic_read(&afs_outstanding_calls);
168
169 trace_afs_call(call, afs_call_trace_put, n + 1, o,
170 __builtin_return_address(0));
171
172 ASSERTCMP(n, >=, 0);
173 if (n == 0) {
174 ASSERT(!work_pending(&call->async_work));
175 ASSERT(call->type->name != NULL);
176
177 if (call->rxcall) {
178 rxrpc_kernel_end_call(afs_socket, call->rxcall);
179 call->rxcall = NULL;
180 }
181 if (call->type->destructor)
182 call->type->destructor(call);
183
184 kfree(call->request);
185 kfree(call);
186
187 o = atomic_dec_return(&afs_outstanding_calls);
188 trace_afs_call(call, afs_call_trace_free, 0, o,
189 __builtin_return_address(0));
190 if (o == 0)
191 wake_up_atomic_t(&afs_outstanding_calls);
David Howells6c67c7c2014-05-21 14:48:05 +0100192 }
Nathaniel Wesley Filardo6cf12862014-05-21 16:04:11 +0100193}
194
195/*
David Howells341f7412017-01-05 10:38:36 +0000196 * Queue the call for actual work. Returns 0 unconditionally for convenience.
Nathaniel Wesley Filardo6cf12862014-05-21 16:04:11 +0100197 */
David Howells341f7412017-01-05 10:38:36 +0000198int afs_queue_call_work(struct afs_call *call)
Nathaniel Wesley Filardo6cf12862014-05-21 16:04:11 +0100199{
David Howells341f7412017-01-05 10:38:36 +0000200 int u = atomic_inc_return(&call->usage);
201
202 trace_afs_call(call, afs_call_trace_work, u,
203 atomic_read(&afs_outstanding_calls),
204 __builtin_return_address(0));
205
206 INIT_WORK(&call->work, call->type->work);
207
208 if (!queue_work(afs_wq, &call->work))
209 afs_put_call(call);
210 return 0;
David Howells6c67c7c2014-05-21 14:48:05 +0100211}
212
213/*
David Howells08e0e7c2007-04-26 15:55:03 -0700214 * allocate a call with flat request and reply buffers
215 */
216struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
David Howellsd0016482016-08-30 20:42:14 +0100217 size_t request_size, size_t reply_max)
David Howells08e0e7c2007-04-26 15:55:03 -0700218{
219 struct afs_call *call;
220
David Howells341f7412017-01-05 10:38:36 +0000221 call = afs_alloc_call(type, GFP_NOFS);
David Howells08e0e7c2007-04-26 15:55:03 -0700222 if (!call)
223 goto nomem_call;
224
David Howells00d3b7a2007-04-26 15:57:07 -0700225 if (request_size) {
David Howells341f7412017-01-05 10:38:36 +0000226 call->request_size = request_size;
David Howells00d3b7a2007-04-26 15:57:07 -0700227 call->request = kmalloc(request_size, GFP_NOFS);
228 if (!call->request)
229 goto nomem_free;
230 }
231
David Howellsd0016482016-08-30 20:42:14 +0100232 if (reply_max) {
David Howells341f7412017-01-05 10:38:36 +0000233 call->reply_max = reply_max;
David Howellsd0016482016-08-30 20:42:14 +0100234 call->buffer = kmalloc(reply_max, GFP_NOFS);
David Howells00d3b7a2007-04-26 15:57:07 -0700235 if (!call->buffer)
236 goto nomem_free;
237 }
238
David Howells08e0e7c2007-04-26 15:55:03 -0700239 init_waitqueue_head(&call->waitq);
David Howells08e0e7c2007-04-26 15:55:03 -0700240 return call;
241
David Howells00d3b7a2007-04-26 15:57:07 -0700242nomem_free:
David Howells341f7412017-01-05 10:38:36 +0000243 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700244nomem_call:
245 return NULL;
246}
247
248/*
249 * clean up a call with flat buffer
250 */
251void afs_flat_call_destructor(struct afs_call *call)
252{
253 _enter("");
254
255 kfree(call->request);
256 call->request = NULL;
257 kfree(call->buffer);
258 call->buffer = NULL;
259}
260
David Howells2f5705a2017-03-16 16:27:46 +0000261#define AFS_BVEC_MAX 8
262
263/*
264 * Load the given bvec with the next few pages.
265 */
266static void afs_load_bvec(struct afs_call *call, struct msghdr *msg,
267 struct bio_vec *bv, pgoff_t first, pgoff_t last,
268 unsigned offset)
269{
270 struct page *pages[AFS_BVEC_MAX];
271 unsigned int nr, n, i, to, bytes = 0;
272
273 nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX);
274 n = find_get_pages_contig(call->mapping, first, nr, pages);
275 ASSERTCMP(n, ==, nr);
276
277 msg->msg_flags |= MSG_MORE;
278 for (i = 0; i < nr; i++) {
279 to = PAGE_SIZE;
280 if (first + i >= last) {
281 to = call->last_to;
282 msg->msg_flags &= ~MSG_MORE;
283 }
284 bv[i].bv_page = pages[i];
285 bv[i].bv_len = to - offset;
286 bv[i].bv_offset = offset;
287 bytes += to - offset;
288 offset = 0;
289 }
290
291 iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, bv, nr, bytes);
292}
293
David Howells08e0e7c2007-04-26 15:55:03 -0700294/*
David Howellse8332512017-08-29 10:18:56 +0100295 * Advance the AFS call state when the RxRPC call ends the transmit phase.
296 */
297static void afs_notify_end_request_tx(struct sock *sock,
298 struct rxrpc_call *rxcall,
299 unsigned long call_user_ID)
300{
301 struct afs_call *call = (struct afs_call *)call_user_ID;
302
303 if (call->state == AFS_CALL_REQUESTING)
304 call->state = AFS_CALL_AWAIT_REPLY;
305}
306
307/*
David Howells31143d52007-05-09 02:33:46 -0700308 * attach the data from a bunch of pages on an inode to a call
309 */
Al Viro39c6ace2016-01-09 20:36:51 -0500310static int afs_send_pages(struct afs_call *call, struct msghdr *msg)
David Howells31143d52007-05-09 02:33:46 -0700311{
David Howells2f5705a2017-03-16 16:27:46 +0000312 struct bio_vec bv[AFS_BVEC_MAX];
313 unsigned int bytes, nr, loop, offset;
David Howells31143d52007-05-09 02:33:46 -0700314 pgoff_t first = call->first, last = call->last;
315 int ret;
316
David Howells31143d52007-05-09 02:33:46 -0700317 offset = call->first_offset;
318 call->first_offset = 0;
319
320 do {
David Howells2f5705a2017-03-16 16:27:46 +0000321 afs_load_bvec(call, msg, bv, first, last, offset);
322 offset = 0;
323 bytes = msg->msg_iter.count;
324 nr = msg->msg_iter.nr_segs;
David Howells31143d52007-05-09 02:33:46 -0700325
David Howellse8332512017-08-29 10:18:56 +0100326 ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, msg,
327 bytes, afs_notify_end_request_tx);
David Howells2f5705a2017-03-16 16:27:46 +0000328 for (loop = 0; loop < nr; loop++)
329 put_page(bv[loop].bv_page);
David Howells31143d52007-05-09 02:33:46 -0700330 if (ret < 0)
331 break;
David Howells2f5705a2017-03-16 16:27:46 +0000332
333 first += nr;
David Howells5bbf5d32007-05-10 03:15:23 -0700334 } while (first <= last);
David Howells31143d52007-05-09 02:33:46 -0700335
David Howells31143d52007-05-09 02:33:46 -0700336 return ret;
337}
338
339/*
David Howells08e0e7c2007-04-26 15:55:03 -0700340 * initiate a call
341 */
342int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
David Howells56ff9c82017-01-05 10:38:36 +0000343 bool async)
David Howells08e0e7c2007-04-26 15:55:03 -0700344{
345 struct sockaddr_rxrpc srx;
346 struct rxrpc_call *rxcall;
347 struct msghdr msg;
348 struct kvec iov[1];
David Howells70af0e32017-03-16 16:27:47 +0000349 size_t offset;
David Howellse754eba2017-06-07 12:40:03 +0100350 s64 tx_total_len;
David Howells70af0e32017-03-16 16:27:47 +0000351 u32 abort_code;
David Howells08e0e7c2007-04-26 15:55:03 -0700352 int ret;
353
354 _enter("%x,{%d},", addr->s_addr, ntohs(call->port));
355
David Howells00d3b7a2007-04-26 15:57:07 -0700356 ASSERT(call->type != NULL);
357 ASSERT(call->type->name != NULL);
358
David Howells31143d52007-05-09 02:33:46 -0700359 _debug("____MAKE %p{%s,%x} [%d]____",
360 call, call->type->name, key_serial(call->key),
361 atomic_read(&afs_outstanding_calls));
David Howells00d3b7a2007-04-26 15:57:07 -0700362
David Howells56ff9c82017-01-05 10:38:36 +0000363 call->async = async;
David Howells08e0e7c2007-04-26 15:55:03 -0700364
365 memset(&srx, 0, sizeof(srx));
366 srx.srx_family = AF_RXRPC;
367 srx.srx_service = call->service_id;
368 srx.transport_type = SOCK_DGRAM;
369 srx.transport_len = sizeof(srx.transport.sin);
370 srx.transport.sin.sin_family = AF_INET;
371 srx.transport.sin.sin_port = call->port;
372 memcpy(&srx.transport.sin.sin_addr, addr, 4);
373
David Howellse754eba2017-06-07 12:40:03 +0100374 /* Work out the length we're going to transmit. This is awkward for
375 * calls such as FS.StoreData where there's an extra injection of data
376 * after the initial fixed part.
377 */
378 tx_total_len = call->request_size;
379 if (call->send_pages) {
380 tx_total_len += call->last_to - call->first_offset;
381 tx_total_len += (call->last - call->first) * PAGE_SIZE;
382 }
383
David Howells08e0e7c2007-04-26 15:55:03 -0700384 /* create a call */
385 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key,
David Howellse754eba2017-06-07 12:40:03 +0100386 (unsigned long)call,
387 tx_total_len, gfp,
David Howells56ff9c82017-01-05 10:38:36 +0000388 (async ?
389 afs_wake_up_async_call :
David Howellsa68f4a22017-10-18 11:36:39 +0100390 afs_wake_up_call_waiter),
391 call->upgrade);
David Howells00d3b7a2007-04-26 15:57:07 -0700392 call->key = NULL;
David Howells08e0e7c2007-04-26 15:55:03 -0700393 if (IS_ERR(rxcall)) {
394 ret = PTR_ERR(rxcall);
395 goto error_kill_call;
396 }
397
398 call->rxcall = rxcall;
399
400 /* send the request */
401 iov[0].iov_base = call->request;
402 iov[0].iov_len = call->request_size;
403
404 msg.msg_name = NULL;
405 msg.msg_namelen = 0;
Al Viro2e90b1c2014-11-27 21:50:31 -0500406 iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1,
Al Viroc0371da2014-11-24 10:42:55 -0500407 call->request_size);
David Howells08e0e7c2007-04-26 15:55:03 -0700408 msg.msg_control = NULL;
409 msg.msg_controllen = 0;
David Howellsbc5e3a52017-10-18 11:07:31 +0100410 msg.msg_flags = MSG_WAITALL | (call->send_pages ? MSG_MORE : 0);
David Howells08e0e7c2007-04-26 15:55:03 -0700411
David Howells70af0e32017-03-16 16:27:47 +0000412 /* We have to change the state *before* sending the last packet as
413 * rxrpc might give us the reply before it returns from sending the
414 * request. Further, if the send fails, we may already have been given
415 * a notification and may have collected it.
416 */
David Howells31143d52007-05-09 02:33:46 -0700417 if (!call->send_pages)
418 call->state = AFS_CALL_AWAIT_REPLY;
David Howells4de48af2016-08-30 12:00:48 +0100419 ret = rxrpc_kernel_send_data(afs_socket, rxcall,
David Howellse8332512017-08-29 10:18:56 +0100420 &msg, call->request_size,
421 afs_notify_end_request_tx);
David Howells08e0e7c2007-04-26 15:55:03 -0700422 if (ret < 0)
423 goto error_do_abort;
424
David Howells31143d52007-05-09 02:33:46 -0700425 if (call->send_pages) {
Al Viro39c6ace2016-01-09 20:36:51 -0500426 ret = afs_send_pages(call, &msg);
David Howells31143d52007-05-09 02:33:46 -0700427 if (ret < 0)
428 goto error_do_abort;
429 }
430
David Howells08e0e7c2007-04-26 15:55:03 -0700431 /* at this point, an async call may no longer exist as it may have
432 * already completed */
David Howells56ff9c82017-01-05 10:38:36 +0000433 if (call->async)
434 return -EINPROGRESS;
435
436 return afs_wait_for_call_to_complete(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700437
438error_do_abort:
David Howells70af0e32017-03-16 16:27:47 +0000439 call->state = AFS_CALL_COMPLETE;
440 if (ret != -ECONNABORTED) {
441 rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT,
David Howells3a927892017-04-06 10:11:56 +0100442 ret, "KSD");
David Howells70af0e32017-03-16 16:27:47 +0000443 } else {
444 abort_code = 0;
445 offset = 0;
446 rxrpc_kernel_recv_data(afs_socket, rxcall, NULL, 0, &offset,
David Howellsa68f4a22017-10-18 11:36:39 +0100447 false, &abort_code, &call->service_id);
David Howells70af0e32017-03-16 16:27:47 +0000448 ret = call->type->abort_to_error(abort_code);
449 }
David Howells08e0e7c2007-04-26 15:55:03 -0700450error_kill_call:
David Howells341f7412017-01-05 10:38:36 +0000451 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700452 _leave(" = %d", ret);
453 return ret;
454}
455
456/*
David Howells08e0e7c2007-04-26 15:55:03 -0700457 * deliver messages to a call
458 */
459static void afs_deliver_to_call(struct afs_call *call)
460{
David Howells08e0e7c2007-04-26 15:55:03 -0700461 u32 abort_code;
462 int ret;
463
David Howellsd0016482016-08-30 20:42:14 +0100464 _enter("%s", call->type->name);
David Howells08e0e7c2007-04-26 15:55:03 -0700465
David Howellsd0016482016-08-30 20:42:14 +0100466 while (call->state == AFS_CALL_AWAIT_REPLY ||
467 call->state == AFS_CALL_AWAIT_OP_ID ||
468 call->state == AFS_CALL_AWAIT_REQUEST ||
469 call->state == AFS_CALL_AWAIT_ACK
470 ) {
471 if (call->state == AFS_CALL_AWAIT_ACK) {
472 size_t offset = 0;
473 ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,
474 NULL, 0, &offset, false,
David Howellsa68f4a22017-10-18 11:36:39 +0100475 &call->abort_code,
476 &call->service_id);
David Howells8e8d7f12017-01-05 10:38:34 +0000477 trace_afs_recv_data(call, 0, offset, false, ret);
478
David Howellsd0016482016-08-30 20:42:14 +0100479 if (ret == -EINPROGRESS || ret == -EAGAIN)
480 return;
David Howells9008f992016-10-06 08:11:50 +0100481 if (ret == 1 || ret < 0) {
David Howellsd0016482016-08-30 20:42:14 +0100482 call->state = AFS_CALL_COMPLETE;
483 goto done;
David Howells08e0e7c2007-04-26 15:55:03 -0700484 }
David Howellsd0016482016-08-30 20:42:14 +0100485 return;
David Howells08e0e7c2007-04-26 15:55:03 -0700486 }
487
David Howellsd0016482016-08-30 20:42:14 +0100488 ret = call->type->deliver(call);
489 switch (ret) {
490 case 0:
491 if (call->state == AFS_CALL_AWAIT_REPLY)
492 call->state = AFS_CALL_COMPLETE;
493 goto done;
494 case -EINPROGRESS:
495 case -EAGAIN:
496 goto out;
David Howells70af0e32017-03-16 16:27:47 +0000497 case -ECONNABORTED:
498 goto call_complete;
David Howellsd0016482016-08-30 20:42:14 +0100499 case -ENOTCONN:
500 abort_code = RX_CALL_DEAD;
501 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells3a927892017-04-06 10:11:56 +0100502 abort_code, ret, "KNC");
David Howells70af0e32017-03-16 16:27:47 +0000503 goto save_error;
David Howellsd0016482016-08-30 20:42:14 +0100504 case -ENOTSUPP:
David Howells1157f152017-03-16 16:27:47 +0000505 abort_code = RXGEN_OPCODE;
David Howellsd0016482016-08-30 20:42:14 +0100506 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells3a927892017-04-06 10:11:56 +0100507 abort_code, ret, "KIV");
David Howells70af0e32017-03-16 16:27:47 +0000508 goto save_error;
David Howellsd0016482016-08-30 20:42:14 +0100509 case -ENODATA:
510 case -EBADMSG:
511 case -EMSGSIZE:
512 default:
513 abort_code = RXGEN_CC_UNMARSHAL;
514 if (call->state != AFS_CALL_AWAIT_REPLY)
515 abort_code = RXGEN_SS_UNMARSHAL;
516 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells3a927892017-04-06 10:11:56 +0100517 abort_code, -EBADMSG, "KUM");
David Howells70af0e32017-03-16 16:27:47 +0000518 goto save_error;
David Howellsd0016482016-08-30 20:42:14 +0100519 }
David Howells08e0e7c2007-04-26 15:55:03 -0700520 }
521
David Howellsd0016482016-08-30 20:42:14 +0100522done:
523 if (call->state == AFS_CALL_COMPLETE && call->incoming)
David Howells341f7412017-01-05 10:38:36 +0000524 afs_put_call(call);
David Howellsd0016482016-08-30 20:42:14 +0100525out:
David Howells08e0e7c2007-04-26 15:55:03 -0700526 _leave("");
David Howellsd0016482016-08-30 20:42:14 +0100527 return;
528
David Howells70af0e32017-03-16 16:27:47 +0000529save_error:
David Howellsd0016482016-08-30 20:42:14 +0100530 call->error = ret;
David Howells70af0e32017-03-16 16:27:47 +0000531call_complete:
David Howellsd0016482016-08-30 20:42:14 +0100532 call->state = AFS_CALL_COMPLETE;
533 goto done;
David Howells08e0e7c2007-04-26 15:55:03 -0700534}
535
536/*
537 * wait synchronously for a call to complete
538 */
539static int afs_wait_for_call_to_complete(struct afs_call *call)
540{
David Howellsbc5e3a52017-10-18 11:07:31 +0100541 signed long rtt2, timeout;
David Howells08e0e7c2007-04-26 15:55:03 -0700542 int ret;
David Howellsbc5e3a52017-10-18 11:07:31 +0100543 u64 rtt;
544 u32 life, last_life;
David Howells08e0e7c2007-04-26 15:55:03 -0700545
546 DECLARE_WAITQUEUE(myself, current);
547
548 _enter("");
549
David Howellsbc5e3a52017-10-18 11:07:31 +0100550 rtt = rxrpc_kernel_get_rtt(afs_socket, call->rxcall);
551 rtt2 = nsecs_to_jiffies64(rtt) * 2;
552 if (rtt2 < 2)
553 rtt2 = 2;
554
555 timeout = rtt2;
556 last_life = rxrpc_kernel_check_life(afs_socket, call->rxcall);
557
David Howells08e0e7c2007-04-26 15:55:03 -0700558 add_wait_queue(&call->waitq, &myself);
559 for (;;) {
David Howellsbc5e3a52017-10-18 11:07:31 +0100560 set_current_state(TASK_UNINTERRUPTIBLE);
David Howells08e0e7c2007-04-26 15:55:03 -0700561
562 /* deliver any messages that are in the queue */
David Howellsd0016482016-08-30 20:42:14 +0100563 if (call->state < AFS_CALL_COMPLETE && call->need_attention) {
564 call->need_attention = false;
David Howells08e0e7c2007-04-26 15:55:03 -0700565 __set_current_state(TASK_RUNNING);
566 afs_deliver_to_call(call);
567 continue;
568 }
569
David Howellsbc5e3a52017-10-18 11:07:31 +0100570 if (call->state == AFS_CALL_COMPLETE)
David Howells08e0e7c2007-04-26 15:55:03 -0700571 break;
David Howellsbc5e3a52017-10-18 11:07:31 +0100572
573 life = rxrpc_kernel_check_life(afs_socket, call->rxcall);
574 if (timeout == 0 &&
575 life == last_life && signal_pending(current))
576 break;
577
578 if (life != last_life) {
579 timeout = rtt2;
580 last_life = life;
581 }
582
583 timeout = schedule_timeout(timeout);
David Howells08e0e7c2007-04-26 15:55:03 -0700584 }
585
586 remove_wait_queue(&call->waitq, &myself);
587 __set_current_state(TASK_RUNNING);
588
David Howells954cd6d2017-03-16 16:27:49 +0000589 /* Kill off the call if it's still live. */
David Howells08e0e7c2007-04-26 15:55:03 -0700590 if (call->state < AFS_CALL_COMPLETE) {
David Howells954cd6d2017-03-16 16:27:49 +0000591 _debug("call interrupted");
David Howellsd0016482016-08-30 20:42:14 +0100592 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells954cd6d2017-03-16 16:27:49 +0000593 RX_USER_ABORT, -EINTR, "KWI");
David Howells08e0e7c2007-04-26 15:55:03 -0700594 }
595
David Howells954cd6d2017-03-16 16:27:49 +0000596 ret = call->error;
David Howells08e0e7c2007-04-26 15:55:03 -0700597 _debug("call complete");
David Howells341f7412017-01-05 10:38:36 +0000598 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700599 _leave(" = %d", ret);
600 return ret;
601}
602
603/*
604 * wake up a waiting call
605 */
David Howellsd0016482016-08-30 20:42:14 +0100606static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall,
607 unsigned long call_user_ID)
David Howells08e0e7c2007-04-26 15:55:03 -0700608{
David Howellsd0016482016-08-30 20:42:14 +0100609 struct afs_call *call = (struct afs_call *)call_user_ID;
610
611 call->need_attention = true;
David Howells08e0e7c2007-04-26 15:55:03 -0700612 wake_up(&call->waitq);
613}
614
615/*
616 * wake up an asynchronous call
617 */
David Howellsd0016482016-08-30 20:42:14 +0100618static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
619 unsigned long call_user_ID)
David Howells08e0e7c2007-04-26 15:55:03 -0700620{
David Howellsd0016482016-08-30 20:42:14 +0100621 struct afs_call *call = (struct afs_call *)call_user_ID;
David Howells341f7412017-01-05 10:38:36 +0000622 int u;
David Howellsd0016482016-08-30 20:42:14 +0100623
David Howells8e8d7f12017-01-05 10:38:34 +0000624 trace_afs_notify_call(rxcall, call);
David Howellsd0016482016-08-30 20:42:14 +0100625 call->need_attention = true;
David Howells341f7412017-01-05 10:38:36 +0000626
627 u = __atomic_add_unless(&call->usage, 1, 0);
628 if (u != 0) {
629 trace_afs_call(call, afs_call_trace_wake, u,
630 atomic_read(&afs_outstanding_calls),
631 __builtin_return_address(0));
632
633 if (!queue_work(afs_async_calls, &call->async_work))
634 afs_put_call(call);
635 }
David Howells08e0e7c2007-04-26 15:55:03 -0700636}
637
638/*
David Howells341f7412017-01-05 10:38:36 +0000639 * Delete an asynchronous call. The work item carries a ref to the call struct
640 * that we need to release.
David Howells08e0e7c2007-04-26 15:55:03 -0700641 */
David Howellsd0016482016-08-30 20:42:14 +0100642static void afs_delete_async_call(struct work_struct *work)
David Howells08e0e7c2007-04-26 15:55:03 -0700643{
David Howellsd0016482016-08-30 20:42:14 +0100644 struct afs_call *call = container_of(work, struct afs_call, async_work);
645
David Howells08e0e7c2007-04-26 15:55:03 -0700646 _enter("");
647
David Howells341f7412017-01-05 10:38:36 +0000648 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700649
650 _leave("");
651}
652
653/*
David Howells341f7412017-01-05 10:38:36 +0000654 * Perform I/O processing on an asynchronous call. The work item carries a ref
655 * to the call struct that we either need to release or to pass on.
David Howells08e0e7c2007-04-26 15:55:03 -0700656 */
David Howellsd0016482016-08-30 20:42:14 +0100657static void afs_process_async_call(struct work_struct *work)
David Howells08e0e7c2007-04-26 15:55:03 -0700658{
David Howellsd0016482016-08-30 20:42:14 +0100659 struct afs_call *call = container_of(work, struct afs_call, async_work);
660
David Howells08e0e7c2007-04-26 15:55:03 -0700661 _enter("");
662
David Howellsd0016482016-08-30 20:42:14 +0100663 if (call->state < AFS_CALL_COMPLETE && call->need_attention) {
664 call->need_attention = false;
David Howells08e0e7c2007-04-26 15:55:03 -0700665 afs_deliver_to_call(call);
David Howellsd0016482016-08-30 20:42:14 +0100666 }
David Howells08e0e7c2007-04-26 15:55:03 -0700667
David Howells56ff9c82017-01-05 10:38:36 +0000668 if (call->state == AFS_CALL_COMPLETE) {
David Howells08e0e7c2007-04-26 15:55:03 -0700669 call->reply = NULL;
670
David Howells341f7412017-01-05 10:38:36 +0000671 /* We have two refs to release - one from the alloc and one
672 * queued with the work item - and we can't just deallocate the
673 * call because the work item may be queued again.
674 */
David Howellsd0016482016-08-30 20:42:14 +0100675 call->async_work.func = afs_delete_async_call;
David Howells341f7412017-01-05 10:38:36 +0000676 if (!queue_work(afs_async_calls, &call->async_work))
677 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700678 }
679
David Howells341f7412017-01-05 10:38:36 +0000680 afs_put_call(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700681 _leave("");
682}
683
David Howells00e90712016-09-08 11:10:12 +0100684static void afs_rx_attach(struct rxrpc_call *rxcall, unsigned long user_call_ID)
685{
686 struct afs_call *call = (struct afs_call *)user_call_ID;
687
688 call->rxcall = rxcall;
689}
690
691/*
692 * Charge the incoming call preallocation.
693 */
694static void afs_charge_preallocation(struct work_struct *work)
695{
696 struct afs_call *call = afs_spare_incoming_call;
697
698 for (;;) {
699 if (!call) {
David Howells341f7412017-01-05 10:38:36 +0000700 call = afs_alloc_call(&afs_RXCMxxxx, GFP_KERNEL);
David Howells00e90712016-09-08 11:10:12 +0100701 if (!call)
702 break;
703
David Howells56ff9c82017-01-05 10:38:36 +0000704 call->async = true;
David Howells00e90712016-09-08 11:10:12 +0100705 call->state = AFS_CALL_AWAIT_OP_ID;
David Howells56ff9c82017-01-05 10:38:36 +0000706 init_waitqueue_head(&call->waitq);
David Howells00e90712016-09-08 11:10:12 +0100707 }
708
709 if (rxrpc_kernel_charge_accept(afs_socket,
710 afs_wake_up_async_call,
711 afs_rx_attach,
712 (unsigned long)call,
713 GFP_KERNEL) < 0)
714 break;
715 call = NULL;
716 }
717 afs_spare_incoming_call = call;
718}
719
720/*
721 * Discard a preallocated call when a socket is shut down.
722 */
723static void afs_rx_discard_new_call(struct rxrpc_call *rxcall,
724 unsigned long user_call_ID)
725{
726 struct afs_call *call = (struct afs_call *)user_call_ID;
727
David Howells00e90712016-09-08 11:10:12 +0100728 call->rxcall = NULL;
David Howells341f7412017-01-05 10:38:36 +0000729 afs_put_call(call);
David Howells00e90712016-09-08 11:10:12 +0100730}
731
David Howells08e0e7c2007-04-26 15:55:03 -0700732/*
David Howellsd0016482016-08-30 20:42:14 +0100733 * Notification of an incoming call.
734 */
David Howells00e90712016-09-08 11:10:12 +0100735static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
736 unsigned long user_call_ID)
David Howellsd0016482016-08-30 20:42:14 +0100737{
David Howells00e90712016-09-08 11:10:12 +0100738 queue_work(afs_wq, &afs_charge_preallocation_work);
David Howellsd0016482016-08-30 20:42:14 +0100739}
740
741/*
David Howells372ee162016-08-03 14:11:40 +0100742 * Grab the operation ID from an incoming cache manager call. The socket
743 * buffer is discarded on error or if we don't yet have sufficient data.
David Howells08e0e7c2007-04-26 15:55:03 -0700744 */
David Howellsd0016482016-08-30 20:42:14 +0100745static int afs_deliver_cm_op_id(struct afs_call *call)
David Howells08e0e7c2007-04-26 15:55:03 -0700746{
David Howellsd0016482016-08-30 20:42:14 +0100747 int ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700748
David Howellsd0016482016-08-30 20:42:14 +0100749 _enter("{%zu}", call->offset);
David Howells08e0e7c2007-04-26 15:55:03 -0700750
751 ASSERTCMP(call->offset, <, 4);
752
753 /* the operation ID forms the first four bytes of the request data */
David Howells50a2c952016-10-13 08:27:10 +0100754 ret = afs_extract_data(call, &call->tmp, 4, true);
David Howellsd0016482016-08-30 20:42:14 +0100755 if (ret < 0)
756 return ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700757
David Howells50a2c952016-10-13 08:27:10 +0100758 call->operation_ID = ntohl(call->tmp);
David Howells08e0e7c2007-04-26 15:55:03 -0700759 call->state = AFS_CALL_AWAIT_REQUEST;
David Howellsd0016482016-08-30 20:42:14 +0100760 call->offset = 0;
David Howells08e0e7c2007-04-26 15:55:03 -0700761
762 /* ask the cache manager to route the call (it'll change the call type
763 * if successful) */
764 if (!afs_cm_incoming_call(call))
765 return -ENOTSUPP;
766
David Howells8e8d7f12017-01-05 10:38:34 +0000767 trace_afs_cb_call(call);
768
David Howells08e0e7c2007-04-26 15:55:03 -0700769 /* pass responsibility for the remainer of this message off to the
770 * cache manager op */
David Howellsd0016482016-08-30 20:42:14 +0100771 return call->type->deliver(call);
David Howells08e0e7c2007-04-26 15:55:03 -0700772}
773
774/*
David Howellse8332512017-08-29 10:18:56 +0100775 * Advance the AFS call state when an RxRPC service call ends the transmit
776 * phase.
777 */
778static void afs_notify_end_reply_tx(struct sock *sock,
779 struct rxrpc_call *rxcall,
780 unsigned long call_user_ID)
781{
782 struct afs_call *call = (struct afs_call *)call_user_ID;
783
784 if (call->state == AFS_CALL_REPLYING)
785 call->state = AFS_CALL_AWAIT_ACK;
786}
787
788/*
David Howells08e0e7c2007-04-26 15:55:03 -0700789 * send an empty reply
790 */
791void afs_send_empty_reply(struct afs_call *call)
792{
793 struct msghdr msg;
David Howells08e0e7c2007-04-26 15:55:03 -0700794
795 _enter("");
796
David Howellse754eba2017-06-07 12:40:03 +0100797 rxrpc_kernel_set_tx_length(afs_socket, call->rxcall, 0);
798
David Howells08e0e7c2007-04-26 15:55:03 -0700799 msg.msg_name = NULL;
800 msg.msg_namelen = 0;
David Howellsbfd4e952015-04-01 16:03:46 +0100801 iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, NULL, 0, 0);
David Howells08e0e7c2007-04-26 15:55:03 -0700802 msg.msg_control = NULL;
803 msg.msg_controllen = 0;
804 msg.msg_flags = 0;
805
806 call->state = AFS_CALL_AWAIT_ACK;
David Howellse8332512017-08-29 10:18:56 +0100807 switch (rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, 0,
808 afs_notify_end_reply_tx)) {
David Howells08e0e7c2007-04-26 15:55:03 -0700809 case 0:
810 _leave(" [replied]");
811 return;
812
813 case -ENOMEM:
814 _debug("oom");
David Howells4de48af2016-08-30 12:00:48 +0100815 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells3a927892017-04-06 10:11:56 +0100816 RX_USER_ABORT, -ENOMEM, "KOO");
David Howells08e0e7c2007-04-26 15:55:03 -0700817 default:
David Howells08e0e7c2007-04-26 15:55:03 -0700818 _leave(" [error]");
819 return;
820 }
821}
822
823/*
David Howellsb908fe62007-04-26 15:58:17 -0700824 * send a simple reply
825 */
826void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
827{
828 struct msghdr msg;
Al Viro2e90b1c2014-11-27 21:50:31 -0500829 struct kvec iov[1];
David Howellsbd6dc742007-07-20 10:59:41 +0100830 int n;
David Howellsb908fe62007-04-26 15:58:17 -0700831
832 _enter("");
833
David Howellse754eba2017-06-07 12:40:03 +0100834 rxrpc_kernel_set_tx_length(afs_socket, call->rxcall, len);
835
David Howellsb908fe62007-04-26 15:58:17 -0700836 iov[0].iov_base = (void *) buf;
837 iov[0].iov_len = len;
838 msg.msg_name = NULL;
839 msg.msg_namelen = 0;
Al Viro2e90b1c2014-11-27 21:50:31 -0500840 iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1, len);
David Howellsb908fe62007-04-26 15:58:17 -0700841 msg.msg_control = NULL;
842 msg.msg_controllen = 0;
843 msg.msg_flags = 0;
844
845 call->state = AFS_CALL_AWAIT_ACK;
David Howellse8332512017-08-29 10:18:56 +0100846 n = rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, len,
847 afs_notify_end_reply_tx);
David Howellsbd6dc742007-07-20 10:59:41 +0100848 if (n >= 0) {
David Howells6c67c7c2014-05-21 14:48:05 +0100849 /* Success */
David Howellsb908fe62007-04-26 15:58:17 -0700850 _leave(" [replied]");
851 return;
David Howellsbd6dc742007-07-20 10:59:41 +0100852 }
David Howells6c67c7c2014-05-21 14:48:05 +0100853
David Howellsbd6dc742007-07-20 10:59:41 +0100854 if (n == -ENOMEM) {
David Howellsb908fe62007-04-26 15:58:17 -0700855 _debug("oom");
David Howells4de48af2016-08-30 12:00:48 +0100856 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
David Howells3a927892017-04-06 10:11:56 +0100857 RX_USER_ABORT, -ENOMEM, "KOO");
David Howellsb908fe62007-04-26 15:58:17 -0700858 }
David Howellsbd6dc742007-07-20 10:59:41 +0100859 _leave(" [error]");
David Howellsb908fe62007-04-26 15:58:17 -0700860}
861
862/*
David Howells372ee162016-08-03 14:11:40 +0100863 * Extract a piece of data from the received data socket buffers.
David Howells08e0e7c2007-04-26 15:55:03 -0700864 */
David Howellsd0016482016-08-30 20:42:14 +0100865int afs_extract_data(struct afs_call *call, void *buf, size_t count,
866 bool want_more)
David Howells08e0e7c2007-04-26 15:55:03 -0700867{
David Howellsd0016482016-08-30 20:42:14 +0100868 int ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700869
David Howellsd0016482016-08-30 20:42:14 +0100870 _enter("{%s,%zu},,%zu,%d",
871 call->type->name, call->offset, count, want_more);
David Howells08e0e7c2007-04-26 15:55:03 -0700872
David Howellsd0016482016-08-30 20:42:14 +0100873 ASSERTCMP(call->offset, <=, count);
David Howells08e0e7c2007-04-26 15:55:03 -0700874
David Howellsd0016482016-08-30 20:42:14 +0100875 ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,
876 buf, count, &call->offset,
David Howellsa68f4a22017-10-18 11:36:39 +0100877 want_more, &call->abort_code,
878 &call->service_id);
David Howells8e8d7f12017-01-05 10:38:34 +0000879 trace_afs_recv_data(call, count, call->offset, want_more, ret);
David Howellsd0016482016-08-30 20:42:14 +0100880 if (ret == 0 || ret == -EAGAIN)
881 return ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700882
David Howellsd0016482016-08-30 20:42:14 +0100883 if (ret == 1) {
884 switch (call->state) {
885 case AFS_CALL_AWAIT_REPLY:
886 call->state = AFS_CALL_COMPLETE;
887 break;
888 case AFS_CALL_AWAIT_REQUEST:
889 call->state = AFS_CALL_REPLYING;
890 break;
891 default:
892 break;
893 }
894 return 0;
David Howells08e0e7c2007-04-26 15:55:03 -0700895 }
David Howellsd0016482016-08-30 20:42:14 +0100896
897 if (ret == -ECONNABORTED)
898 call->error = call->type->abort_to_error(call->abort_code);
899 else
900 call->error = ret;
901 call->state = AFS_CALL_COMPLETE;
902 return ret;
David Howells08e0e7c2007-04-26 15:55:03 -0700903}