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