aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2013-01-18 21:30:29 +0900
committerDaniel Phillips <daniel@tux3.org>2013-01-18 21:30:29 +0900
commitc58f6793f0da2b5ecb9cb9e1455c69cd10daeffd (patch)
treebe30ea03ef15c1053d146b3776b37a92a6c1664f
parentbed204e740c87e4b3a8befbec980f0ad9089dacb (diff)
downloadlinux-tux3-c58f6793f0da2b5ecb9cb9e1455c69cd10daeffd.tar.gz
tux3: Make asynchronous task for backend to daemon
The workqueue have to use the needless work item, and hard to see the cpu account and state of backend. Because workqueue has thread pool, so we are not sure the backend is running on which worker thread. So, this makes own daemon for backend. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/commit.c52
-rw-r--r--fs/tux3/tux3.h3
2 files changed, 39 insertions, 16 deletions
diff --git a/fs/tux3/commit.c b/fs/tux3/commit.c
index 55f891ec700cdc..8d5fc7d8f3b4fc 100644
--- a/fs/tux3/commit.c
+++ b/fs/tux3/commit.c
@@ -4,6 +4,10 @@
*/
#include "tux3.h"
+#ifdef __KERNEL__
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#endif
#ifndef trace
#define trace trace_on
@@ -461,44 +465,64 @@ static int flush_delta(struct sb *sb)
}
#ifndef DISABLE_ASYNC_BACKEND
-static void flush_delta_work(struct work_struct *work)
+static int flush_delta_work(void *data)
{
- struct sb *sb = container_of(work, struct sb, flush_work);
+ struct sb *sb = data;
int err;
- if (test_and_clear_bit(TUX3_COMMIT_PENDING_BIT, &sb->backend_state))
- err = flush_delta(sb);
- else
- assert(0);
+ set_freezable();
+
+ /*
+ * Our parent may run at a different priority, just set us to normal
+ */
+ set_user_nice(current, 0);
+
+ while (!kthread_freezable_should_stop(NULL)) {
+ if (test_bit(TUX3_COMMIT_PENDING_BIT, &sb->backend_state)) {
+ clear_bit(TUX3_COMMIT_PENDING_BIT, &sb->backend_state);
- /* FIXME: error handling */
+ err = flush_delta(sb);
+ /* FIXME: error handling */
+ }
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!test_bit(TUX3_COMMIT_PENDING_BIT, &sb->backend_state) &&
+ !kthread_should_stop())
+ schedule();
+ __set_current_state(TASK_RUNNING);
+ }
+
+ return 0;
}
static void schedule_flush_delta(struct sb *sb)
{
- queue_work(sb->flush_wq, &sb->flush_work);
+ wake_up_process(sb->flush_task);
}
int tux3_init_flusher(struct sb *sb)
{
+ struct task_struct *task;
char b[BDEVNAME_SIZE];
bdevname(vfs_sb(sb)->s_bdev, b);
/* FIXME: we should use normal bdi-writeback by changing core */
- sb->flush_wq = alloc_ordered_workqueue("tux3-wq/%s", WQ_MEM_RECLAIM, b);
- if (!sb->flush_wq)
- return -ENOMEM;
+ task = kthread_run(flush_delta_work, sb, "tux3/%s", b);
+ if (IS_ERR(task))
+ return PTR_ERR(task);
- INIT_WORK(&sb->flush_work, flush_delta_work);
+ sb->flush_task = task;
return 0;
}
void tux3_exit_flusher(struct sb *sb)
{
- flush_work(&sb->flush_work);
- destroy_workqueue(sb->flush_wq);
+ if (sb->flush_task) {
+ kthread_stop(sb->flush_task);
+ sb->flush_task = NULL;
+ }
}
static int flush_pending_delta(struct sb *sb)
diff --git a/fs/tux3/tux3.h b/fs/tux3/tux3.h
index cce3a2aa3f984e..00cbb6c43f6df6 100644
--- a/fs/tux3/tux3.h
+++ b/fs/tux3/tux3.h
@@ -239,8 +239,7 @@ struct sb {
wait_queue_head_t delta_event_wq; /* wait queue for delta event */
#ifndef DISABLE_ASYNC_BACKEND
/* work to flush delta */
- struct workqueue_struct *flush_wq;
- struct work_struct flush_work;
+ struct task_struct *flush_task;
#endif
struct btree itable; /* Inode table btree */