vserver 1.9.3
[linux-2.6.git] / fs / jbd / commit.c
index a540c7f..f8a1dea 100644 (file)
@@ -405,9 +405,9 @@ write_out_data:
                        jbd_debug(4, "JBD: got buffer %llu (%p)\n",
                                (unsigned long long)bh->b_blocknr, bh->b_data);
                        header = (journal_header_t *)&bh->b_data[0];
-                       header->h_magic     = htonl(JFS_MAGIC_NUMBER);
-                       header->h_blocktype = htonl(JFS_DESCRIPTOR_BLOCK);
-                       header->h_sequence  = htonl(commit_transaction->t_tid);
+                       header->h_magic     = cpu_to_be32(JFS_MAGIC_NUMBER);
+                       header->h_blocktype = cpu_to_be32(JFS_DESCRIPTOR_BLOCK);
+                       header->h_sequence  = cpu_to_be32(commit_transaction->t_tid);
 
                        tagp = &bh->b_data[sizeof(journal_header_t)];
                        space_left = bh->b_size - sizeof(journal_header_t);
@@ -473,8 +473,8 @@ write_out_data:
                        tag_flag |= JFS_FLAG_SAME_UUID;
 
                tag = (journal_block_tag_t *) tagp;
-               tag->t_blocknr = htonl(jh2bh(jh)->b_blocknr);
-               tag->t_flags = htonl(tag_flag);
+               tag->t_blocknr = cpu_to_be32(jh2bh(jh)->b_blocknr);
+               tag->t_flags = cpu_to_be32(tag_flag);
                tagp += sizeof(journal_block_tag_t);
                space_left -= sizeof(journal_block_tag_t);
 
@@ -498,7 +498,7 @@ write_out_data:
                            submitting the IOs.  "tag" still points to
                            the last tag we set up. */
 
-                       tag->t_flags |= htonl(JFS_FLAG_LAST_TAG);
+                       tag->t_flags |= cpu_to_be32(JFS_FLAG_LAST_TAG);
 
 start_journal_io:
                        for (i = 0; i < bufs; i++) {
@@ -631,18 +631,46 @@ wait_for_iobuf:
        for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
                journal_header_t *tmp =
                        (journal_header_t*)jh2bh(descriptor)->b_data;
-               tmp->h_magic = htonl(JFS_MAGIC_NUMBER);
-               tmp->h_blocktype = htonl(JFS_COMMIT_BLOCK);
-               tmp->h_sequence = htonl(commit_transaction->t_tid);
+               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);
        }
 
        JBUFFER_TRACE(descriptor, "write commit block");
        {
                struct buffer_head *bh = jh2bh(descriptor);
+               int ret;
+               int barrier_done = 0;
 
                set_buffer_dirty(bh);
-               sync_dirty_buffer(bh);
-               if (unlikely(!buffer_uptodate(bh)))
+               if (journal->j_flags & JFS_BARRIER) {
+                       set_buffer_ordered(bh);
+                       barrier_done = 1;
+               }
+               ret = sync_dirty_buffer(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
+                * to remember if we sent a barrier request
+                */
+               if (ret == -EOPNOTSUPP && barrier_done) {
+                       char b[BDEVNAME_SIZE];
+
+                       printk(KERN_WARNING
+                               "JBD: barrier-based sync failed on %s - "
+                               "disabling barriers\n",
+                               bdevname(journal->j_dev, b));
+                       spin_lock(&journal->j_state_lock);
+                       journal->j_flags &= ~JFS_BARRIER;
+                       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);
+               }
+               if (unlikely(ret == -EIO))
                        err = -EIO;
                put_bh(bh);             /* One for getblk() */
                journal_put_journal_head(descriptor);