Merge branch 'alpha-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88...
[safe/jmp/linux-2.6] / fs / jbd / commit.c
index 4bd8825..28a9dda 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/bio.h>
@@ -787,6 +786,12 @@ wait_for_iobuf:
 
        jbd_debug(3, "JBD: commit phase 6\n");
 
+       /* All metadata is written, now write commit record and do cleanup */
+       spin_lock(&journal->j_state_lock);
+       J_ASSERT(commit_transaction->t_state == T_COMMIT);
+       commit_transaction->t_state = T_COMMIT_RECORD;
+       spin_unlock(&journal->j_state_lock);
+
        if (journal_write_commit_record(journal, commit_transaction))
                err = -EIO;
 
@@ -862,12 +867,12 @@ restart_loop:
                /* A buffer which has been freed while still being
                 * journaled by a previous transaction may end up still
                 * being dirty here, but we want to avoid writing back
-                * that buffer in the future now that the last use has
-                * been committed.  That's not only a performance gain,
-                * it also stops aliasing problems if the buffer is left
-                * behind for writeback and gets reallocated for another
+                * that buffer in the future after the "add to orphan"
+                * operation been committed,  That's not only a performance
+                * gain, it also stops aliasing problems if the buffer is
+                * left behind for writeback and gets reallocated for another
                 * use in a different page. */
-               if (buffer_freed(bh)) {
+               if (buffer_freed(bh) && !jh->b_next_transaction) {
                        clear_buffer_freed(bh);
                        clear_buffer_jbddirty(bh);
                }
@@ -924,7 +929,7 @@ restart_loop:
 
        jbd_debug(3, "JBD: commit phase 8\n");
 
-       J_ASSERT(commit_transaction->t_state == T_COMMIT);
+       J_ASSERT(commit_transaction->t_state == T_COMMIT_RECORD);
 
        commit_transaction->t_state = T_FINISHED;
        J_ASSERT(commit_transaction == journal->j_committing_transaction);