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