Whamcloud - gitweb
jbd-checkpoint-on-commit: dix possible deadlock.
authornikita <nikita>
Sun, 19 Nov 2006 14:50:21 +0000 (14:50 +0000)
committernikita <nikita>
Sun, 19 Nov 2006 14:50:21 +0000 (14:50 +0000)
lustre/kernel_patches/patches/jbd-checkpoint-on-commit.patch

index 7541cfd..d28272d 100644 (file)
@@ -89,7 +89,7 @@ Index: linux/fs/jbd/journal.c
                spin_unlock(&journal->j_state_lock);
                del_timer_sync(journal->j_commit_timer);
                journal_commit_transaction(journal);
-@@ -168,6 +172,27 @@ loop:
+@@ -168,6 +172,33 @@ loop:
        }
  
        wake_up(&journal->j_wait_done_commit);
@@ -100,19 +100,25 @@ Index: linux/fs/jbd/journal.c
 +       * Do this after wake-up to reduce waiters latency.
 +       */
 +      spin_unlock(&journal->j_state_lock);
-+      down(&journal->j_checkpoint_sem);
-+      spin_lock(&journal->j_state_lock);
-+      while (__log_space_left(journal) <
-+             journal->j_max_transaction_buffers + 2 * transaction_size) {
-+              int result;
++      /*
++       * Trylock to avoid deadlock with threads waiting for commit under
++       * journal->j_checkpoint_sem.
++       */
++      if (!down_trylock(&journal->j_checkpoint_sem)) {
++              spin_lock(&journal->j_state_lock);
++              while (__log_space_left(journal) <
++                     journal->j_max_transaction_buffers +
++                     2 * transaction_size) {
++                      int result;
 +
-+              spin_unlock(&journal->j_state_lock);
-+              result = log_do_checkpoint(journal);
-+              spin_lock(&journal->j_state_lock);
-+              if (result < 0)
-+                      break;
++                      spin_unlock(&journal->j_state_lock);
++                      result = log_do_checkpoint(journal);
++                      spin_lock(&journal->j_state_lock);
++                      if (result < 0)
++                              break;
++              }
++              up(&journal->j_checkpoint_sem);
 +      }
-+      up(&journal->j_checkpoint_sem);
 +
        if (current->flags & PF_FREEZE) {
                /*