Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
new file mode 100644
index 0000000..6fc88ae
--- /dev/null
+++ b/fs/afs/kafsasyncd.c
@@ -0,0 +1,257 @@
+/* kafsasyncd.c: AFS asynchronous operation daemon
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *
+ * The AFS async daemon is used to the following:
+ * - probe "dead" servers to see whether they've come back to life yet.
+ * - probe "live" servers that we haven't talked to for a while to see if they are better
+ *   candidates for serving than what we're currently using
+ * - poll volume location servers to keep up to date volume location lists
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include "cell.h"
+#include "server.h"
+#include "volume.h"
+#include "kafsasyncd.h"
+#include "kafstimod.h"
+#include <rxrpc/call.h>
+#include <asm/errno.h>
+#include "internal.h"
+
+static DECLARE_COMPLETION(kafsasyncd_alive);
+static DECLARE_COMPLETION(kafsasyncd_dead);
+static DECLARE_WAIT_QUEUE_HEAD(kafsasyncd_sleepq);
+static struct task_struct *kafsasyncd_task;
+static int kafsasyncd_die;
+
+static int kafsasyncd(void *arg);
+
+static LIST_HEAD(kafsasyncd_async_attnq);
+static LIST_HEAD(kafsasyncd_async_busyq);
+static DEFINE_SPINLOCK(kafsasyncd_async_lock);
+
+static void kafsasyncd_null_call_attn_func(struct rxrpc_call *call)
+{
+}
+
+static void kafsasyncd_null_call_error_func(struct rxrpc_call *call)
+{
+}
+
+/*****************************************************************************/
+/*
+ * start the async daemon
+ */
+int afs_kafsasyncd_start(void)
+{
+	int ret;
+
+	ret = kernel_thread(kafsasyncd, NULL, 0);
+	if (ret < 0)
+		return ret;
+
+	wait_for_completion(&kafsasyncd_alive);
+
+	return ret;
+} /* end afs_kafsasyncd_start() */
+
+/*****************************************************************************/
+/*
+ * stop the async daemon
+ */
+void afs_kafsasyncd_stop(void)
+{
+	/* get rid of my daemon */
+	kafsasyncd_die = 1;
+	wake_up(&kafsasyncd_sleepq);
+	wait_for_completion(&kafsasyncd_dead);
+
+} /* end afs_kafsasyncd_stop() */
+
+/*****************************************************************************/
+/*
+ * probing daemon
+ */
+static int kafsasyncd(void *arg)
+{
+	struct afs_async_op *op;
+	int die;
+
+	DECLARE_WAITQUEUE(myself, current);
+
+	kafsasyncd_task = current;
+
+	printk("kAFS: Started kafsasyncd %d\n", current->pid);
+
+	daemonize("kafsasyncd");
+
+	complete(&kafsasyncd_alive);
+
+	/* loop around looking for things to attend to */
+	do {
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&kafsasyncd_sleepq, &myself);
+
+		for (;;) {
+			if (!list_empty(&kafsasyncd_async_attnq) ||
+			    signal_pending(current) ||
+			    kafsasyncd_die)
+				break;
+
+			schedule();
+			set_current_state(TASK_INTERRUPTIBLE);
+		}
+
+		remove_wait_queue(&kafsasyncd_sleepq, &myself);
+		set_current_state(TASK_RUNNING);
+
+		try_to_freeze(PF_FREEZE);
+
+		/* discard pending signals */
+		afs_discard_my_signals();
+
+		die = kafsasyncd_die;
+
+		/* deal with the next asynchronous operation requiring
+		 * attention */
+		if (!list_empty(&kafsasyncd_async_attnq)) {
+			struct afs_async_op *op;
+
+			_debug("@@@ Begin Asynchronous Operation");
+
+			op = NULL;
+			spin_lock(&kafsasyncd_async_lock);
+
+			if (!list_empty(&kafsasyncd_async_attnq)) {
+				op = list_entry(kafsasyncd_async_attnq.next,
+						struct afs_async_op, link);
+				list_del(&op->link);
+				list_add_tail(&op->link,
+					      &kafsasyncd_async_busyq);
+			}
+
+			spin_unlock(&kafsasyncd_async_lock);
+
+			_debug("@@@ Operation %p {%p}\n",
+			       op, op ? op->ops : NULL);
+
+			if (op)
+				op->ops->attend(op);
+
+			_debug("@@@ End Asynchronous Operation");
+		}
+
+	} while(!die);
+
+	/* need to kill all outstanding asynchronous operations before
+	 * exiting */
+	kafsasyncd_task = NULL;
+	spin_lock(&kafsasyncd_async_lock);
+
+	/* fold the busy and attention queues together */
+	list_splice_init(&kafsasyncd_async_busyq,
+			 &kafsasyncd_async_attnq);
+
+	/* dequeue kafsasyncd from all their wait queues */
+	list_for_each_entry(op, &kafsasyncd_async_attnq, link) {
+		op->call->app_attn_func = kafsasyncd_null_call_attn_func;
+		op->call->app_error_func = kafsasyncd_null_call_error_func;
+		remove_wait_queue(&op->call->waitq, &op->waiter);
+	}
+
+	spin_unlock(&kafsasyncd_async_lock);
+
+	/* abort all the operations */
+	while (!list_empty(&kafsasyncd_async_attnq)) {
+		op = list_entry(kafsasyncd_async_attnq.next, struct afs_async_op, link);
+		list_del_init(&op->link);
+
+		rxrpc_call_abort(op->call, -EIO);
+		rxrpc_put_call(op->call);
+		op->call = NULL;
+
+		op->ops->discard(op);
+	}
+
+	/* and that's all */
+	_leave("");
+	complete_and_exit(&kafsasyncd_dead, 0);
+
+} /* end kafsasyncd() */
+
+/*****************************************************************************/
+/*
+ * begin an operation
+ * - place operation on busy queue
+ */
+void afs_kafsasyncd_begin_op(struct afs_async_op *op)
+{
+	_enter("");
+
+	spin_lock(&kafsasyncd_async_lock);
+
+	init_waitqueue_entry(&op->waiter, kafsasyncd_task);
+	add_wait_queue(&op->call->waitq, &op->waiter);
+
+	list_del(&op->link);
+	list_add_tail(&op->link, &kafsasyncd_async_busyq);
+
+	spin_unlock(&kafsasyncd_async_lock);
+
+	_leave("");
+} /* end afs_kafsasyncd_begin_op() */
+
+/*****************************************************************************/
+/*
+ * request attention for an operation
+ * - move to attention queue
+ */
+void afs_kafsasyncd_attend_op(struct afs_async_op *op)
+{
+	_enter("");
+
+	spin_lock(&kafsasyncd_async_lock);
+
+	list_del(&op->link);
+	list_add_tail(&op->link, &kafsasyncd_async_attnq);
+
+	spin_unlock(&kafsasyncd_async_lock);
+
+	wake_up(&kafsasyncd_sleepq);
+
+	_leave("");
+} /* end afs_kafsasyncd_attend_op() */
+
+/*****************************************************************************/
+/*
+ * terminate an operation
+ * - remove from either queue
+ */
+void afs_kafsasyncd_terminate_op(struct afs_async_op *op)
+{
+	_enter("");
+
+	spin_lock(&kafsasyncd_async_lock);
+
+	if (!list_empty(&op->link)) {
+		list_del_init(&op->link);
+		remove_wait_queue(&op->call->waitq, &op->waiter);
+	}
+
+	spin_unlock(&kafsasyncd_async_lock);
+
+	wake_up(&kafsasyncd_sleepq);
+
+	_leave("");
+} /* end afs_kafsasyncd_terminate_op() */