kafsasyncd.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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 <linux/freezer.h>
  23. #include "cell.h"
  24. #include "server.h"
  25. #include "volume.h"
  26. #include "kafsasyncd.h"
  27. #include "kafstimod.h"
  28. #include <rxrpc/call.h>
  29. #include <asm/errno.h>
  30. #include "internal.h"
  31. static DECLARE_COMPLETION(kafsasyncd_alive);
  32. static DECLARE_COMPLETION(kafsasyncd_dead);
  33. static DECLARE_WAIT_QUEUE_HEAD(kafsasyncd_sleepq);
  34. static struct task_struct *kafsasyncd_task;
  35. static int kafsasyncd_die;
  36. static int kafsasyncd(void *arg);
  37. static LIST_HEAD(kafsasyncd_async_attnq);
  38. static LIST_HEAD(kafsasyncd_async_busyq);
  39. static DEFINE_SPINLOCK(kafsasyncd_async_lock);
  40. static void kafsasyncd_null_call_attn_func(struct rxrpc_call *call)
  41. {
  42. }
  43. static void kafsasyncd_null_call_error_func(struct rxrpc_call *call)
  44. {
  45. }
  46. /*****************************************************************************/
  47. /*
  48. * start the async daemon
  49. */
  50. int afs_kafsasyncd_start(void)
  51. {
  52. int ret;
  53. ret = kernel_thread(kafsasyncd, NULL, 0);
  54. if (ret < 0)
  55. return ret;
  56. wait_for_completion(&kafsasyncd_alive);
  57. return ret;
  58. } /* end afs_kafsasyncd_start() */
  59. /*****************************************************************************/
  60. /*
  61. * stop the async daemon
  62. */
  63. void afs_kafsasyncd_stop(void)
  64. {
  65. /* get rid of my daemon */
  66. kafsasyncd_die = 1;
  67. wake_up(&kafsasyncd_sleepq);
  68. wait_for_completion(&kafsasyncd_dead);
  69. } /* end afs_kafsasyncd_stop() */
  70. /*****************************************************************************/
  71. /*
  72. * probing daemon
  73. */
  74. static int kafsasyncd(void *arg)
  75. {
  76. struct afs_async_op *op;
  77. int die;
  78. DECLARE_WAITQUEUE(myself, current);
  79. kafsasyncd_task = current;
  80. printk("kAFS: Started kafsasyncd %d\n", current->pid);
  81. daemonize("kafsasyncd");
  82. complete(&kafsasyncd_alive);
  83. /* loop around looking for things to attend to */
  84. do {
  85. set_current_state(TASK_INTERRUPTIBLE);
  86. add_wait_queue(&kafsasyncd_sleepq, &myself);
  87. for (;;) {
  88. if (!list_empty(&kafsasyncd_async_attnq) ||
  89. signal_pending(current) ||
  90. kafsasyncd_die)
  91. break;
  92. schedule();
  93. set_current_state(TASK_INTERRUPTIBLE);
  94. }
  95. remove_wait_queue(&kafsasyncd_sleepq, &myself);
  96. set_current_state(TASK_RUNNING);
  97. try_to_freeze();
  98. /* discard pending signals */
  99. afs_discard_my_signals();
  100. die = kafsasyncd_die;
  101. /* deal with the next asynchronous operation requiring
  102. * attention */
  103. if (!list_empty(&kafsasyncd_async_attnq)) {
  104. struct afs_async_op *op;
  105. _debug("@@@ Begin Asynchronous Operation");
  106. op = NULL;
  107. spin_lock(&kafsasyncd_async_lock);
  108. if (!list_empty(&kafsasyncd_async_attnq)) {
  109. op = list_entry(kafsasyncd_async_attnq.next,
  110. struct afs_async_op, link);
  111. list_move_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_move_tail(&op->link, &kafsasyncd_async_busyq);
  161. spin_unlock(&kafsasyncd_async_lock);
  162. _leave("");
  163. } /* end afs_kafsasyncd_begin_op() */
  164. /*****************************************************************************/
  165. /*
  166. * request attention for an operation
  167. * - move to attention queue
  168. */
  169. void afs_kafsasyncd_attend_op(struct afs_async_op *op)
  170. {
  171. _enter("");
  172. spin_lock(&kafsasyncd_async_lock);
  173. list_move_tail(&op->link, &kafsasyncd_async_attnq);
  174. spin_unlock(&kafsasyncd_async_lock);
  175. wake_up(&kafsasyncd_sleepq);
  176. _leave("");
  177. } /* end afs_kafsasyncd_attend_op() */
  178. /*****************************************************************************/
  179. /*
  180. * terminate an operation
  181. * - remove from either queue
  182. */
  183. void afs_kafsasyncd_terminate_op(struct afs_async_op *op)
  184. {
  185. _enter("");
  186. spin_lock(&kafsasyncd_async_lock);
  187. if (!list_empty(&op->link)) {
  188. list_del_init(&op->link);
  189. remove_wait_queue(&op->call->waitq, &op->waiter);
  190. }
  191. spin_unlock(&kafsasyncd_async_lock);
  192. wake_up(&kafsasyncd_sleepq);
  193. _leave("");
  194. } /* end afs_kafsasyncd_terminate_op() */