aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jbd/commit.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index f943b9b3f208..2eccbfaa1d48 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -185,7 +185,7 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
185/* 185/*
186 * Submit all the data buffers to disk 186 * Submit all the data buffers to disk
187 */ 187 */
188static void journal_submit_data_buffers(journal_t *journal, 188static int journal_submit_data_buffers(journal_t *journal,
189 transaction_t *commit_transaction) 189 transaction_t *commit_transaction)
190{ 190{
191 struct journal_head *jh; 191 struct journal_head *jh;
@@ -193,6 +193,7 @@ static void journal_submit_data_buffers(journal_t *journal,
193 int locked; 193 int locked;
194 int bufs = 0; 194 int bufs = 0;
195 struct buffer_head **wbuf = journal->j_wbuf; 195 struct buffer_head **wbuf = journal->j_wbuf;
196 int err = 0;
196 197
197 /* 198 /*
198 * Whenever we unlock the journal and sleep, things can get added 199 * Whenever we unlock the journal and sleep, things can get added
@@ -266,6 +267,8 @@ write_out_data:
266 put_bh(bh); 267 put_bh(bh);
267 } else { 268 } else {
268 BUFFER_TRACE(bh, "writeout complete: unfile"); 269 BUFFER_TRACE(bh, "writeout complete: unfile");
270 if (unlikely(!buffer_uptodate(bh)))
271 err = -EIO;
269 __journal_unfile_buffer(jh); 272 __journal_unfile_buffer(jh);
270 jbd_unlock_bh_state(bh); 273 jbd_unlock_bh_state(bh);
271 if (locked) 274 if (locked)
@@ -284,6 +287,8 @@ write_out_data:
284 } 287 }
285 spin_unlock(&journal->j_list_lock); 288 spin_unlock(&journal->j_list_lock);
286 journal_do_submit_data(wbuf, bufs); 289 journal_do_submit_data(wbuf, bufs);
290
291 return err;
287} 292}
288 293
289/* 294/*
@@ -423,8 +428,7 @@ void journal_commit_transaction(journal_t *journal)
423 * Now start flushing things to disk, in the order they appear 428 * Now start flushing things to disk, in the order they appear
424 * on the transaction lists. Data blocks go first. 429 * on the transaction lists. Data blocks go first.
425 */ 430 */
426 err = 0; 431 err = journal_submit_data_buffers(journal, commit_transaction);
427 journal_submit_data_buffers(journal, commit_transaction);
428 432
429 /* 433 /*
430 * Wait for all previously submitted IO to complete. 434 * Wait for all previously submitted IO to complete.
@@ -439,10 +443,21 @@ void journal_commit_transaction(journal_t *journal)
439 if (buffer_locked(bh)) { 443 if (buffer_locked(bh)) {
440 spin_unlock(&journal->j_list_lock); 444 spin_unlock(&journal->j_list_lock);
441 wait_on_buffer(bh); 445 wait_on_buffer(bh);
442 if (unlikely(!buffer_uptodate(bh)))
443 err = -EIO;
444 spin_lock(&journal->j_list_lock); 446 spin_lock(&journal->j_list_lock);
445 } 447 }
448 if (unlikely(!buffer_uptodate(bh))) {
449 if (TestSetPageLocked(bh->b_page)) {
450 spin_unlock(&journal->j_list_lock);
451 lock_page(bh->b_page);
452 spin_lock(&journal->j_list_lock);
453 }
454 if (bh->b_page->mapping)
455 set_bit(AS_EIO, &bh->b_page->mapping->flags);
456
457 unlock_page(bh->b_page);
458 SetPageError(bh->b_page);
459 err = -EIO;
460 }
446 if (!inverted_lock(journal, bh)) { 461 if (!inverted_lock(journal, bh)) {
447 put_bh(bh); 462 put_bh(bh);
448 spin_lock(&journal->j_list_lock); 463 spin_lock(&journal->j_list_lock);
@@ -461,8 +476,14 @@ void journal_commit_transaction(journal_t *journal)
461 } 476 }
462 spin_unlock(&journal->j_list_lock); 477 spin_unlock(&journal->j_list_lock);
463 478
464 if (err) 479 if (err) {
465 journal_abort(journal, err); 480 char b[BDEVNAME_SIZE];
481
482 printk(KERN_WARNING
483 "JBD: Detected IO errors while flushing file data "
484 "on %s\n", bdevname(journal->j_fs_dev, b));
485 err = 0;
486 }
466 487
467 journal_write_revoke_records(journal, commit_transaction); 488 journal_write_revoke_records(journal, commit_transaction);
468 489