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