]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/jbd/commit.c
jbd: tidy up revoke cache initialisation and destruction
[linux-2.6-omap-h63xx.git] / fs / jbd / commit.c
index a003d50edcdbdc1fe45a7627e83191cd55df378c..5a8ca61498caf36cbb818fddc00eafbca2642f03 100644 (file)
@@ -104,7 +104,8 @@ static int journal_write_commit_record(journal_t *journal,
 {
        struct journal_head *descriptor;
        struct buffer_head *bh;
-       int i, ret;
+       journal_header_t *header;
+       int ret;
        int barrier_done = 0;
 
        if (is_journal_aborted(journal))
@@ -116,13 +117,10 @@ static int journal_write_commit_record(journal_t *journal,
 
        bh = jh2bh(descriptor);
 
-       /* AKPM: buglet - add `i' to tmp! */
-       for (i = 0; i < bh->b_size; i += 512) {
-               journal_header_t *tmp = (journal_header_t*)bh->b_data;
-               tmp->h_magic = cpu_to_be32(JFS_MAGIC_NUMBER);
-               tmp->h_blocktype = cpu_to_be32(JFS_COMMIT_BLOCK);
-               tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid);
-       }
+       header = (journal_header_t *)(bh->b_data);
+       header->h_magic = cpu_to_be32(JFS_MAGIC_NUMBER);
+       header->h_blocktype = cpu_to_be32(JFS_COMMIT_BLOCK);
+       header->h_sequence = cpu_to_be32(commit_transaction->t_tid);
 
        JBUFFER_TRACE(descriptor, "write commit block");
        set_buffer_dirty(bh);
@@ -131,6 +129,8 @@ static int journal_write_commit_record(journal_t *journal,
                barrier_done = 1;
        }
        ret = sync_dirty_buffer(bh);
+       if (barrier_done)
+               clear_buffer_ordered(bh);
        /* is it possible for another commit to fail at roughly
         * the same time as this one?  If so, we don't want to
         * trust the barrier flag in the super, but instead want
@@ -148,7 +148,6 @@ static int journal_write_commit_record(journal_t *journal,
                spin_unlock(&journal->j_state_lock);
 
                /* And try again, without the barrier */
-               clear_buffer_ordered(bh);
                set_buffer_uptodate(bh);
                set_buffer_dirty(bh);
                ret = sync_dirty_buffer(bh);
@@ -265,7 +264,7 @@ write_out_data:
                        put_bh(bh);
                }
 
-               if (lock_need_resched(&journal->j_list_lock)) {
+               if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
                        spin_unlock(&journal->j_list_lock);
                        goto write_out_data;
                }
@@ -375,7 +374,7 @@ void journal_commit_transaction(journal_t *journal)
                        struct buffer_head *bh = jh2bh(jh);
 
                        jbd_lock_bh_state(bh);
-                       jbd_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        jbd_unlock_bh_state(bh);
                }
@@ -407,22 +406,6 @@ void journal_commit_transaction(journal_t *journal)
 
        jbd_debug (3, "JBD: commit phase 2\n");
 
-       /*
-        * First, drop modified flag: all accesses to the buffers
-        * will be tracked for a new trasaction only -bzzz
-        */
-       spin_lock(&journal->j_list_lock);
-       if (commit_transaction->t_buffers) {
-               new_jh = jh = commit_transaction->t_buffers->b_tnext;
-               do {
-                       J_ASSERT_JH(new_jh, new_jh->b_modified == 1 ||
-                                       new_jh->b_modified == 0);
-                       new_jh->b_modified = 0;
-                       new_jh = new_jh->b_tnext;
-               } while (new_jh != jh);
-       }
-       spin_unlock(&journal->j_list_lock);
-
        /*
         * Now start flushing things to disk, in the order they appear
         * on the transaction lists.  Data blocks go first.
@@ -466,7 +449,7 @@ void journal_commit_transaction(journal_t *journal)
        spin_unlock(&journal->j_list_lock);
 
        if (err)
-               __journal_abort_hard(journal);
+               journal_abort(journal, err);
 
        journal_write_revoke_records(journal, commit_transaction);
 
@@ -487,7 +470,12 @@ void journal_commit_transaction(journal_t *journal)
         * transaction!  Now comes the tricky part: we need to write out
         * metadata.  Loop over the transaction's entire buffer list:
         */
+       spin_lock(&journal->j_state_lock);
        commit_transaction->t_state = T_COMMIT;
+       spin_unlock(&journal->j_state_lock);
+
+       J_ASSERT(commit_transaction->t_nr_buffers <=
+                commit_transaction->t_outstanding_credits);
 
        descriptor = NULL;
        bufs = 0;
@@ -524,7 +512,7 @@ void journal_commit_transaction(journal_t *journal)
 
                        descriptor = journal_get_descriptor_buffer(journal);
                        if (!descriptor) {
-                               __journal_abort_hard(journal);
+                               journal_abort(journal, -EIO);
                                continue;
                        }
 
@@ -557,7 +545,7 @@ void journal_commit_transaction(journal_t *journal)
                   and repeat this loop: we'll fall into the
                   refile-on-abort condition above. */
                if (err) {
-                       __journal_abort_hard(journal);
+                       journal_abort(journal, err);
                        continue;
                }
 
@@ -748,7 +736,7 @@ wait_for_iobuf:
                err = -EIO;
 
        if (err)
-               __journal_abort_hard(journal);
+               journal_abort(journal, err);
 
        /* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
@@ -792,14 +780,14 @@ restart_loop:
                 * Otherwise, we can just throw away the frozen data now.
                 */
                if (jh->b_committed_data) {
-                       jbd_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        if (jh->b_frozen_data) {
                                jh->b_committed_data = jh->b_frozen_data;
                                jh->b_frozen_data = NULL;
                        }
                } else if (jh->b_frozen_data) {
-                       jbd_slab_free(jh->b_frozen_data, bh->b_size);
+                       jbd_free(jh->b_frozen_data, bh->b_size);
                        jh->b_frozen_data = NULL;
                }
 
@@ -858,10 +846,10 @@ restart_loop:
        }
        spin_unlock(&journal->j_list_lock);
        /*
-        * This is a bit sleazy.  We borrow j_list_lock to protect
-        * journal->j_committing_transaction in __journal_remove_checkpoint.
-        * Really, __journal_remove_checkpoint should be using j_state_lock but
-        * it's a bit hassle to hold that across __journal_remove_checkpoint
+        * This is a bit sleazy.  We use j_list_lock to protect transition
+        * of a transaction into T_FINISHED state and calling
+        * __journal_drop_transaction(). Otherwise we could race with
+        * other checkpointing code processing the transaction...
         */
        spin_lock(&journal->j_state_lock);
        spin_lock(&journal->j_list_lock);