]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/afs/cmservice.c
afs: Introduce a file-private data record
[mirror_ubuntu-bionic-kernel.git] / fs / afs / cmservice.c
CommitLineData
ec26815a 1/* AFS Cache Manager Service
1da177e4
LT
2 *
3 * Copyright (C) 2002 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
12#include <linux/module.h>
13#include <linux/init.h>
5a0e3ad6 14#include <linux/slab.h>
1da177e4 15#include <linux/sched.h>
08e0e7c8 16#include <linux/ip.h>
1da177e4 17#include "internal.h"
08e0e7c8 18#include "afs_cm.h"
1da177e4 19
d001648e
DH
20static int afs_deliver_cb_init_call_back_state(struct afs_call *);
21static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
22static int afs_deliver_cb_probe(struct afs_call *);
23static int afs_deliver_cb_callback(struct afs_call *);
24static int afs_deliver_cb_probe_uuid(struct afs_call *);
25static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
08e0e7c8 26static void afs_cm_destructor(struct afs_call *);
341f741f
DH
27static void SRXAFSCB_CallBack(struct work_struct *);
28static void SRXAFSCB_InitCallBackState(struct work_struct *);
29static void SRXAFSCB_Probe(struct work_struct *);
30static void SRXAFSCB_ProbeUuid(struct work_struct *);
31static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
1da177e4 32
8e8d7f13
DH
33#define CM_NAME(name) \
34 const char afs_SRXCB##name##_name[] __tracepoint_string = \
35 "CB." #name
36
1da177e4 37/*
08e0e7c8 38 * CB.CallBack operation type
1da177e4 39 */
8e8d7f13 40static CM_NAME(CallBack);
08e0e7c8 41static const struct afs_call_type afs_SRXCBCallBack = {
8e8d7f13 42 .name = afs_SRXCBCallBack_name,
08e0e7c8 43 .deliver = afs_deliver_cb_callback,
08e0e7c8 44 .destructor = afs_cm_destructor,
341f741f 45 .work = SRXAFSCB_CallBack,
08e0e7c8 46};
1da177e4 47
1da177e4 48/*
08e0e7c8 49 * CB.InitCallBackState operation type
1da177e4 50 */
8e8d7f13 51static CM_NAME(InitCallBackState);
08e0e7c8 52static const struct afs_call_type afs_SRXCBInitCallBackState = {
8e8d7f13 53 .name = afs_SRXCBInitCallBackState_name,
08e0e7c8 54 .deliver = afs_deliver_cb_init_call_back_state,
08e0e7c8 55 .destructor = afs_cm_destructor,
341f741f 56 .work = SRXAFSCB_InitCallBackState,
08e0e7c8 57};
1da177e4 58
c35eccb1
DH
59/*
60 * CB.InitCallBackState3 operation type
61 */
8e8d7f13 62static CM_NAME(InitCallBackState3);
c35eccb1 63static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
8e8d7f13 64 .name = afs_SRXCBInitCallBackState3_name,
c35eccb1 65 .deliver = afs_deliver_cb_init_call_back_state3,
c35eccb1 66 .destructor = afs_cm_destructor,
341f741f 67 .work = SRXAFSCB_InitCallBackState,
c35eccb1
DH
68};
69
1da177e4 70/*
08e0e7c8 71 * CB.Probe operation type
1da177e4 72 */
8e8d7f13 73static CM_NAME(Probe);
08e0e7c8 74static const struct afs_call_type afs_SRXCBProbe = {
8e8d7f13 75 .name = afs_SRXCBProbe_name,
08e0e7c8 76 .deliver = afs_deliver_cb_probe,
08e0e7c8 77 .destructor = afs_cm_destructor,
341f741f 78 .work = SRXAFSCB_Probe,
08e0e7c8 79};
1da177e4 80
9396d496
DH
81/*
82 * CB.ProbeUuid operation type
83 */
8e8d7f13 84static CM_NAME(ProbeUuid);
9396d496 85static const struct afs_call_type afs_SRXCBProbeUuid = {
8e8d7f13 86 .name = afs_SRXCBProbeUuid_name,
9396d496 87 .deliver = afs_deliver_cb_probe_uuid,
9396d496 88 .destructor = afs_cm_destructor,
341f741f 89 .work = SRXAFSCB_ProbeUuid,
9396d496
DH
90};
91
b908fe6b 92/*
7c80bcce 93 * CB.TellMeAboutYourself operation type
b908fe6b 94 */
8e8d7f13 95static CM_NAME(TellMeAboutYourself);
7c80bcce 96static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
8e8d7f13 97 .name = afs_SRXCBTellMeAboutYourself_name,
7c80bcce 98 .deliver = afs_deliver_cb_tell_me_about_yourself,
b908fe6b 99 .destructor = afs_cm_destructor,
341f741f 100 .work = SRXAFSCB_TellMeAboutYourself,
b908fe6b
DH
101};
102
1da177e4 103/*
08e0e7c8
DH
104 * route an incoming cache manager call
105 * - return T if supported, F if not
1da177e4 106 */
08e0e7c8 107bool afs_cm_incoming_call(struct afs_call *call)
1da177e4 108{
50a2c953 109 _enter("{CB.OP %u}", call->operation_ID);
08e0e7c8 110
50a2c953 111 switch (call->operation_ID) {
08e0e7c8
DH
112 case CBCallBack:
113 call->type = &afs_SRXCBCallBack;
114 return true;
115 case CBInitCallBackState:
116 call->type = &afs_SRXCBInitCallBackState;
117 return true;
c35eccb1
DH
118 case CBInitCallBackState3:
119 call->type = &afs_SRXCBInitCallBackState3;
120 return true;
08e0e7c8
DH
121 case CBProbe:
122 call->type = &afs_SRXCBProbe;
123 return true;
f4b3526d
DH
124 case CBProbeUuid:
125 call->type = &afs_SRXCBProbeUuid;
126 return true;
7c80bcce
DH
127 case CBTellMeAboutYourself:
128 call->type = &afs_SRXCBTellMeAboutYourself;
b908fe6b 129 return true;
08e0e7c8
DH
130 default:
131 return false;
1da177e4 132 }
ec26815a 133}
1da177e4 134
1da177e4 135/*
08e0e7c8 136 * clean up a cache manager call
1da177e4 137 */
08e0e7c8 138static void afs_cm_destructor(struct afs_call *call)
1da177e4 139{
08e0e7c8
DH
140 _enter("");
141
6c67c7c3
DH
142 /* Break the callbacks here so that we do it after the final ACK is
143 * received. The step number here must match the final number in
144 * afs_deliver_cb_callback().
145 */
d001648e 146 if (call->unmarshall == 5) {
d0676a16
DH
147 ASSERT(call->cm_server && call->count && call->request);
148 afs_break_callbacks(call->cm_server, call->count, call->request);
6c67c7c3
DH
149 }
150
08e0e7c8
DH
151 kfree(call->buffer);
152 call->buffer = NULL;
ec26815a 153}
1da177e4 154
1da177e4 155/*
c435ee34 156 * The server supplied a list of callbacks that it wanted to break.
1da177e4 157 */
08e0e7c8 158static void SRXAFSCB_CallBack(struct work_struct *work)
1da177e4 159{
08e0e7c8 160 struct afs_call *call = container_of(work, struct afs_call, work);
1da177e4 161
08e0e7c8 162 _enter("");
1da177e4 163
08e0e7c8
DH
164 /* be sure to send the reply *before* attempting to spam the AFS server
165 * with FSFetchStatus requests on the vnodes with broken callbacks lest
166 * the AFS server get into a vicious cycle of trying to break further
167 * callbacks because it hadn't received completion of the CBCallBack op
168 * yet */
169 afs_send_empty_reply(call);
1da177e4 170
d0676a16 171 afs_break_callbacks(call->cm_server, call->count, call->request);
341f741f 172 afs_put_call(call);
08e0e7c8 173 _leave("");
ec26815a 174}
1da177e4 175
1da177e4 176/*
08e0e7c8 177 * deliver request data to a CB.CallBack call
1da177e4 178 */
d001648e 179static int afs_deliver_cb_callback(struct afs_call *call)
1da177e4 180{
8324f0bc 181 struct sockaddr_rxrpc srx;
08e0e7c8
DH
182 struct afs_callback *cb;
183 struct afs_server *server;
08e0e7c8 184 __be32 *bp;
08e0e7c8
DH
185 int ret, loop;
186
d001648e 187 _enter("{%u}", call->unmarshall);
08e0e7c8
DH
188
189 switch (call->unmarshall) {
190 case 0:
f044c884 191 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
08e0e7c8
DH
192 call->offset = 0;
193 call->unmarshall++;
194
195 /* extract the FID array and its count in two steps */
196 case 1:
197 _debug("extract FID count");
d001648e 198 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
199 if (ret < 0)
200 return ret;
1da177e4 201
08e0e7c8
DH
202 call->count = ntohl(call->tmp);
203 _debug("FID count: %u", call->count);
204 if (call->count > AFSCBMAX)
205 return -EBADMSG;
206
207 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
208 if (!call->buffer)
209 return -ENOMEM;
210 call->offset = 0;
211 call->unmarshall++;
212
213 case 2:
214 _debug("extract FID array");
d001648e
DH
215 ret = afs_extract_data(call, call->buffer,
216 call->count * 3 * 4, true);
372ee163
DH
217 if (ret < 0)
218 return ret;
1da177e4 219
08e0e7c8
DH
220 _debug("unmarshall FID array");
221 call->request = kcalloc(call->count,
222 sizeof(struct afs_callback),
223 GFP_KERNEL);
224 if (!call->request)
225 return -ENOMEM;
226
227 cb = call->request;
228 bp = call->buffer;
229 for (loop = call->count; loop > 0; loop--, cb++) {
230 cb->fid.vid = ntohl(*bp++);
231 cb->fid.vnode = ntohl(*bp++);
232 cb->fid.unique = ntohl(*bp++);
233 cb->type = AFSCM_CB_UNTYPED;
1da177e4
LT
234 }
235
08e0e7c8
DH
236 call->offset = 0;
237 call->unmarshall++;
238
239 /* extract the callback array and its count in two steps */
240 case 3:
241 _debug("extract CB count");
d001648e 242 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
243 if (ret < 0)
244 return ret;
1da177e4 245
bcd89270
MD
246 call->count2 = ntohl(call->tmp);
247 _debug("CB count: %u", call->count2);
248 if (call->count2 != call->count && call->count2 != 0)
08e0e7c8
DH
249 return -EBADMSG;
250 call->offset = 0;
251 call->unmarshall++;
08e0e7c8
DH
252
253 case 4:
254 _debug("extract CB array");
d001648e 255 ret = afs_extract_data(call, call->buffer,
bcd89270 256 call->count2 * 3 * 4, false);
372ee163
DH
257 if (ret < 0)
258 return ret;
1da177e4 259
08e0e7c8
DH
260 _debug("unmarshall CB array");
261 cb = call->request;
262 bp = call->buffer;
bcd89270 263 for (loop = call->count2; loop > 0; loop--, cb++) {
08e0e7c8
DH
264 cb->version = ntohl(*bp++);
265 cb->expiry = ntohl(*bp++);
266 cb->type = ntohl(*bp++);
267 }
1da177e4 268
08e0e7c8
DH
269 call->offset = 0;
270 call->unmarshall++;
1da177e4 271
6c67c7c3
DH
272 /* Record that the message was unmarshalled successfully so
273 * that the call destructor can know do the callback breaking
274 * work, even if the final ACK isn't received.
275 *
276 * If the step number changes, then afs_cm_destructor() must be
277 * updated also.
278 */
279 call->unmarshall++;
d001648e 280 case 5:
1da177e4
LT
281 break;
282 }
283
08e0e7c8 284 call->state = AFS_CALL_REPLYING;
1da177e4 285
08e0e7c8
DH
286 /* we'll need the file server record as that tells us which set of
287 * vnodes to operate upon */
f044c884 288 server = afs_find_server(call->net, &srx);
08e0e7c8
DH
289 if (!server)
290 return -ENOTCONN;
d0676a16 291 call->cm_server = server;
08e0e7c8 292
341f741f 293 return afs_queue_call_work(call);
ec26815a 294}
1da177e4 295
1da177e4 296/*
08e0e7c8 297 * allow the fileserver to request callback state (re-)initialisation
1da177e4 298 */
08e0e7c8 299static void SRXAFSCB_InitCallBackState(struct work_struct *work)
1da177e4 300{
08e0e7c8 301 struct afs_call *call = container_of(work, struct afs_call, work);
1da177e4 302
d0676a16 303 _enter("{%p}", call->cm_server);
1da177e4 304
d0676a16 305 afs_init_callback_state(call->cm_server);
08e0e7c8 306 afs_send_empty_reply(call);
341f741f 307 afs_put_call(call);
08e0e7c8 308 _leave("");
ec26815a 309}
1da177e4 310
1da177e4 311/*
08e0e7c8 312 * deliver request data to a CB.InitCallBackState call
1da177e4 313 */
d001648e 314static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
1da177e4 315{
8324f0bc 316 struct sockaddr_rxrpc srx;
1da177e4 317 struct afs_server *server;
372ee163 318 int ret;
1da177e4 319
d001648e 320 _enter("");
1da177e4 321
f044c884 322 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
8324f0bc 323
d001648e 324 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
325 if (ret < 0)
326 return ret;
1da177e4 327
08e0e7c8
DH
328 /* no unmarshalling required */
329 call->state = AFS_CALL_REPLYING;
1da177e4 330
08e0e7c8
DH
331 /* we'll need the file server record as that tells us which set of
332 * vnodes to operate upon */
f044c884 333 server = afs_find_server(call->net, &srx);
08e0e7c8
DH
334 if (!server)
335 return -ENOTCONN;
d0676a16 336 call->cm_server = server;
1da177e4 337
341f741f 338 return afs_queue_call_work(call);
08e0e7c8 339}
1da177e4 340
c35eccb1
DH
341/*
342 * deliver request data to a CB.InitCallBackState3 call
343 */
d001648e 344static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
c35eccb1 345{
8324f0bc 346 struct sockaddr_rxrpc srx;
c35eccb1 347 struct afs_server *server;
41bb26f8 348 struct afs_uuid *r;
d001648e
DH
349 unsigned loop;
350 __be32 *b;
351 int ret;
c35eccb1 352
d001648e 353 _enter("");
c35eccb1 354
f044c884 355 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
8324f0bc 356
d001648e
DH
357 _enter("{%u}", call->unmarshall);
358
359 switch (call->unmarshall) {
360 case 0:
361 call->offset = 0;
362 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
363 if (!call->buffer)
364 return -ENOMEM;
365 call->unmarshall++;
366
367 case 1:
368 _debug("extract UUID");
369 ret = afs_extract_data(call, call->buffer,
370 11 * sizeof(__be32), false);
371 switch (ret) {
372 case 0: break;
373 case -EAGAIN: return 0;
374 default: return ret;
375 }
376
377 _debug("unmarshall UUID");
41bb26f8 378 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
d001648e
DH
379 if (!call->request)
380 return -ENOMEM;
381
382 b = call->buffer;
383 r = call->request;
ff548773
DH
384 r->time_low = b[0];
385 r->time_mid = htons(ntohl(b[1]));
386 r->time_hi_and_version = htons(ntohl(b[2]));
d001648e
DH
387 r->clock_seq_hi_and_reserved = ntohl(b[3]);
388 r->clock_seq_low = ntohl(b[4]);
389
390 for (loop = 0; loop < 6; loop++)
391 r->node[loop] = ntohl(b[loop + 5]);
392
393 call->offset = 0;
394 call->unmarshall++;
395
396 case 2:
397 break;
398 }
c35eccb1
DH
399
400 /* no unmarshalling required */
401 call->state = AFS_CALL_REPLYING;
402
403 /* we'll need the file server record as that tells us which set of
404 * vnodes to operate upon */
f044c884 405 server = afs_find_server(call->net, &srx);
c35eccb1
DH
406 if (!server)
407 return -ENOTCONN;
d0676a16 408 call->cm_server = server;
c35eccb1 409
341f741f 410 return afs_queue_call_work(call);
c35eccb1
DH
411}
412
08e0e7c8
DH
413/*
414 * allow the fileserver to see if the cache manager is still alive
415 */
416static void SRXAFSCB_Probe(struct work_struct *work)
417{
418 struct afs_call *call = container_of(work, struct afs_call, work);
1da177e4 419
08e0e7c8
DH
420 _enter("");
421 afs_send_empty_reply(call);
341f741f 422 afs_put_call(call);
08e0e7c8
DH
423 _leave("");
424}
1da177e4 425
08e0e7c8
DH
426/*
427 * deliver request data to a CB.Probe call
428 */
d001648e 429static int afs_deliver_cb_probe(struct afs_call *call)
08e0e7c8 430{
372ee163
DH
431 int ret;
432
d001648e 433 _enter("");
1da177e4 434
d001648e 435 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
436 if (ret < 0)
437 return ret;
1da177e4 438
08e0e7c8
DH
439 /* no unmarshalling required */
440 call->state = AFS_CALL_REPLYING;
1da177e4 441
341f741f 442 return afs_queue_call_work(call);
ec26815a 443}
b908fe6b 444
9396d496
DH
445/*
446 * allow the fileserver to quickly find out if the fileserver has been rebooted
447 */
448static void SRXAFSCB_ProbeUuid(struct work_struct *work)
449{
450 struct afs_call *call = container_of(work, struct afs_call, work);
41bb26f8 451 struct afs_uuid *r = call->request;
9396d496
DH
452
453 struct {
454 __be32 match;
455 } reply;
456
457 _enter("");
458
f044c884 459 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
9396d496
DH
460 reply.match = htonl(0);
461 else
462 reply.match = htonl(1);
463
464 afs_send_simple_reply(call, &reply, sizeof(reply));
341f741f 465 afs_put_call(call);
9396d496
DH
466 _leave("");
467}
468
469/*
470 * deliver request data to a CB.ProbeUuid call
471 */
d001648e 472static int afs_deliver_cb_probe_uuid(struct afs_call *call)
9396d496 473{
41bb26f8 474 struct afs_uuid *r;
9396d496
DH
475 unsigned loop;
476 __be32 *b;
477 int ret;
478
d001648e 479 _enter("{%u}", call->unmarshall);
9396d496
DH
480
481 switch (call->unmarshall) {
482 case 0:
483 call->offset = 0;
484 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
485 if (!call->buffer)
486 return -ENOMEM;
487 call->unmarshall++;
488
489 case 1:
490 _debug("extract UUID");
d001648e
DH
491 ret = afs_extract_data(call, call->buffer,
492 11 * sizeof(__be32), false);
9396d496
DH
493 switch (ret) {
494 case 0: break;
495 case -EAGAIN: return 0;
496 default: return ret;
497 }
498
499 _debug("unmarshall UUID");
41bb26f8 500 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
9396d496
DH
501 if (!call->request)
502 return -ENOMEM;
503
504 b = call->buffer;
505 r = call->request;
41bb26f8
CH
506 r->time_low = ntohl(b[0]);
507 r->time_mid = ntohl(b[1]);
508 r->time_hi_and_version = ntohl(b[2]);
9396d496
DH
509 r->clock_seq_hi_and_reserved = ntohl(b[3]);
510 r->clock_seq_low = ntohl(b[4]);
511
512 for (loop = 0; loop < 6; loop++)
513 r->node[loop] = ntohl(b[loop + 5]);
514
515 call->offset = 0;
516 call->unmarshall++;
517
518 case 2:
9396d496
DH
519 break;
520 }
521
9396d496
DH
522 call->state = AFS_CALL_REPLYING;
523
341f741f 524 return afs_queue_call_work(call);
9396d496
DH
525}
526
b908fe6b
DH
527/*
528 * allow the fileserver to ask about the cache manager's capabilities
529 */
7c80bcce 530static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
b908fe6b
DH
531{
532 struct afs_interface *ifs;
533 struct afs_call *call = container_of(work, struct afs_call, work);
534 int loop, nifs;
535
536 struct {
537 struct /* InterfaceAddr */ {
538 __be32 nifs;
539 __be32 uuid[11];
540 __be32 ifaddr[32];
541 __be32 netmask[32];
542 __be32 mtu[32];
543 } ia;
544 struct /* Capabilities */ {
545 __be32 capcount;
546 __be32 caps[1];
547 } cap;
548 } reply;
549
550 _enter("");
551
552 nifs = 0;
553 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
554 if (ifs) {
555 nifs = afs_get_ipv4_interfaces(ifs, 32, false);
556 if (nifs < 0) {
557 kfree(ifs);
558 ifs = NULL;
559 nifs = 0;
560 }
561 }
562
563 memset(&reply, 0, sizeof(reply));
564 reply.ia.nifs = htonl(nifs);
565
f044c884
DH
566 reply.ia.uuid[0] = call->net->uuid.time_low;
567 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
568 reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
569 reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
570 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
b908fe6b 571 for (loop = 0; loop < 6; loop++)
f044c884 572 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
b908fe6b
DH
573
574 if (ifs) {
575 for (loop = 0; loop < nifs; loop++) {
576 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
577 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
578 reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
579 }
5b35fad9 580 kfree(ifs);
b908fe6b
DH
581 }
582
583 reply.cap.capcount = htonl(1);
584 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
585 afs_send_simple_reply(call, &reply, sizeof(reply));
341f741f 586 afs_put_call(call);
b908fe6b
DH
587 _leave("");
588}
589
590/*
7c80bcce 591 * deliver request data to a CB.TellMeAboutYourself call
b908fe6b 592 */
d001648e 593static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
b908fe6b 594{
372ee163
DH
595 int ret;
596
d001648e 597 _enter("");
b908fe6b 598
d001648e 599 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
600 if (ret < 0)
601 return ret;
b908fe6b
DH
602
603 /* no unmarshalling required */
604 call->state = AFS_CALL_REPLYING;
605
341f741f 606 return afs_queue_call_work(call);
b908fe6b 607}