提交 3e3bd358 编写于 作者: J Joseph Qi

alinux: jbd2: create jbd2-ckpt thread for journal checkpoint

This is trying to do jbd2 checkpoint in a specific kernel thread, then
checkpoint won't be under io throttle control.
Signed-off-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: NJiufei Xue <jiufei.xue@linux.alibaba.com>
Signed-off-by: Nzhangliguang <zhangliguang@linux.alibaba.com>
Reviewed by: Baoyou Xie <baoyou.xie@linux.alibaba.com>
Reviewed-by: NLiu Bo <bo.liu@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
上级 83044726
......@@ -4332,6 +4332,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
}
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
set_task_ioprio(sbi->s_journal->j_checkpoint_task, journal_ioprio);
sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
......@@ -5268,6 +5269,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
if (sbi->s_journal) {
ext4_init_journal_params(sb, sbi->s_journal);
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
set_task_ioprio(sbi->s_journal->j_checkpoint_task,
journal_ioprio);
}
if (*flags & SB_LAZYTIME)
......
......@@ -143,7 +143,15 @@ void __jbd2_log_wait_for_space(journal_t *journal)
spin_unlock(&journal->j_list_lock);
write_unlock(&journal->j_state_lock);
if (chkpt) {
jbd2_log_do_checkpoint(journal);
DEFINE_WAIT(wait);
prepare_to_wait(&journal->j_wait_done_checkpoint, &wait,
TASK_UNINTERRUPTIBLE);
mutex_unlock(&journal->j_checkpoint_mutex);
wake_up(&journal->j_wait_checkpoint);
schedule();
mutex_lock(&journal->j_checkpoint_mutex);
finish_wait(&journal->j_wait_done_checkpoint, &wait);
jbd_debug(1, "wake up checkpoint thread.\n");
} else if (jbd2_cleanup_journal_tail(journal) == 0) {
/* We were able to recover space; yay! */
;
......
......@@ -221,6 +221,9 @@ static int kjournald2(void *arg)
if (journal->j_flags & JBD2_UNMOUNT)
goto end_loop;
if (kthread_should_stop())
goto end_loop;
jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
journal->j_commit_sequence, journal->j_commit_request);
......@@ -291,9 +294,39 @@ static int kjournald2(void *arg)
return 0;
}
static int jbd2_checkpoint_thread(void *arg)
{
journal_t *journal = arg;
DEFINE_WAIT(wait);
jbd_debug(1, "jbd2_checkpoint_thread\n");
journal->j_checkpoint_task = current;
loop:
prepare_to_wait(&journal->j_wait_checkpoint, &wait,
TASK_INTERRUPTIBLE);
wake_up_all(&journal->j_wait_done_checkpoint);
schedule();
finish_wait(&journal->j_wait_checkpoint, &wait);
if (journal->j_flags & JBD2_UNMOUNT)
goto end_loop;
mutex_lock(&journal->j_checkpoint_mutex);
jbd2_log_do_checkpoint(journal);
mutex_unlock(&journal->j_checkpoint_mutex);
goto loop;
end_loop:
journal->j_checkpoint_task = NULL;
wake_up_all(&journal->j_wait_done_checkpoint);
jbd_debug(1, "jbd2_checkpoint_thread exiting.\n");
return 0;
}
static int jbd2_journal_start_thread(journal_t *journal)
{
struct task_struct *t;
struct task_struct *t, *t_ckpt;
t = kthread_run(kjournald2, journal, "jbd2/%s",
journal->j_devname);
......@@ -301,6 +334,17 @@ static int jbd2_journal_start_thread(journal_t *journal)
return PTR_ERR(t);
wait_event(journal->j_wait_done_commit, journal->j_task != NULL);
t_ckpt = kthread_run(jbd2_checkpoint_thread, journal, "jbd2-ckpt/%s",
journal->j_devname);
if (IS_ERR(t_ckpt)) {
kthread_stop(t);
return PTR_ERR(t_ckpt);
}
wait_event(journal->j_wait_done_checkpoint,
journal->j_checkpoint_task != NULL);
return 0;
}
......@@ -316,6 +360,14 @@ static void journal_kill_thread(journal_t *journal)
write_lock(&journal->j_state_lock);
}
write_unlock(&journal->j_state_lock);
while (journal->j_checkpoint_task) {
mutex_lock(&journal->j_checkpoint_mutex);
wake_up(&journal->j_wait_checkpoint);
wait_event(journal->j_wait_done_checkpoint,
journal->j_checkpoint_task == NULL);
mutex_unlock(&journal->j_checkpoint_mutex);
}
}
/*
......@@ -1144,6 +1196,8 @@ static journal_t *journal_init_common(struct block_device *bdev,
init_waitqueue_head(&journal->j_wait_transaction_locked);
init_waitqueue_head(&journal->j_wait_done_commit);
init_waitqueue_head(&journal->j_wait_checkpoint);
init_waitqueue_head(&journal->j_wait_done_checkpoint);
init_waitqueue_head(&journal->j_wait_commit);
init_waitqueue_head(&journal->j_wait_updates);
init_waitqueue_head(&journal->j_wait_reserved);
......
......@@ -849,6 +849,16 @@ struct journal_s
*/
wait_queue_head_t j_wait_commit;
/**
* @j_wait_done_checkpoint: Wait queue for waiting for checkpoint to complete.
*/
wait_queue_head_t j_wait_done_checkpoint;
/**
* @j_wait_checkpoint: Wait queue to trigger checkpointing.
*/
wait_queue_head_t j_wait_checkpoint;
/**
* @j_wait_updates: Wait queue to wait for updates to complete.
*/
......@@ -1108,6 +1118,9 @@ struct journal_s
void (*j_commit_callback)(journal_t *,
transaction_t *);
/* Pointer to the current checkpoint thread for this journal */
struct task_struct *j_checkpoint_task;
/*
* Journal statistics
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册