Commit 6b65bc1f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] JBD: implement journal->j_commit_sequence locking

Implement the designed locking around journal->j_commit_sequence.
parent e3a03fb8
...@@ -162,27 +162,36 @@ int kjournald(void *arg) ...@@ -162,27 +162,36 @@ int kjournald(void *arg)
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) {
journal->j_commit_timer_active = 0; journal->j_commit_timer_active = 0;
del_timer(journal->j_commit_timer); del_timer(journal->j_commit_timer);
} }
spin_unlock(&journal->j_state_lock);
journal_commit_transaction(journal); journal_commit_transaction(journal);
continue; continue;
} }
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) { /* The simpler the better. Flushing journal isn't a if (current->flags & PF_FREEZE) {
good idea, because that depends on threads that /*
may be already stopped. */ * The simpler the better. Flushing journal isn't a
* good idea, because that depends on threads that may
* be already stopped.
*/
jbd_debug(1, "Now suspending kjournald\n"); jbd_debug(1, "Now suspending kjournald\n");
refrigerator(PF_IOTHREAD); refrigerator(PF_IOTHREAD);
jbd_debug(1, "Resuming kjournald\n"); jbd_debug(1, "Resuming kjournald\n");
} else /* we assume on resume that commits are already there, } else {
so we don't sleep */ /*
* We assume on resume that commits are already there,
* so we don't sleep
*/
interruptible_sleep_on(&journal->j_wait_commit); interruptible_sleep_on(&journal->j_wait_commit);
}
jbd_debug(1, "kjournald wakes\n"); jbd_debug(1, "kjournald wakes\n");
...@@ -475,7 +484,7 @@ tid_t log_start_commit(journal_t *journal, transaction_t *transaction) ...@@ -475,7 +484,7 @@ tid_t log_start_commit(journal_t *journal, transaction_t *transaction)
* Wait for a specified commit to complete. * Wait for a specified commit to complete.
* The caller may not hold the journal lock. * The caller may not hold the journal lock.
*/ */
int log_wait_commit (journal_t *journal, tid_t tid) int log_wait_commit(journal_t *journal, tid_t tid)
{ {
int err = 0; int err = 0;
...@@ -489,12 +498,17 @@ int log_wait_commit (journal_t *journal, tid_t tid) ...@@ -489,12 +498,17 @@ int log_wait_commit (journal_t *journal, tid_t tid)
} }
unlock_journal(journal); unlock_journal(journal);
#endif #endif
spin_lock(&journal->j_state_lock);
while (tid_gt(tid, journal->j_commit_sequence)) { while (tid_gt(tid, journal->j_commit_sequence)) {
jbd_debug(1, "JBD: want %d, j_commit_sequence=%d\n", jbd_debug(1, "JBD: want %d, j_commit_sequence=%d\n",
tid, journal->j_commit_sequence); tid, journal->j_commit_sequence);
wake_up(&journal->j_wait_commit); wake_up(&journal->j_wait_commit);
sleep_on(&journal->j_wait_done_commit); spin_unlock(&journal->j_state_lock);
wait_event(journal->j_wait_done_commit,
!tid_gt(tid, journal->j_commit_sequence));
spin_lock(&journal->j_state_lock);
} }
spin_unlock(&journal->j_state_lock);
if (unlikely(is_journal_aborted(journal))) { if (unlikely(is_journal_aborted(journal))) {
printk(KERN_EMERG "journal commit I/O error\n"); printk(KERN_EMERG "journal commit I/O error\n");
......
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