X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjbd%2Fcommit.c;h=f8a1dea566113ce8d7d067cf27c2b85916e08c55;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=c1eb3c536474be854639ec893447da43b52cba8a;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index c1eb3c536..f8a1dea56 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -362,7 +362,7 @@ write_out_data: */ commit_transaction->t_state = T_COMMIT; - descriptor = 0; + descriptor = NULL; bufs = 0; while (commit_transaction->t_buffers) { @@ -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,12 +498,12 @@ 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++) { struct buffer_head *bh = wbuf[i]; - set_buffer_locked(bh); + lock_buffer(bh); clear_buffer_dirty(bh); set_buffer_uptodate(bh); bh->b_end_io = journal_end_buffer_io_sync; @@ -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);