diff options
Diffstat (limited to 'fs/jbd')
-rw-r--r-- | fs/jbd/commit.c | 35 |
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 | */ |
188 | static void journal_submit_data_buffers(journal_t *journal, | 188 | static 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 | ||