X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjbd%2Fcommit.c;h=f8a1dea566113ce8d7d067cf27c2b85916e08c55;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=a540c7f03da69f0f4f1dd73872bfbc2477f48267;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index a540c7f03..f8a1dea56 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -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);