hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/afs/cmservice.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* AFS Cache Manager Service
23 *
34 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
45 * 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.
106 */
117
128 #include <linux/module.h>
....@@ -16,6 +12,7 @@
1612 #include <linux/ip.h>
1713 #include "internal.h"
1814 #include "afs_cm.h"
15
+#include "protocol_yfs.h"
1916
2017 static int afs_deliver_cb_init_call_back_state(struct afs_call *);
2118 static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
....@@ -30,16 +27,13 @@
3027 static void SRXAFSCB_ProbeUuid(struct work_struct *);
3128 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
3229
33
-#define CM_NAME(name) \
34
- const char afs_SRXCB##name##_name[] __tracepoint_string = \
35
- "CB." #name
30
+static int afs_deliver_yfs_cb_callback(struct afs_call *);
3631
3732 /*
3833 * CB.CallBack operation type
3934 */
40
-static CM_NAME(CallBack);
4135 static const struct afs_call_type afs_SRXCBCallBack = {
42
- .name = afs_SRXCBCallBack_name,
36
+ .name = "CB.CallBack",
4337 .deliver = afs_deliver_cb_callback,
4438 .destructor = afs_cm_destructor,
4539 .work = SRXAFSCB_CallBack,
....@@ -48,9 +42,8 @@
4842 /*
4943 * CB.InitCallBackState operation type
5044 */
51
-static CM_NAME(InitCallBackState);
5245 static const struct afs_call_type afs_SRXCBInitCallBackState = {
53
- .name = afs_SRXCBInitCallBackState_name,
46
+ .name = "CB.InitCallBackState",
5447 .deliver = afs_deliver_cb_init_call_back_state,
5548 .destructor = afs_cm_destructor,
5649 .work = SRXAFSCB_InitCallBackState,
....@@ -59,9 +52,8 @@
5952 /*
6053 * CB.InitCallBackState3 operation type
6154 */
62
-static CM_NAME(InitCallBackState3);
6355 static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
64
- .name = afs_SRXCBInitCallBackState3_name,
56
+ .name = "CB.InitCallBackState3",
6557 .deliver = afs_deliver_cb_init_call_back_state3,
6658 .destructor = afs_cm_destructor,
6759 .work = SRXAFSCB_InitCallBackState,
....@@ -70,9 +62,8 @@
7062 /*
7163 * CB.Probe operation type
7264 */
73
-static CM_NAME(Probe);
7465 static const struct afs_call_type afs_SRXCBProbe = {
75
- .name = afs_SRXCBProbe_name,
66
+ .name = "CB.Probe",
7667 .deliver = afs_deliver_cb_probe,
7768 .destructor = afs_cm_destructor,
7869 .work = SRXAFSCB_Probe,
....@@ -81,9 +72,8 @@
8172 /*
8273 * CB.ProbeUuid operation type
8374 */
84
-static CM_NAME(ProbeUuid);
8575 static const struct afs_call_type afs_SRXCBProbeUuid = {
86
- .name = afs_SRXCBProbeUuid_name,
76
+ .name = "CB.ProbeUuid",
8777 .deliver = afs_deliver_cb_probe_uuid,
8878 .destructor = afs_cm_destructor,
8979 .work = SRXAFSCB_ProbeUuid,
....@@ -92,12 +82,21 @@
9282 /*
9383 * CB.TellMeAboutYourself operation type
9484 */
95
-static CM_NAME(TellMeAboutYourself);
9685 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
97
- .name = afs_SRXCBTellMeAboutYourself_name,
86
+ .name = "CB.TellMeAboutYourself",
9887 .deliver = afs_deliver_cb_tell_me_about_yourself,
9988 .destructor = afs_cm_destructor,
10089 .work = SRXAFSCB_TellMeAboutYourself,
90
+};
91
+
92
+/*
93
+ * YFS CB.CallBack operation type
94
+ */
95
+static const struct afs_call_type afs_SRXYFSCB_CallBack = {
96
+ .name = "YFSCB.CallBack",
97
+ .deliver = afs_deliver_yfs_cb_callback,
98
+ .destructor = afs_cm_destructor,
99
+ .work = SRXAFSCB_CallBack,
101100 };
102101
103102 /*
....@@ -106,7 +105,7 @@
106105 */
107106 bool afs_cm_incoming_call(struct afs_call *call)
108107 {
109
- _enter("{CB.OP %u}", call->operation_ID);
108
+ _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);
110109
111110 switch (call->operation_ID) {
112111 case CBCallBack:
....@@ -127,9 +126,56 @@
127126 case CBTellMeAboutYourself:
128127 call->type = &afs_SRXCBTellMeAboutYourself;
129128 return true;
129
+ case YFSCBCallBack:
130
+ if (call->service_id != YFS_CM_SERVICE)
131
+ return false;
132
+ call->type = &afs_SRXYFSCB_CallBack;
133
+ return true;
130134 default:
131135 return false;
132136 }
137
+}
138
+
139
+/*
140
+ * Find the server record by peer address and record a probe to the cache
141
+ * manager from a server.
142
+ */
143
+static int afs_find_cm_server_by_peer(struct afs_call *call)
144
+{
145
+ struct sockaddr_rxrpc srx;
146
+ struct afs_server *server;
147
+
148
+ rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
149
+
150
+ server = afs_find_server(call->net, &srx);
151
+ if (!server) {
152
+ trace_afs_cm_no_server(call, &srx);
153
+ return 0;
154
+ }
155
+
156
+ call->server = server;
157
+ return 0;
158
+}
159
+
160
+/*
161
+ * Find the server record by server UUID and record a probe to the cache
162
+ * manager from a server.
163
+ */
164
+static int afs_find_cm_server_by_uuid(struct afs_call *call,
165
+ struct afs_uuid *uuid)
166
+{
167
+ struct afs_server *server;
168
+
169
+ rcu_read_lock();
170
+ server = afs_find_server_by_uuid(call->net, call->request);
171
+ rcu_read_unlock();
172
+ if (!server) {
173
+ trace_afs_cm_no_server_u(call, call->request);
174
+ return 0;
175
+ }
176
+
177
+ call->server = server;
178
+ return 0;
133179 }
134180
135181 /*
....@@ -139,6 +185,17 @@
139185 {
140186 kfree(call->buffer);
141187 call->buffer = NULL;
188
+}
189
+
190
+/*
191
+ * Abort a service call from within an action function.
192
+ */
193
+static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error,
194
+ const char *why)
195
+{
196
+ rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
197
+ abort_code, error, why);
198
+ afs_set_call_complete(call, error, 0);
142199 }
143200
144201 /*
....@@ -154,8 +211,13 @@
154211 * server holds up change visibility till it receives our reply so as
155212 * to maintain cache coherency.
156213 */
157
- if (call->cm_server)
158
- afs_break_callbacks(call->cm_server, call->count, call->request);
214
+ if (call->server) {
215
+ trace_afs_server(call->server,
216
+ atomic_read(&call->server->ref),
217
+ atomic_read(&call->server->active),
218
+ afs_server_trace_callback);
219
+ afs_break_callbacks(call->server, call->count, call->request);
220
+ }
159221
160222 afs_send_empty_reply(call);
161223 afs_put_call(call);
....@@ -168,7 +230,6 @@
168230 static int afs_deliver_cb_callback(struct afs_call *call)
169231 {
170232 struct afs_callback_break *cb;
171
- struct sockaddr_rxrpc srx;
172233 __be32 *bp;
173234 int ret, loop;
174235
....@@ -176,32 +237,33 @@
176237
177238 switch (call->unmarshall) {
178239 case 0:
179
- call->offset = 0;
240
+ afs_extract_to_tmp(call);
180241 call->unmarshall++;
181242
182243 /* extract the FID array and its count in two steps */
244
+ fallthrough;
183245 case 1:
184246 _debug("extract FID count");
185
- ret = afs_extract_data(call, &call->tmp, 4, true);
247
+ ret = afs_extract_data(call, true);
186248 if (ret < 0)
187249 return ret;
188250
189251 call->count = ntohl(call->tmp);
190252 _debug("FID count: %u", call->count);
191253 if (call->count > AFSCBMAX)
192
- return afs_protocol_error(call, -EBADMSG);
254
+ return afs_protocol_error(call, afs_eproto_cb_fid_count);
193255
194256 call->buffer = kmalloc(array3_size(call->count, 3, 4),
195257 GFP_KERNEL);
196258 if (!call->buffer)
197259 return -ENOMEM;
198
- call->offset = 0;
260
+ afs_extract_to_buf(call, call->count * 3 * 4);
199261 call->unmarshall++;
200262
263
+ fallthrough;
201264 case 2:
202265 _debug("extract FID array");
203
- ret = afs_extract_data(call, call->buffer,
204
- call->count * 3 * 4, true);
266
+ ret = afs_extract_data(call, true);
205267 if (ret < 0)
206268 return ret;
207269
....@@ -218,59 +280,47 @@
218280 cb->fid.vid = ntohl(*bp++);
219281 cb->fid.vnode = ntohl(*bp++);
220282 cb->fid.unique = ntohl(*bp++);
221
- cb->cb.type = AFSCM_CB_UNTYPED;
222283 }
223284
224
- call->offset = 0;
285
+ afs_extract_to_tmp(call);
225286 call->unmarshall++;
226287
227288 /* extract the callback array and its count in two steps */
289
+ fallthrough;
228290 case 3:
229291 _debug("extract CB count");
230
- ret = afs_extract_data(call, &call->tmp, 4, true);
292
+ ret = afs_extract_data(call, true);
231293 if (ret < 0)
232294 return ret;
233295
234296 call->count2 = ntohl(call->tmp);
235297 _debug("CB count: %u", call->count2);
236298 if (call->count2 != call->count && call->count2 != 0)
237
- return afs_protocol_error(call, -EBADMSG);
238
- call->offset = 0;
299
+ return afs_protocol_error(call, afs_eproto_cb_count);
300
+ call->iter = &call->def_iter;
301
+ iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4);
239302 call->unmarshall++;
240303
304
+ fallthrough;
241305 case 4:
242
- _debug("extract CB array");
243
- ret = afs_extract_data(call, call->buffer,
244
- call->count2 * 3 * 4, false);
306
+ _debug("extract discard %zu/%u",
307
+ iov_iter_count(call->iter), call->count2 * 3 * 4);
308
+
309
+ ret = afs_extract_data(call, false);
245310 if (ret < 0)
246311 return ret;
247312
248
- _debug("unmarshall CB array");
249
- cb = call->request;
250
- bp = call->buffer;
251
- for (loop = call->count2; loop > 0; loop--, cb++) {
252
- cb->cb.version = ntohl(*bp++);
253
- cb->cb.expiry = ntohl(*bp++);
254
- cb->cb.type = ntohl(*bp++);
255
- }
256
-
257
- call->offset = 0;
258313 call->unmarshall++;
259314 case 5:
260315 break;
261316 }
262317
263318 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
264
- return -EIO;
319
+ return afs_io_error(call, afs_io_error_cm_reply);
265320
266321 /* we'll need the file server record as that tells us which set of
267322 * vnodes to operate upon */
268
- rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
269
- call->cm_server = afs_find_server(call->net, &srx);
270
- if (!call->cm_server)
271
- trace_afs_cm_no_server(call, &srx);
272
-
273
- return afs_queue_call_work(call);
323
+ return afs_find_cm_server_by_peer(call);
274324 }
275325
276326 /*
....@@ -280,10 +330,10 @@
280330 {
281331 struct afs_call *call = container_of(work, struct afs_call, work);
282332
283
- _enter("{%p}", call->cm_server);
333
+ _enter("{%p}", call->server);
284334
285
- if (call->cm_server)
286
- afs_init_callback_state(call->cm_server);
335
+ if (call->server)
336
+ afs_init_callback_state(call->server);
287337 afs_send_empty_reply(call);
288338 afs_put_call(call);
289339 _leave("");
....@@ -294,24 +344,18 @@
294344 */
295345 static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
296346 {
297
- struct sockaddr_rxrpc srx;
298347 int ret;
299348
300349 _enter("");
301350
302
- rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
303
-
304
- ret = afs_extract_data(call, NULL, 0, false);
351
+ afs_extract_discard(call, 0);
352
+ ret = afs_extract_data(call, false);
305353 if (ret < 0)
306354 return ret;
307355
308356 /* we'll need the file server record as that tells us which set of
309357 * vnodes to operate upon */
310
- call->cm_server = afs_find_server(call->net, &srx);
311
- if (!call->cm_server)
312
- trace_afs_cm_no_server(call, &srx);
313
-
314
- return afs_queue_call_work(call);
358
+ return afs_find_cm_server_by_peer(call);
315359 }
316360
317361 /*
....@@ -330,16 +374,16 @@
330374
331375 switch (call->unmarshall) {
332376 case 0:
333
- call->offset = 0;
334377 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
335378 if (!call->buffer)
336379 return -ENOMEM;
380
+ afs_extract_to_buf(call, 11 * sizeof(__be32));
337381 call->unmarshall++;
338382
383
+ fallthrough;
339384 case 1:
340385 _debug("extract UUID");
341
- ret = afs_extract_data(call, call->buffer,
342
- 11 * sizeof(__be32), false);
386
+ ret = afs_extract_data(call, false);
343387 switch (ret) {
344388 case 0: break;
345389 case -EAGAIN: return 0;
....@@ -362,7 +406,6 @@
362406 for (loop = 0; loop < 6; loop++)
363407 r->node[loop] = ntohl(b[loop + 5]);
364408
365
- call->offset = 0;
366409 call->unmarshall++;
367410
368411 case 2:
....@@ -370,17 +413,11 @@
370413 }
371414
372415 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
373
- return -EIO;
416
+ return afs_io_error(call, afs_io_error_cm_reply);
374417
375418 /* we'll need the file server record as that tells us which set of
376419 * vnodes to operate upon */
377
- rcu_read_lock();
378
- call->cm_server = afs_find_server_by_uuid(call->net, call->request);
379
- rcu_read_unlock();
380
- if (!call->cm_server)
381
- trace_afs_cm_no_server_u(call, call->request);
382
-
383
- return afs_queue_call_work(call);
420
+ return afs_find_cm_server_by_uuid(call, call->request);
384421 }
385422
386423 /*
....@@ -405,18 +442,19 @@
405442
406443 _enter("");
407444
408
- ret = afs_extract_data(call, NULL, 0, false);
445
+ afs_extract_discard(call, 0);
446
+ ret = afs_extract_data(call, false);
409447 if (ret < 0)
410448 return ret;
411449
412450 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
413
- return -EIO;
414
-
415
- return afs_queue_call_work(call);
451
+ return afs_io_error(call, afs_io_error_cm_reply);
452
+ return afs_find_cm_server_by_peer(call);
416453 }
417454
418455 /*
419
- * allow the fileserver to quickly find out if the fileserver has been rebooted
456
+ * Allow the fileserver to quickly find out if the cache manager has been
457
+ * rebooted.
420458 */
421459 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
422460 {
....@@ -428,8 +466,7 @@
428466 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
429467 afs_send_empty_reply(call);
430468 else
431
- rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
432
- 1, 1, "K-1");
469
+ afs_abort_service_call(call, 1, 1, "K-1");
433470
434471 afs_put_call(call);
435472 _leave("");
....@@ -449,16 +486,16 @@
449486
450487 switch (call->unmarshall) {
451488 case 0:
452
- call->offset = 0;
453489 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
454490 if (!call->buffer)
455491 return -ENOMEM;
492
+ afs_extract_to_buf(call, 11 * sizeof(__be32));
456493 call->unmarshall++;
457494
495
+ fallthrough;
458496 case 1:
459497 _debug("extract UUID");
460
- ret = afs_extract_data(call, call->buffer,
461
- 11 * sizeof(__be32), false);
498
+ ret = afs_extract_data(call, false);
462499 switch (ret) {
463500 case 0: break;
464501 case -EAGAIN: return 0;
....@@ -481,7 +518,6 @@
481518 for (loop = 0; loop < 6; loop++)
482519 r->node[loop] = ntohl(b[loop + 5]);
483520
484
- call->offset = 0;
485521 call->unmarshall++;
486522
487523 case 2:
....@@ -489,9 +525,8 @@
489525 }
490526
491527 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
492
- return -EIO;
493
-
494
- return afs_queue_call_work(call);
528
+ return afs_io_error(call, afs_io_error_cm_reply);
529
+ return afs_find_cm_server_by_peer(call);
495530 }
496531
497532 /*
....@@ -499,9 +534,8 @@
499534 */
500535 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
501536 {
502
- struct afs_interface *ifs;
503537 struct afs_call *call = container_of(work, struct afs_call, work);
504
- int loop, nifs;
538
+ int loop;
505539
506540 struct {
507541 struct /* InterfaceAddr */ {
....@@ -519,19 +553,7 @@
519553
520554 _enter("");
521555
522
- nifs = 0;
523
- ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
524
- if (ifs) {
525
- nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
526
- if (nifs < 0) {
527
- kfree(ifs);
528
- ifs = NULL;
529
- nifs = 0;
530
- }
531
- }
532
-
533556 memset(&reply, 0, sizeof(reply));
534
- reply.ia.nifs = htonl(nifs);
535557
536558 reply.ia.uuid[0] = call->net->uuid.time_low;
537559 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
....@@ -540,15 +562,6 @@
540562 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
541563 for (loop = 0; loop < 6; loop++)
542564 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
543
-
544
- if (ifs) {
545
- for (loop = 0; loop < nifs; loop++) {
546
- reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
547
- reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
548
- reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
549
- }
550
- kfree(ifs);
551
- }
552565
553566 reply.cap.capcount = htonl(1);
554567 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
....@@ -566,12 +579,89 @@
566579
567580 _enter("");
568581
569
- ret = afs_extract_data(call, NULL, 0, false);
582
+ afs_extract_discard(call, 0);
583
+ ret = afs_extract_data(call, false);
570584 if (ret < 0)
571585 return ret;
572586
573587 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
574
- return -EIO;
588
+ return afs_io_error(call, afs_io_error_cm_reply);
589
+ return afs_find_cm_server_by_peer(call);
590
+}
575591
576
- return afs_queue_call_work(call);
592
+/*
593
+ * deliver request data to a YFS CB.CallBack call
594
+ */
595
+static int afs_deliver_yfs_cb_callback(struct afs_call *call)
596
+{
597
+ struct afs_callback_break *cb;
598
+ struct yfs_xdr_YFSFid *bp;
599
+ size_t size;
600
+ int ret, loop;
601
+
602
+ _enter("{%u}", call->unmarshall);
603
+
604
+ switch (call->unmarshall) {
605
+ case 0:
606
+ afs_extract_to_tmp(call);
607
+ call->unmarshall++;
608
+
609
+ /* extract the FID array and its count in two steps */
610
+ fallthrough;
611
+ case 1:
612
+ _debug("extract FID count");
613
+ ret = afs_extract_data(call, true);
614
+ if (ret < 0)
615
+ return ret;
616
+
617
+ call->count = ntohl(call->tmp);
618
+ _debug("FID count: %u", call->count);
619
+ if (call->count > YFSCBMAX)
620
+ return afs_protocol_error(call, afs_eproto_cb_fid_count);
621
+
622
+ size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));
623
+ call->buffer = kmalloc(size, GFP_KERNEL);
624
+ if (!call->buffer)
625
+ return -ENOMEM;
626
+ afs_extract_to_buf(call, size);
627
+ call->unmarshall++;
628
+
629
+ fallthrough;
630
+ case 2:
631
+ _debug("extract FID array");
632
+ ret = afs_extract_data(call, false);
633
+ if (ret < 0)
634
+ return ret;
635
+
636
+ _debug("unmarshall FID array");
637
+ call->request = kcalloc(call->count,
638
+ sizeof(struct afs_callback_break),
639
+ GFP_KERNEL);
640
+ if (!call->request)
641
+ return -ENOMEM;
642
+
643
+ cb = call->request;
644
+ bp = call->buffer;
645
+ for (loop = call->count; loop > 0; loop--, cb++) {
646
+ cb->fid.vid = xdr_to_u64(bp->volume);
647
+ cb->fid.vnode = xdr_to_u64(bp->vnode.lo);
648
+ cb->fid.vnode_hi = ntohl(bp->vnode.hi);
649
+ cb->fid.unique = ntohl(bp->vnode.unique);
650
+ bp++;
651
+ }
652
+
653
+ afs_extract_to_tmp(call);
654
+ call->unmarshall++;
655
+
656
+ case 3:
657
+ break;
658
+ }
659
+
660
+ if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
661
+ return afs_io_error(call, afs_io_error_cm_reply);
662
+
663
+ /* We'll need the file server record as that tells us which set of
664
+ * vnodes to operate upon.
665
+ */
666
+ return afs_find_cm_server_by_peer(call);
577667 }