diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2013-01-18 21:30:29 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2013-01-18 21:30:29 +0900 |
commit | c58f6793f0da2b5ecb9cb9e1455c69cd10daeffd (patch) | |
tree | be30ea03ef15c1053d146b3776b37a92a6c1664f | |
parent | bed204e740c87e4b3a8befbec980f0ad9089dacb (diff) | |
download | linux-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.c | 52 | ||||
-rw-r--r-- | fs/tux3/tux3.h | 3 |
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 */ |