Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cmservice.c
Go to the documentation of this file.
1 /* AFS Cache Manager Service
2  *
3  * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells ([email protected])
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
21 struct workqueue_struct *afs_cm_workqueue;
22 #endif /* 0 */
23 
24 static int afs_deliver_cb_init_call_back_state(struct afs_call *,
25  struct sk_buff *, bool);
26 static int afs_deliver_cb_init_call_back_state3(struct afs_call *,
27  struct sk_buff *, bool);
28 static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
29 static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
30 static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool);
31 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
32  struct sk_buff *, bool);
33 static void afs_cm_destructor(struct afs_call *);
34 
35 /*
36  * CB.CallBack operation type
37  */
38 static 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  */
48 static 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  */
58 static 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  */
68 static 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  */
78 static 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  */
88 static 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  */
99 bool 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;
113  call->type = &afs_SRXCBInitCallBackState3;
114  return true;
115  case CBProbe:
116  call->type = &afs_SRXCBProbe;
117  return true;
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  */
129 static void afs_cm_destructor(struct afs_call *call)
130 {
131  _enter("");
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, struct sk_buff *skb,
163  bool last)
164 {
165  struct afs_callback *cb;
166  struct afs_server *server;
167  struct in_addr addr;
168  __be32 *bp;
169  u32 tmp;
170  int ret, loop;
171 
172  _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
173 
174  switch (call->unmarshall) {
175  case 0:
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, skb, last, &call->tmp, 4);
183  switch (ret) {
184  case 0: break;
185  case -EAGAIN: return 0;
186  default: return ret;
187  }
188 
189  call->count = ntohl(call->tmp);
190  _debug("FID count: %u", call->count);
191  if (call->count > AFSCBMAX)
192  return -EBADMSG;
193 
194  call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
195  if (!call->buffer)
196  return -ENOMEM;
197  call->offset = 0;
198  call->unmarshall++;
199 
200  case 2:
201  _debug("extract FID array");
202  ret = afs_extract_data(call, skb, last, call->buffer,
203  call->count * 3 * 4);
204  switch (ret) {
205  case 0: break;
206  case -EAGAIN: return 0;
207  default: return ret;
208  }
209 
210  _debug("unmarshall FID array");
211  call->request = kcalloc(call->count,
212  sizeof(struct afs_callback),
213  GFP_KERNEL);
214  if (!call->request)
215  return -ENOMEM;
216 
217  cb = call->request;
218  bp = call->buffer;
219  for (loop = call->count; loop > 0; loop--, cb++) {
220  cb->fid.vid = ntohl(*bp++);
221  cb->fid.vnode = ntohl(*bp++);
222  cb->fid.unique = ntohl(*bp++);
223  cb->type = AFSCM_CB_UNTYPED;
224  }
225 
226  call->offset = 0;
227  call->unmarshall++;
228 
229  /* extract the callback array and its count in two steps */
230  case 3:
231  _debug("extract CB count");
232  ret = afs_extract_data(call, skb, last, &call->tmp, 4);
233  switch (ret) {
234  case 0: break;
235  case -EAGAIN: return 0;
236  default: return ret;
237  }
238 
239  tmp = ntohl(call->tmp);
240  _debug("CB count: %u", tmp);
241  if (tmp != call->count && tmp != 0)
242  return -EBADMSG;
243  call->offset = 0;
244  call->unmarshall++;
245  if (tmp == 0)
246  goto empty_cb_array;
247 
248  case 4:
249  _debug("extract CB array");
250  ret = afs_extract_data(call, skb, last, call->request,
251  call->count * 3 * 4);
252  switch (ret) {
253  case 0: break;
254  case -EAGAIN: return 0;
255  default: return ret;
256  }
257 
258  _debug("unmarshall CB array");
259  cb = call->request;
260  bp = call->buffer;
261  for (loop = call->count; loop > 0; loop--, cb++) {
262  cb->version = ntohl(*bp++);
263  cb->expiry = ntohl(*bp++);
264  cb->type = ntohl(*bp++);
265  }
266 
267  empty_cb_array:
268  call->offset = 0;
269  call->unmarshall++;
270 
271  case 5:
272  _debug("trailer");
273  if (skb->len != 0)
274  return -EBADMSG;
275  break;
276  }
277 
278  if (!last)
279  return 0;
280 
281  call->state = AFS_CALL_REPLYING;
282 
283  /* we'll need the file server record as that tells us which set of
284  * vnodes to operate upon */
285  memcpy(&addr, &ip_hdr(skb)->saddr, 4);
286  server = afs_find_server(&addr);
287  if (!server)
288  return -ENOTCONN;
289  call->server = server;
290 
291  INIT_WORK(&call->work, SRXAFSCB_CallBack);
292  queue_work(afs_wq, &call->work);
293  return 0;
294 }
295 
296 /*
297  * allow the fileserver to request callback state (re-)initialisation
298  */
299 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
300 {
301  struct afs_call *call = container_of(work, struct afs_call, work);
302 
303  _enter("{%p}", call->server);
304 
306  afs_send_empty_reply(call);
307  _leave("");
308 }
309 
310 /*
311  * deliver request data to a CB.InitCallBackState call
312  */
313 static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
314  struct sk_buff *skb,
315  bool last)
316 {
317  struct afs_server *server;
318  struct in_addr addr;
319 
320  _enter(",{%u},%d", skb->len, last);
321 
322  if (skb->len > 0)
323  return -EBADMSG;
324  if (!last)
325  return 0;
326 
327  /* no unmarshalling required */
328  call->state = AFS_CALL_REPLYING;
329 
330  /* we'll need the file server record as that tells us which set of
331  * vnodes to operate upon */
332  memcpy(&addr, &ip_hdr(skb)->saddr, 4);
333  server = afs_find_server(&addr);
334  if (!server)
335  return -ENOTCONN;
336  call->server = server;
337 
338  INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
339  queue_work(afs_wq, &call->work);
340  return 0;
341 }
342 
343 /*
344  * deliver request data to a CB.InitCallBackState3 call
345  */
346 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
347  struct sk_buff *skb,
348  bool last)
349 {
350  struct afs_server *server;
351  struct in_addr addr;
352 
353  _enter(",{%u},%d", skb->len, last);
354 
355  if (!last)
356  return 0;
357 
358  /* no unmarshalling required */
359  call->state = AFS_CALL_REPLYING;
360 
361  /* we'll need the file server record as that tells us which set of
362  * vnodes to operate upon */
363  memcpy(&addr, &ip_hdr(skb)->saddr, 4);
364  server = afs_find_server(&addr);
365  if (!server)
366  return -ENOTCONN;
367  call->server = server;
368 
369  INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
370  queue_work(afs_wq, &call->work);
371  return 0;
372 }
373 
374 /*
375  * allow the fileserver to see if the cache manager is still alive
376  */
377 static void SRXAFSCB_Probe(struct work_struct *work)
378 {
379  struct afs_call *call = container_of(work, struct afs_call, work);
380 
381  _enter("");
382  afs_send_empty_reply(call);
383  _leave("");
384 }
385 
386 /*
387  * deliver request data to a CB.Probe call
388  */
389 static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
390  bool last)
391 {
392  _enter(",{%u},%d", skb->len, last);
393 
394  if (skb->len > 0)
395  return -EBADMSG;
396  if (!last)
397  return 0;
398 
399  /* no unmarshalling required */
400  call->state = AFS_CALL_REPLYING;
401 
402  INIT_WORK(&call->work, SRXAFSCB_Probe);
403  queue_work(afs_wq, &call->work);
404  return 0;
405 }
406 
407 /*
408  * allow the fileserver to quickly find out if the fileserver has been rebooted
409  */
410 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
411 {
412  struct afs_call *call = container_of(work, struct afs_call, work);
413  struct afs_uuid *r = call->request;
414 
415  struct {
416  __be32 match;
417  } reply;
418 
419  _enter("");
420 
421 
422  if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
423  reply.match = htonl(0);
424  else
425  reply.match = htonl(1);
426 
427  afs_send_simple_reply(call, &reply, sizeof(reply));
428  _leave("");
429 }
430 
431 /*
432  * deliver request data to a CB.ProbeUuid call
433  */
434 static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
435  bool last)
436 {
437  struct afs_uuid *r;
438  unsigned loop;
439  __be32 *b;
440  int ret;
441 
442  _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
443 
444  if (skb->len > 0)
445  return -EBADMSG;
446  if (!last)
447  return 0;
448 
449  switch (call->unmarshall) {
450  case 0:
451  call->offset = 0;
452  call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
453  if (!call->buffer)
454  return -ENOMEM;
455  call->unmarshall++;
456 
457  case 1:
458  _debug("extract UUID");
459  ret = afs_extract_data(call, skb, last, call->buffer,
460  11 * sizeof(__be32));
461  switch (ret) {
462  case 0: break;
463  case -EAGAIN: return 0;
464  default: return ret;
465  }
466 
467  _debug("unmarshall UUID");
468  call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
469  if (!call->request)
470  return -ENOMEM;
471 
472  b = call->buffer;
473  r = call->request;
474  r->time_low = ntohl(b[0]);
475  r->time_mid = ntohl(b[1]);
476  r->time_hi_and_version = ntohl(b[2]);
477  r->clock_seq_hi_and_reserved = ntohl(b[3]);
478  r->clock_seq_low = ntohl(b[4]);
479 
480  for (loop = 0; loop < 6; loop++)
481  r->node[loop] = ntohl(b[loop + 5]);
482 
483  call->offset = 0;
484  call->unmarshall++;
485 
486  case 2:
487  _debug("trailer");
488  if (skb->len != 0)
489  return -EBADMSG;
490  break;
491  }
492 
493  if (!last)
494  return 0;
495 
496  call->state = AFS_CALL_REPLYING;
497 
498  INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
499  queue_work(afs_wq, &call->work);
500  return 0;
501 }
502 
503 /*
504  * allow the fileserver to ask about the cache manager's capabilities
505  */
506 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
507 {
508  struct afs_interface *ifs;
509  struct afs_call *call = container_of(work, struct afs_call, work);
510  int loop, nifs;
511 
512  struct {
513  struct /* InterfaceAddr */ {
514  __be32 nifs;
515  __be32 uuid[11];
516  __be32 ifaddr[32];
517  __be32 netmask[32];
518  __be32 mtu[32];
519  } ia;
520  struct /* Capabilities */ {
521  __be32 capcount;
522  __be32 caps[1];
523  } cap;
524  } reply;
525 
526  _enter("");
527 
528  nifs = 0;
529  ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
530  if (ifs) {
531  nifs = afs_get_ipv4_interfaces(ifs, 32, false);
532  if (nifs < 0) {
533  kfree(ifs);
534  ifs = NULL;
535  nifs = 0;
536  }
537  }
538 
539  memset(&reply, 0, sizeof(reply));
540  reply.ia.nifs = htonl(nifs);
541 
542  reply.ia.uuid[0] = htonl(afs_uuid.time_low);
543  reply.ia.uuid[1] = htonl(afs_uuid.time_mid);
544  reply.ia.uuid[2] = htonl(afs_uuid.time_hi_and_version);
545  reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved);
546  reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low);
547  for (loop = 0; loop < 6; loop++)
548  reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]);
549 
550  if (ifs) {
551  for (loop = 0; loop < nifs; loop++) {
552  reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
553  reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
554  reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
555  }
556  kfree(ifs);
557  }
558 
559  reply.cap.capcount = htonl(1);
560  reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
561  afs_send_simple_reply(call, &reply, sizeof(reply));
562 
563  _leave("");
564 }
565 
566 /*
567  * deliver request data to a CB.TellMeAboutYourself call
568  */
569 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call,
570  struct sk_buff *skb, bool last)
571 {
572  _enter(",{%u},%d", skb->len, last);
573 
574  if (skb->len > 0)
575  return -EBADMSG;
576  if (!last)
577  return 0;
578 
579  /* no unmarshalling required */
580  call->state = AFS_CALL_REPLYING;
581 
582  INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself);
583  queue_work(afs_wq, &call->work);
584  return 0;
585 }