]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/afs/cmservice.c
ceph: fix root quota realm check
[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:
191 call->offset = 0;
192 call->unmarshall++;
193
194 /* extract the FID array and its count in two steps */
195 case 1:
196 _debug("extract FID count");
d001648e 197 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
198 if (ret < 0)
199 return ret;
1da177e4 200
08e0e7c8
DH
201 call->count = ntohl(call->tmp);
202 _debug("FID count: %u", call->count);
203 if (call->count > AFSCBMAX)
204 return -EBADMSG;
205
206 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
207 if (!call->buffer)
208 return -ENOMEM;
209 call->offset = 0;
210 call->unmarshall++;
211
212 case 2:
213 _debug("extract FID array");
d001648e
DH
214 ret = afs_extract_data(call, call->buffer,
215 call->count * 3 * 4, true);
372ee163
DH
216 if (ret < 0)
217 return ret;
1da177e4 218
08e0e7c8
DH
219 _debug("unmarshall FID array");
220 call->request = kcalloc(call->count,
221 sizeof(struct afs_callback),
222 GFP_KERNEL);
223 if (!call->request)
224 return -ENOMEM;
225
226 cb = call->request;
227 bp = call->buffer;
228 for (loop = call->count; loop > 0; loop--, cb++) {
229 cb->fid.vid = ntohl(*bp++);
230 cb->fid.vnode = ntohl(*bp++);
231 cb->fid.unique = ntohl(*bp++);
232 cb->type = AFSCM_CB_UNTYPED;
1da177e4
LT
233 }
234
08e0e7c8
DH
235 call->offset = 0;
236 call->unmarshall++;
237
238 /* extract the callback array and its count in two steps */
239 case 3:
240 _debug("extract CB count");
d001648e 241 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
242 if (ret < 0)
243 return ret;
1da177e4 244
bcd89270
MD
245 call->count2 = ntohl(call->tmp);
246 _debug("CB count: %u", call->count2);
247 if (call->count2 != call->count && call->count2 != 0)
08e0e7c8
DH
248 return -EBADMSG;
249 call->offset = 0;
250 call->unmarshall++;
08e0e7c8
DH
251
252 case 4:
253 _debug("extract CB array");
d001648e 254 ret = afs_extract_data(call, call->buffer,
bcd89270 255 call->count2 * 3 * 4, false);
372ee163
DH
256 if (ret < 0)
257 return ret;
1da177e4 258
08e0e7c8
DH
259 _debug("unmarshall CB array");
260 cb = call->request;
261 bp = call->buffer;
bcd89270 262 for (loop = call->count2; loop > 0; loop--, cb++) {
08e0e7c8
DH
263 cb->version = ntohl(*bp++);
264 cb->expiry = ntohl(*bp++);
265 cb->type = ntohl(*bp++);
266 }
1da177e4 267
08e0e7c8
DH
268 call->offset = 0;
269 call->unmarshall++;
1da177e4 270
6c67c7c3
DH
271 /* Record that the message was unmarshalled successfully so
272 * that the call destructor can know do the callback breaking
273 * work, even if the final ACK isn't received.
274 *
275 * If the step number changes, then afs_cm_destructor() must be
276 * updated also.
277 */
278 call->unmarshall++;
d001648e 279 case 5:
1da177e4
LT
280 break;
281 }
282
98bf40cd
DH
283 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
284 return -EIO;
1da177e4 285
08e0e7c8
DH
286 /* we'll need the file server record as that tells us which set of
287 * vnodes to operate upon */
98bf40cd 288 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
f044c884 289 server = afs_find_server(call->net, &srx);
08e0e7c8
DH
290 if (!server)
291 return -ENOTCONN;
d0676a16 292 call->cm_server = server;
08e0e7c8 293
341f741f 294 return afs_queue_call_work(call);
ec26815a 295}
1da177e4 296
1da177e4 297/*
08e0e7c8 298 * allow the fileserver to request callback state (re-)initialisation
1da177e4 299 */
08e0e7c8 300static void SRXAFSCB_InitCallBackState(struct work_struct *work)
1da177e4 301{
08e0e7c8 302 struct afs_call *call = container_of(work, struct afs_call, work);
1da177e4 303
d0676a16 304 _enter("{%p}", call->cm_server);
1da177e4 305
d0676a16 306 afs_init_callback_state(call->cm_server);
08e0e7c8 307 afs_send_empty_reply(call);
341f741f 308 afs_put_call(call);
08e0e7c8 309 _leave("");
ec26815a 310}
1da177e4 311
1da177e4 312/*
08e0e7c8 313 * deliver request data to a CB.InitCallBackState call
1da177e4 314 */
d001648e 315static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
1da177e4 316{
8324f0bc 317 struct sockaddr_rxrpc srx;
1da177e4 318 struct afs_server *server;
372ee163 319 int ret;
1da177e4 320
d001648e 321 _enter("");
1da177e4 322
f044c884 323 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
8324f0bc 324
d001648e 325 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
326 if (ret < 0)
327 return ret;
1da177e4 328
08e0e7c8
DH
329 /* we'll need the file server record as that tells us which set of
330 * vnodes to operate upon */
f044c884 331 server = afs_find_server(call->net, &srx);
08e0e7c8
DH
332 if (!server)
333 return -ENOTCONN;
d0676a16 334 call->cm_server = server;
1da177e4 335
341f741f 336 return afs_queue_call_work(call);
08e0e7c8 337}
1da177e4 338
c35eccb1
DH
339/*
340 * deliver request data to a CB.InitCallBackState3 call
341 */
d001648e 342static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
c35eccb1
DH
343{
344 struct afs_server *server;
41bb26f8 345 struct afs_uuid *r;
d001648e
DH
346 unsigned loop;
347 __be32 *b;
348 int ret;
c35eccb1 349
d001648e 350 _enter("");
c35eccb1 351
d001648e
DH
352 _enter("{%u}", call->unmarshall);
353
354 switch (call->unmarshall) {
355 case 0:
356 call->offset = 0;
357 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
358 if (!call->buffer)
359 return -ENOMEM;
360 call->unmarshall++;
361
362 case 1:
363 _debug("extract UUID");
364 ret = afs_extract_data(call, call->buffer,
365 11 * sizeof(__be32), false);
366 switch (ret) {
367 case 0: break;
368 case -EAGAIN: return 0;
369 default: return ret;
370 }
371
372 _debug("unmarshall UUID");
41bb26f8 373 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
d001648e
DH
374 if (!call->request)
375 return -ENOMEM;
376
377 b = call->buffer;
378 r = call->request;
ff548773
DH
379 r->time_low = b[0];
380 r->time_mid = htons(ntohl(b[1]));
381 r->time_hi_and_version = htons(ntohl(b[2]));
d001648e
DH
382 r->clock_seq_hi_and_reserved = ntohl(b[3]);
383 r->clock_seq_low = ntohl(b[4]);
384
385 for (loop = 0; loop < 6; loop++)
386 r->node[loop] = ntohl(b[loop + 5]);
387
388 call->offset = 0;
389 call->unmarshall++;
390
391 case 2:
392 break;
393 }
c35eccb1 394
98bf40cd
DH
395 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
396 return -EIO;
c35eccb1
DH
397
398 /* we'll need the file server record as that tells us which set of
399 * vnodes to operate upon */
988da1bf
DH
400 rcu_read_lock();
401 server = afs_find_server_by_uuid(call->net, call->request);
402 rcu_read_unlock();
c35eccb1
DH
403 if (!server)
404 return -ENOTCONN;
d0676a16 405 call->cm_server = server;
c35eccb1 406
341f741f 407 return afs_queue_call_work(call);
c35eccb1
DH
408}
409
08e0e7c8
DH
410/*
411 * allow the fileserver to see if the cache manager is still alive
412 */
413static void SRXAFSCB_Probe(struct work_struct *work)
414{
415 struct afs_call *call = container_of(work, struct afs_call, work);
1da177e4 416
08e0e7c8
DH
417 _enter("");
418 afs_send_empty_reply(call);
341f741f 419 afs_put_call(call);
08e0e7c8
DH
420 _leave("");
421}
1da177e4 422
08e0e7c8
DH
423/*
424 * deliver request data to a CB.Probe call
425 */
d001648e 426static int afs_deliver_cb_probe(struct afs_call *call)
08e0e7c8 427{
372ee163
DH
428 int ret;
429
d001648e 430 _enter("");
1da177e4 431
d001648e 432 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
433 if (ret < 0)
434 return ret;
1da177e4 435
98bf40cd
DH
436 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
437 return -EIO;
1da177e4 438
341f741f 439 return afs_queue_call_work(call);
ec26815a 440}
b908fe6b 441
9396d496
DH
442/*
443 * allow the fileserver to quickly find out if the fileserver has been rebooted
444 */
445static void SRXAFSCB_ProbeUuid(struct work_struct *work)
446{
447 struct afs_call *call = container_of(work, struct afs_call, work);
41bb26f8 448 struct afs_uuid *r = call->request;
9396d496
DH
449
450 struct {
451 __be32 match;
452 } reply;
453
454 _enter("");
455
f044c884 456 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
9396d496
DH
457 reply.match = htonl(0);
458 else
459 reply.match = htonl(1);
460
461 afs_send_simple_reply(call, &reply, sizeof(reply));
341f741f 462 afs_put_call(call);
9396d496
DH
463 _leave("");
464}
465
466/*
467 * deliver request data to a CB.ProbeUuid call
468 */
d001648e 469static int afs_deliver_cb_probe_uuid(struct afs_call *call)
9396d496 470{
41bb26f8 471 struct afs_uuid *r;
9396d496
DH
472 unsigned loop;
473 __be32 *b;
474 int ret;
475
d001648e 476 _enter("{%u}", call->unmarshall);
9396d496
DH
477
478 switch (call->unmarshall) {
479 case 0:
480 call->offset = 0;
481 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
482 if (!call->buffer)
483 return -ENOMEM;
484 call->unmarshall++;
485
486 case 1:
487 _debug("extract UUID");
d001648e
DH
488 ret = afs_extract_data(call, call->buffer,
489 11 * sizeof(__be32), false);
9396d496
DH
490 switch (ret) {
491 case 0: break;
492 case -EAGAIN: return 0;
493 default: return ret;
494 }
495
496 _debug("unmarshall UUID");
41bb26f8 497 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
9396d496
DH
498 if (!call->request)
499 return -ENOMEM;
500
501 b = call->buffer;
502 r = call->request;
41bb26f8
CH
503 r->time_low = ntohl(b[0]);
504 r->time_mid = ntohl(b[1]);
505 r->time_hi_and_version = ntohl(b[2]);
9396d496
DH
506 r->clock_seq_hi_and_reserved = ntohl(b[3]);
507 r->clock_seq_low = ntohl(b[4]);
508
509 for (loop = 0; loop < 6; loop++)
510 r->node[loop] = ntohl(b[loop + 5]);
511
512 call->offset = 0;
513 call->unmarshall++;
514
515 case 2:
9396d496
DH
516 break;
517 }
518
98bf40cd
DH
519 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
520 return -EIO;
9396d496 521
341f741f 522 return afs_queue_call_work(call);
9396d496
DH
523}
524
b908fe6b
DH
525/*
526 * allow the fileserver to ask about the cache manager's capabilities
527 */
7c80bcce 528static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
b908fe6b
DH
529{
530 struct afs_interface *ifs;
531 struct afs_call *call = container_of(work, struct afs_call, work);
532 int loop, nifs;
533
534 struct {
535 struct /* InterfaceAddr */ {
536 __be32 nifs;
537 __be32 uuid[11];
538 __be32 ifaddr[32];
539 __be32 netmask[32];
540 __be32 mtu[32];
541 } ia;
542 struct /* Capabilities */ {
543 __be32 capcount;
544 __be32 caps[1];
545 } cap;
546 } reply;
547
548 _enter("");
549
550 nifs = 0;
551 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
552 if (ifs) {
553 nifs = afs_get_ipv4_interfaces(ifs, 32, false);
554 if (nifs < 0) {
555 kfree(ifs);
556 ifs = NULL;
557 nifs = 0;
558 }
559 }
560
561 memset(&reply, 0, sizeof(reply));
562 reply.ia.nifs = htonl(nifs);
563
f044c884
DH
564 reply.ia.uuid[0] = call->net->uuid.time_low;
565 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
566 reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
567 reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
568 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
b908fe6b 569 for (loop = 0; loop < 6; loop++)
f044c884 570 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
b908fe6b
DH
571
572 if (ifs) {
573 for (loop = 0; loop < nifs; loop++) {
574 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
575 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
576 reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
577 }
5b35fad9 578 kfree(ifs);
b908fe6b
DH
579 }
580
581 reply.cap.capcount = htonl(1);
582 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
583 afs_send_simple_reply(call, &reply, sizeof(reply));
341f741f 584 afs_put_call(call);
b908fe6b
DH
585 _leave("");
586}
587
588/*
7c80bcce 589 * deliver request data to a CB.TellMeAboutYourself call
b908fe6b 590 */
d001648e 591static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
b908fe6b 592{
372ee163
DH
593 int ret;
594
d001648e 595 _enter("");
b908fe6b 596
d001648e 597 ret = afs_extract_data(call, NULL, 0, false);
372ee163
DH
598 if (ret < 0)
599 return ret;
b908fe6b 600
98bf40cd
DH
601 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
602 return -EIO;
b908fe6b 603
341f741f 604 return afs_queue_call_work(call);
b908fe6b 605}