xref: /openbmc/linux/fs/afs/cmservice.c (revision a17922de)
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 	.destructor	= afs_cm_destructor,
45 	.work		= SRXAFSCB_CallBack,
46 };
47 
48 /*
49  * CB.InitCallBackState operation type
50  */
51 static CM_NAME(InitCallBackState);
52 static const struct afs_call_type afs_SRXCBInitCallBackState = {
53 	.name		= afs_SRXCBInitCallBackState_name,
54 	.deliver	= afs_deliver_cb_init_call_back_state,
55 	.destructor	= afs_cm_destructor,
56 	.work		= SRXAFSCB_InitCallBackState,
57 };
58 
59 /*
60  * CB.InitCallBackState3 operation type
61  */
62 static CM_NAME(InitCallBackState3);
63 static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
64 	.name		= afs_SRXCBInitCallBackState3_name,
65 	.deliver	= afs_deliver_cb_init_call_back_state3,
66 	.destructor	= afs_cm_destructor,
67 	.work		= SRXAFSCB_InitCallBackState,
68 };
69 
70 /*
71  * CB.Probe operation type
72  */
73 static CM_NAME(Probe);
74 static const struct afs_call_type afs_SRXCBProbe = {
75 	.name		= afs_SRXCBProbe_name,
76 	.deliver	= afs_deliver_cb_probe,
77 	.destructor	= afs_cm_destructor,
78 	.work		= SRXAFSCB_Probe,
79 };
80 
81 /*
82  * CB.ProbeUuid operation type
83  */
84 static CM_NAME(ProbeUuid);
85 static const struct afs_call_type afs_SRXCBProbeUuid = {
86 	.name		= afs_SRXCBProbeUuid_name,
87 	.deliver	= afs_deliver_cb_probe_uuid,
88 	.destructor	= afs_cm_destructor,
89 	.work		= SRXAFSCB_ProbeUuid,
90 };
91 
92 /*
93  * CB.TellMeAboutYourself operation type
94  */
95 static CM_NAME(TellMeAboutYourself);
96 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
97 	.name		= afs_SRXCBTellMeAboutYourself_name,
98 	.deliver	= afs_deliver_cb_tell_me_about_yourself,
99 	.destructor	= afs_cm_destructor,
100 	.work		= SRXAFSCB_TellMeAboutYourself,
101 };
102 
103 /*
104  * route an incoming cache manager call
105  * - return T if supported, F if not
106  */
107 bool afs_cm_incoming_call(struct afs_call *call)
108 {
109 	_enter("{CB.OP %u}", call->operation_ID);
110 
111 	switch (call->operation_ID) {
112 	case CBCallBack:
113 		call->type = &afs_SRXCBCallBack;
114 		return true;
115 	case CBInitCallBackState:
116 		call->type = &afs_SRXCBInitCallBackState;
117 		return true;
118 	case CBInitCallBackState3:
119 		call->type = &afs_SRXCBInitCallBackState3;
120 		return true;
121 	case CBProbe:
122 		call->type = &afs_SRXCBProbe;
123 		return true;
124 	case CBProbeUuid:
125 		call->type = &afs_SRXCBProbeUuid;
126 		return true;
127 	case CBTellMeAboutYourself:
128 		call->type = &afs_SRXCBTellMeAboutYourself;
129 		return true;
130 	default:
131 		return false;
132 	}
133 }
134 
135 /*
136  * Clean up a cache manager call.
137  */
138 static void afs_cm_destructor(struct afs_call *call)
139 {
140 	kfree(call->buffer);
141 	call->buffer = NULL;
142 }
143 
144 /*
145  * The server supplied a list of callbacks that it wanted to break.
146  */
147 static void SRXAFSCB_CallBack(struct work_struct *work)
148 {
149 	struct afs_call *call = container_of(work, struct afs_call, work);
150 
151 	_enter("");
152 
153 	/* We need to break the callbacks before sending the reply as the
154 	 * server holds up change visibility till it receives our reply so as
155 	 * to maintain cache coherency.
156 	 */
157 	if (call->cm_server)
158 		afs_break_callbacks(call->cm_server, call->count, call->request);
159 
160 	afs_send_empty_reply(call);
161 	afs_put_call(call);
162 	_leave("");
163 }
164 
165 /*
166  * deliver request data to a CB.CallBack call
167  */
168 static int afs_deliver_cb_callback(struct afs_call *call)
169 {
170 	struct afs_callback_break *cb;
171 	struct sockaddr_rxrpc srx;
172 	__be32 *bp;
173 	int ret, loop;
174 
175 	_enter("{%u}", call->unmarshall);
176 
177 	switch (call->unmarshall) {
178 	case 0:
179 		call->offset = 0;
180 		call->unmarshall++;
181 
182 		/* extract the FID array and its count in two steps */
183 	case 1:
184 		_debug("extract FID count");
185 		ret = afs_extract_data(call, &call->tmp, 4, true);
186 		if (ret < 0)
187 			return ret;
188 
189 		call->count = ntohl(call->tmp);
190 		_debug("FID count: %u", call->count);
191 		if (call->count > AFSCBMAX)
192 			return afs_protocol_error(call, -EBADMSG);
193 
194 		call->buffer = kmalloc(array3_size(call->count, 3, 4),
195 				       GFP_KERNEL);
196 		if (!call->buffer)
197 			return -ENOMEM;
198 		call->offset = 0;
199 		call->unmarshall++;
200 
201 	case 2:
202 		_debug("extract FID array");
203 		ret = afs_extract_data(call, call->buffer,
204 				       call->count * 3 * 4, true);
205 		if (ret < 0)
206 			return ret;
207 
208 		_debug("unmarshall FID array");
209 		call->request = kcalloc(call->count,
210 					sizeof(struct afs_callback_break),
211 					GFP_KERNEL);
212 		if (!call->request)
213 			return -ENOMEM;
214 
215 		cb = call->request;
216 		bp = call->buffer;
217 		for (loop = call->count; loop > 0; loop--, cb++) {
218 			cb->fid.vid	= ntohl(*bp++);
219 			cb->fid.vnode	= ntohl(*bp++);
220 			cb->fid.unique	= ntohl(*bp++);
221 			cb->cb.type	= AFSCM_CB_UNTYPED;
222 		}
223 
224 		call->offset = 0;
225 		call->unmarshall++;
226 
227 		/* extract the callback array and its count in two steps */
228 	case 3:
229 		_debug("extract CB count");
230 		ret = afs_extract_data(call, &call->tmp, 4, true);
231 		if (ret < 0)
232 			return ret;
233 
234 		call->count2 = ntohl(call->tmp);
235 		_debug("CB count: %u", call->count2);
236 		if (call->count2 != call->count && call->count2 != 0)
237 			return afs_protocol_error(call, -EBADMSG);
238 		call->offset = 0;
239 		call->unmarshall++;
240 
241 	case 4:
242 		_debug("extract CB array");
243 		ret = afs_extract_data(call, call->buffer,
244 				       call->count2 * 3 * 4, false);
245 		if (ret < 0)
246 			return ret;
247 
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;
258 		call->unmarshall++;
259 	case 5:
260 		break;
261 	}
262 
263 	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
264 		return -EIO;
265 
266 	/* we'll need the file server record as that tells us which set of
267 	 * 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);
274 }
275 
276 /*
277  * allow the fileserver to request callback state (re-)initialisation
278  */
279 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
280 {
281 	struct afs_call *call = container_of(work, struct afs_call, work);
282 
283 	_enter("{%p}", call->cm_server);
284 
285 	if (call->cm_server)
286 		afs_init_callback_state(call->cm_server);
287 	afs_send_empty_reply(call);
288 	afs_put_call(call);
289 	_leave("");
290 }
291 
292 /*
293  * deliver request data to a CB.InitCallBackState call
294  */
295 static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
296 {
297 	struct sockaddr_rxrpc srx;
298 	int ret;
299 
300 	_enter("");
301 
302 	rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
303 
304 	ret = afs_extract_data(call, NULL, 0, false);
305 	if (ret < 0)
306 		return ret;
307 
308 	/* we'll need the file server record as that tells us which set of
309 	 * 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);
315 }
316 
317 /*
318  * deliver request data to a CB.InitCallBackState3 call
319  */
320 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
321 {
322 	struct afs_uuid *r;
323 	unsigned loop;
324 	__be32 *b;
325 	int ret;
326 
327 	_enter("");
328 
329 	_enter("{%u}", call->unmarshall);
330 
331 	switch (call->unmarshall) {
332 	case 0:
333 		call->offset = 0;
334 		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
335 		if (!call->buffer)
336 			return -ENOMEM;
337 		call->unmarshall++;
338 
339 	case 1:
340 		_debug("extract UUID");
341 		ret = afs_extract_data(call, call->buffer,
342 				       11 * sizeof(__be32), false);
343 		switch (ret) {
344 		case 0:		break;
345 		case -EAGAIN:	return 0;
346 		default:	return ret;
347 		}
348 
349 		_debug("unmarshall UUID");
350 		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
351 		if (!call->request)
352 			return -ENOMEM;
353 
354 		b = call->buffer;
355 		r = call->request;
356 		r->time_low			= b[0];
357 		r->time_mid			= htons(ntohl(b[1]));
358 		r->time_hi_and_version		= htons(ntohl(b[2]));
359 		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
360 		r->clock_seq_low		= ntohl(b[4]);
361 
362 		for (loop = 0; loop < 6; loop++)
363 			r->node[loop] = ntohl(b[loop + 5]);
364 
365 		call->offset = 0;
366 		call->unmarshall++;
367 
368 	case 2:
369 		break;
370 	}
371 
372 	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
373 		return -EIO;
374 
375 	/* we'll need the file server record as that tells us which set of
376 	 * 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);
384 }
385 
386 /*
387  * allow the fileserver to see if the cache manager is still alive
388  */
389 static void SRXAFSCB_Probe(struct work_struct *work)
390 {
391 	struct afs_call *call = container_of(work, struct afs_call, work);
392 
393 	_enter("");
394 	afs_send_empty_reply(call);
395 	afs_put_call(call);
396 	_leave("");
397 }
398 
399 /*
400  * deliver request data to a CB.Probe call
401  */
402 static int afs_deliver_cb_probe(struct afs_call *call)
403 {
404 	int ret;
405 
406 	_enter("");
407 
408 	ret = afs_extract_data(call, NULL, 0, false);
409 	if (ret < 0)
410 		return ret;
411 
412 	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
413 		return -EIO;
414 
415 	return afs_queue_call_work(call);
416 }
417 
418 /*
419  * allow the fileserver to quickly find out if the fileserver has been rebooted
420  */
421 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
422 {
423 	struct afs_call *call = container_of(work, struct afs_call, work);
424 	struct afs_uuid *r = call->request;
425 
426 	struct {
427 		__be32	match;
428 	} reply;
429 
430 	_enter("");
431 
432 	if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
433 		reply.match = htonl(0);
434 	else
435 		reply.match = htonl(1);
436 
437 	afs_send_simple_reply(call, &reply, sizeof(reply));
438 	afs_put_call(call);
439 	_leave("");
440 }
441 
442 /*
443  * deliver request data to a CB.ProbeUuid call
444  */
445 static int afs_deliver_cb_probe_uuid(struct afs_call *call)
446 {
447 	struct afs_uuid *r;
448 	unsigned loop;
449 	__be32 *b;
450 	int ret;
451 
452 	_enter("{%u}", call->unmarshall);
453 
454 	switch (call->unmarshall) {
455 	case 0:
456 		call->offset = 0;
457 		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
458 		if (!call->buffer)
459 			return -ENOMEM;
460 		call->unmarshall++;
461 
462 	case 1:
463 		_debug("extract UUID");
464 		ret = afs_extract_data(call, call->buffer,
465 				       11 * sizeof(__be32), false);
466 		switch (ret) {
467 		case 0:		break;
468 		case -EAGAIN:	return 0;
469 		default:	return ret;
470 		}
471 
472 		_debug("unmarshall UUID");
473 		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
474 		if (!call->request)
475 			return -ENOMEM;
476 
477 		b = call->buffer;
478 		r = call->request;
479 		r->time_low			= b[0];
480 		r->time_mid			= htons(ntohl(b[1]));
481 		r->time_hi_and_version		= htons(ntohl(b[2]));
482 		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
483 		r->clock_seq_low		= ntohl(b[4]);
484 
485 		for (loop = 0; loop < 6; loop++)
486 			r->node[loop] = ntohl(b[loop + 5]);
487 
488 		call->offset = 0;
489 		call->unmarshall++;
490 
491 	case 2:
492 		break;
493 	}
494 
495 	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
496 		return -EIO;
497 
498 	return afs_queue_call_work(call);
499 }
500 
501 /*
502  * allow the fileserver to ask about the cache manager's capabilities
503  */
504 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
505 {
506 	struct afs_interface *ifs;
507 	struct afs_call *call = container_of(work, struct afs_call, work);
508 	int loop, nifs;
509 
510 	struct {
511 		struct /* InterfaceAddr */ {
512 			__be32 nifs;
513 			__be32 uuid[11];
514 			__be32 ifaddr[32];
515 			__be32 netmask[32];
516 			__be32 mtu[32];
517 		} ia;
518 		struct /* Capabilities */ {
519 			__be32 capcount;
520 			__be32 caps[1];
521 		} cap;
522 	} reply;
523 
524 	_enter("");
525 
526 	nifs = 0;
527 	ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
528 	if (ifs) {
529 		nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
530 		if (nifs < 0) {
531 			kfree(ifs);
532 			ifs = NULL;
533 			nifs = 0;
534 		}
535 	}
536 
537 	memset(&reply, 0, sizeof(reply));
538 	reply.ia.nifs = htonl(nifs);
539 
540 	reply.ia.uuid[0] = call->net->uuid.time_low;
541 	reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
542 	reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
543 	reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
544 	reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
545 	for (loop = 0; loop < 6; loop++)
546 		reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
547 
548 	if (ifs) {
549 		for (loop = 0; loop < nifs; loop++) {
550 			reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
551 			reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
552 			reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
553 		}
554 		kfree(ifs);
555 	}
556 
557 	reply.cap.capcount = htonl(1);
558 	reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
559 	afs_send_simple_reply(call, &reply, sizeof(reply));
560 	afs_put_call(call);
561 	_leave("");
562 }
563 
564 /*
565  * deliver request data to a CB.TellMeAboutYourself call
566  */
567 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
568 {
569 	int ret;
570 
571 	_enter("");
572 
573 	ret = afs_extract_data(call, NULL, 0, false);
574 	if (ret < 0)
575 		return ret;
576 
577 	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
578 		return -EIO;
579 
580 	return afs_queue_call_work(call);
581 }
582