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