kafsasyncd.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* kafsasyncd.c: AFS asynchronous operation daemon
  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. * The AFS async daemon is used to the following:
  13. * - probe "dead" servers to see whether they've come back to life yet.
  14. * - probe "live" servers that we haven't talked to for a while to see if they are better
  15. * candidates for serving than what we're currently using
  16. * - poll volume location servers to keep up to date volume location lists
  17. */
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <linux/sched.h>
  21. #include <linux/completion.h>
  22. #include "cell.h"
  23. #include "server.h"
  24. #include "volume.h"
  25. #include "kafsasyncd.h"
  26. #include "kafstimod.h"
  27. #include <rxrpc/call.h>
  28. #include <asm/errno.h>
  29. #include "internal.h"
  30. static DECLARE_COMPLETION(kafsasyncd_alive);
  31. static DECLARE_COMPLETION(kafsasyncd_dead);
  32. static DECLARE_WAIT_QUEUE_HEAD(kafsasyncd_sleepq);
  33. static struct task_struct *kafsasyncd_task;
  34. static int kafsasyncd_die;
  35. static int kafsasyncd(void *arg);
  36. static LIST_HEAD(kafsasyncd_async_attnq);
  37. static LIST_HEAD(kafsasyncd_async_busyq);
  38. static DEFINE_SPINLOCK(kafsasyncd_async_lock);
  39. static void kafsasyncd_null_call_attn_func(struct rxrpc_call *call)
  40. {
  41. }
  42. static void kafsasyncd_null_call_error_func(struct rxrpc_call *call)
  43. {
  44. }
  45. /*****************************************************************************/
  46. /*
  47. * start the async daemon
  48. */
  49. int afs_kafsasyncd_start(void)
  50. {
  51. int ret;
  52. ret = kernel_thread(kafsasyncd, NULL, 0);
  53. if (ret < 0)
  54. return ret;
  55. wait_for_completion(&kafsasyncd_alive);
  56. return ret;
  57. } /* end afs_kafsasyncd_start() */
  58. /*****************************************************************************/
  59. /*
  60. * stop the async daemon
  61. */
  62. void afs_kafsasyncd_stop(void)
  63. {
  64. /* get rid of my daemon */
  65. kafsasyncd_die = 1;
  66. wake_up(&kafsasyncd_sleepq);
  67. wait_for_completion(&kafsasyncd_dead);
  68. } /* end afs_kafsasyncd_stop() */
  69. /*****************************************************************************/
  70. /*
  71. * probing daemon
  72. */
  73. static int kafsasyncd(void *arg)
  74. {
  75. struct afs_async_op *op;
  76. int die;
  77. DECLARE_WAITQUEUE(myself, current);
  78. kafsasyncd_task = current;
  79. printk("kAFS: Started kafsasyncd %d\n", current->pid);
  80. daemonize("kafsasyncd");
  81. complete(&kafsasyncd_alive);
  82. /* loop around looking for things to attend to */
  83. do {
  84. set_current_state(TASK_INTERRUPTIBLE);
  85. add_wait_queue(&kafsasyncd_sleepq, &myself);
  86. for (;;) {
  87. if (!list_empty(&kafsasyncd_async_attnq) ||
  88. signal_pending(current) ||
  89. kafsasyncd_die)
  90. break;
  91. schedule();
  92. set_current_state(TASK_INTERRUPTIBLE);
  93. }
  94. remove_wait_queue(&kafsasyncd_sleepq, &myself);
  95. set_current_state(TASK_RUNNING);
  96. try_to_freeze();
  97. /* discard pending signals */
  98. afs_discard_my_signals();
  99. die = kafsasyncd_die;
  100. /* deal with the next asynchronous operation requiring
  101. * attention */
  102. if (!list_empty(&kafsasyncd_async_attnq)) {
  103. struct afs_async_op *op;
  104. _debug("@@@ Begin Asynchronous Operation");
  105. op = NULL;
  106. spin_lock(&kafsasyncd_async_lock);
  107. if (!list_empty(&kafsasyncd_async_attnq)) {
  108. op = list_entry(kafsasyncd_async_attnq.next,
  109. struct afs_async_op, link);
  110. list_del(&op->link);
  111. list_add_tail(&op->link,
  112. &kafsasyncd_async_busyq);
  113. }
  114. spin_unlock(&kafsasyncd_async_lock);
  115. _debug("@@@ Operation %p {%p}\n",
  116. op, op ? op->ops : NULL);
  117. if (op)
  118. op->ops->attend(op);
  119. _debug("@@@ End Asynchronous Operation");
  120. }
  121. } while(!die);
  122. /* need to kill all outstanding asynchronous operations before
  123. * exiting */
  124. kafsasyncd_task = NULL;
  125. spin_lock(&kafsasyncd_async_lock);
  126. /* fold the busy and attention queues together */
  127. list_splice_init(&kafsasyncd_async_busyq,
  128. &kafsasyncd_async_attnq);
  129. /* dequeue kafsasyncd from all their wait queues */
  130. list_for_each_entry(op, &kafsasyncd_async_attnq, link) {
  131. op->call->app_attn_func = kafsasyncd_null_call_attn_func;
  132. op->call->app_error_func = kafsasyncd_null_call_error_func;
  133. remove_wait_queue(&op->call->waitq, &op->waiter);
  134. }
  135. spin_unlock(&kafsasyncd_async_lock);
  136. /* abort all the operations */
  137. while (!list_empty(&kafsasyncd_async_attnq)) {
  138. op = list_entry(kafsasyncd_async_attnq.next, struct afs_async_op, link);
  139. list_del_init(&op->link);
  140. rxrpc_call_abort(op->call, -EIO);
  141. rxrpc_put_call(op->call);
  142. op->call = NULL;
  143. op->ops->discard(op);
  144. }
  145. /* and that's all */
  146. _leave("");
  147. complete_and_exit(&kafsasyncd_dead, 0);
  148. } /* end kafsasyncd() */
  149. /*****************************************************************************/
  150. /*
  151. * begin an operation
  152. * - place operation on busy queue
  153. */
  154. void afs_kafsasyncd_begin_op(struct afs_async_op *op)
  155. {
  156. _enter("");
  157. spin_lock(&kafsasyncd_async_lock);
  158. init_waitqueue_entry(&op->waiter, kafsasyncd_task);
  159. add_wait_queue(&op->call->waitq, &op->waiter);
  160. list_del(&op->link);
  161. list_add_tail(&op->link, &kafsasyncd_async_busyq);
  162. spin_unlock(&kafsasyncd_async_lock);
  163. _leave("");
  164. } /* end afs_kafsasyncd_begin_op() */
  165. /*****************************************************************************/
  166. /*
  167. * request attention for an operation
  168. * - move to attention queue
  169. */
  170. void afs_kafsasyncd_attend_op(struct afs_async_op *op)
  171. {
  172. _enter("");
  173. spin_lock(&kafsasyncd_async_lock);
  174. list_del(&op->link);
  175. list_add_tail(&op->link, &kafsasyncd_async_attnq);
  176. spin_unlock(&kafsasyncd_async_lock);
  177. wake_up(&kafsasyncd_sleepq);
  178. _leave("");
  179. } /* end afs_kafsasyncd_attend_op() */
  180. /*****************************************************************************/
  181. /*
  182. * terminate an operation
  183. * - remove from either queue
  184. */
  185. void afs_kafsasyncd_terminate_op(struct afs_async_op *op)
  186. {
  187. _enter("");
  188. spin_lock(&kafsasyncd_async_lock);
  189. if (!list_empty(&op->link)) {
  190. list_del_init(&op->link);
  191. remove_wait_queue(&op->call->waitq, &op->waiter);
  192. }
  193. spin_unlock(&kafsasyncd_async_lock);
  194. wake_up(&kafsasyncd_sleepq);
  195. _leave("");
  196. } /* end afs_kafsasyncd_terminate_op() */