[PATCH 2/2]
PATCH 2/2 [PATCH 2/2]
Sometimes barriers fail asynchronously (after the submit_bh call). This patch changes both ext3 and reiserfs to handle that without mistaking the barrier failures for io errors.
fs/jbd/commit.c +11 -2
@@ -640,12 +640,20 @@ wait_for_iobuf: {struct buffer_head *bh =jh2bh (descriptor);int ret; +int barrier_done =0 ;set_buffer_dirty (bh); -if (journal->j_flags &JFS_BARRIER ) +if (journal->j_flags &JFS_BARRIER ) {set_buffer_ordered (bh); + barrier_done =1 ; + } ret =sync_dirty_buffer (bh); -if (ret == -EOPNOTSUPP && (journal->j_flags &JFS_BARRIER )) { +/* 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
@@ -658,6 +666,7 @@ wait_for_iobuf:/* And try again, without the barrier */ clear_buffer_ordered (bh); +set_buffer_uptodate (bh);set_buffer_dirty (bh); ret =sync_dirty_buffer (bh); }
fs/reiserfs/journal.c +13 -0
@@ -655,6 +655,17 @@ static int submit_barrier_buffer(structreturn submit_bh (WRITE_BARRIER , bh) ; } +static void check_barrier_completion (struct super_block *s, +struct buffer_head *bh) { +if (buffer_eopnotsupp (bh)) { +clear_buffer_eopnotsupp (bh); +disable_barrier (s); +set_buffer_uptodate (bh); +set_buffer_dirty (bh); +sync_dirty_buffer (bh); + } +} +#define CHUNK_SIZE 32struct buffer_chunk {struct buffer_head *bh[CHUNK_SIZE ];
@@ -1032,6 +1043,7 @@ static int flush_commit_list(struct supe }else wait_on_buffer (jl->j_commit_bh); +check_barrier_completion (s, jl->j_commit_bh);if (!buffer_uptodate (jl->j_commit_bh)) {reiserfs_panic (s,"journal-615: buffer write failed\n" ) ; }
@@ -1142,6 +1154,7 @@ static int _update_journal_header_block( goto sync; }wait_on_buffer (SB_JOURNAL (p_s_sb)->j_header_bh); +check_barrier_completion (p_s_sb,SB_JOURNAL (p_s_sb)->j_header_bh); }else { sync:set_buffer_dirty (SB_JOURNAL (p_s_sb)->j_header_bh) ;