Commit ca340395 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] JBD: implement j_commit_request locking

Impement the designed locking around journal->j_commit_request.
parent 6b65bc1f
...@@ -152,17 +152,20 @@ int kjournald(void *arg) ...@@ -152,17 +152,20 @@ int kjournald(void *arg)
printk(KERN_INFO "kjournald starting. Commit interval %ld seconds\n", printk(KERN_INFO "kjournald starting. Commit interval %ld seconds\n",
journal->j_commit_interval / HZ); journal->j_commit_interval / HZ);
lock_kernel();
list_add(&journal->j_all_journals, &all_journals); list_add(&journal->j_all_journals, &all_journals);
unlock_kernel();
/* And now, wait forever for commit wakeup events. */ /*
while (1) { * And now, wait forever for commit wakeup events.
if (journal->j_flags & JFS_UNMOUNT) */
break; spin_lock(&journal->j_state_lock);
loop:
jbd_debug(1, "commit_sequence=%d, commit_request=%d\n", jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
journal->j_commit_sequence, journal->j_commit_request); journal->j_commit_sequence, journal->j_commit_request);
spin_lock(&journal->j_state_lock);
if (journal->j_commit_sequence != journal->j_commit_request) { if (journal->j_commit_sequence != journal->j_commit_request) {
jbd_debug(1, "OK, requests differ\n"); jbd_debug(1, "OK, requests differ\n");
if (journal->j_commit_timer_active) { if (journal->j_commit_timer_active) {
...@@ -171,9 +174,9 @@ int kjournald(void *arg) ...@@ -171,9 +174,9 @@ int kjournald(void *arg)
} }
spin_unlock(&journal->j_state_lock); spin_unlock(&journal->j_state_lock);
journal_commit_transaction(journal); journal_commit_transaction(journal);
continue; spin_lock(&journal->j_state_lock);
goto loop;
} }
spin_unlock(&journal->j_state_lock);
wake_up(&journal->j_wait_done_commit); wake_up(&journal->j_wait_done_commit);
if (current->flags & PF_FREEZE) { if (current->flags & PF_FREEZE) {
...@@ -183,32 +186,57 @@ int kjournald(void *arg) ...@@ -183,32 +186,57 @@ int kjournald(void *arg)
* be already stopped. * be already stopped.
*/ */
jbd_debug(1, "Now suspending kjournald\n"); jbd_debug(1, "Now suspending kjournald\n");
spin_unlock(&journal->j_state_lock);
refrigerator(PF_IOTHREAD); refrigerator(PF_IOTHREAD);
spin_lock(&journal->j_state_lock);
jbd_debug(1, "Resuming kjournald\n"); jbd_debug(1, "Resuming kjournald\n");
} else { } else {
/* /*
* We assume on resume that commits are already there, * We assume on resume that commits are already there,
* so we don't sleep * so we don't sleep
*/ */
interruptible_sleep_on(&journal->j_wait_commit); DEFINE_WAIT(wait);
int should_sleep = 1;
prepare_to_wait(&journal->j_wait_commit, &wait,
TASK_INTERRUPTIBLE);
if (journal->j_commit_sequence != journal->j_commit_request)
should_sleep = 0;
transaction = journal->j_running_transaction;
if (transaction && time_after_eq(jiffies,
transaction->t_expires))
should_sleep = 0;
if (should_sleep) {
spin_unlock(&journal->j_state_lock);
schedule();
spin_lock(&journal->j_state_lock);
}
finish_wait(&journal->j_wait_commit, &wait);
} }
jbd_debug(1, "kjournald wakes\n"); jbd_debug(1, "kjournald wakes\n");
/* Were we woken up by a commit wakeup event? */ /*
if ((transaction = journal->j_running_transaction) != NULL && * Were we woken up by a commit wakeup event?
time_after_eq(jiffies, transaction->t_expires)) { */
transaction = journal->j_running_transaction;
if (transaction && time_after_eq(jiffies, transaction->t_expires)) {
journal->j_commit_request = transaction->t_tid; journal->j_commit_request = transaction->t_tid;
jbd_debug(1, "woke because of timeout\n"); jbd_debug(1, "woke because of timeout\n");
} }
}
if (!(journal->j_flags & JFS_UNMOUNT))
goto loop;
if (journal->j_commit_timer_active) { if (journal->j_commit_timer_active) {
journal->j_commit_timer_active = 0; journal->j_commit_timer_active = 0;
del_timer_sync(journal->j_commit_timer); del_timer_sync(journal->j_commit_timer);
} }
spin_unlock(&journal->j_state_lock);
lock_kernel();
list_del(&journal->j_all_journals); list_del(&journal->j_all_journals);
unlock_kernel();
journal->j_task = NULL; journal->j_task = NULL;
wake_up(&journal->j_wait_done_commit); wake_up(&journal->j_wait_done_commit);
...@@ -430,7 +458,7 @@ int __log_space_left(journal_t *journal) ...@@ -430,7 +458,7 @@ int __log_space_left(journal_t *journal)
} }
/* /*
* This function must be non-allocating for PF_MEMALLOC tasks * Called under j_state_lock.
*/ */
static tid_t __log_start_commit(journal_t *journal, transaction_t *transaction) static tid_t __log_start_commit(journal_t *journal, transaction_t *transaction)
{ {
...@@ -491,11 +519,13 @@ int log_wait_commit(journal_t *journal, tid_t tid) ...@@ -491,11 +519,13 @@ int log_wait_commit(journal_t *journal, tid_t tid)
lock_kernel(); lock_kernel();
#ifdef CONFIG_JBD_DEBUG #ifdef CONFIG_JBD_DEBUG
lock_journal(journal); lock_journal(journal);
spin_lock(&journal->j_state_lock);
if (!tid_geq(journal->j_commit_request, tid)) { if (!tid_geq(journal->j_commit_request, tid)) {
printk(KERN_EMERG printk(KERN_EMERG
"%s: error: j_commit_request=%d, tid=%d\n", "%s: error: j_commit_request=%d, tid=%d\n",
__FUNCTION__, journal->j_commit_request, tid); __FUNCTION__, journal->j_commit_request, tid);
} }
spin_unlock(&journal->j_state_lock);
unlock_journal(journal); unlock_journal(journal);
#endif #endif
spin_lock(&journal->j_state_lock); spin_lock(&journal->j_state_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment