diff options
Diffstat (limited to 'fs/jbd/transaction.c')
-rw-r--r-- | fs/jbd/transaction.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 77b7662b840b..c6ec66fd8766 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -490,23 +490,21 @@ void journal_unlock_updates (journal_t *journal) | |||
490 | */ | 490 | */ |
491 | static void jbd_unexpected_dirty_buffer(struct journal_head *jh) | 491 | static void jbd_unexpected_dirty_buffer(struct journal_head *jh) |
492 | { | 492 | { |
493 | struct buffer_head *bh = jh2bh(jh); | ||
494 | int jlist; | 493 | int jlist; |
495 | 494 | ||
496 | if (buffer_dirty(bh)) { | 495 | /* If this buffer is one which might reasonably be dirty |
497 | /* If this buffer is one which might reasonably be dirty | 496 | * --- ie. data, or not part of this journal --- then |
498 | * --- ie. data, or not part of this journal --- then | 497 | * we're OK to leave it alone, but otherwise we need to |
499 | * we're OK to leave it alone, but otherwise we need to | 498 | * move the dirty bit to the journal's own internal |
500 | * move the dirty bit to the journal's own internal | 499 | * JBDDirty bit. */ |
501 | * JBDDirty bit. */ | 500 | jlist = jh->b_jlist; |
502 | jlist = jh->b_jlist; | 501 | |
503 | 502 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | |
504 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 503 | jlist == BJ_Shadow || jlist == BJ_Forget) { |
505 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 504 | struct buffer_head *bh = jh2bh(jh); |
506 | if (test_clear_buffer_dirty(jh2bh(jh))) { | 505 | |
507 | set_bit(BH_JBDDirty, &jh2bh(jh)->b_state); | 506 | if (test_clear_buffer_dirty(bh)) |
508 | } | 507 | set_buffer_jbddirty(bh); |
509 | } | ||
510 | } | 508 | } |
511 | } | 509 | } |
512 | 510 | ||
@@ -574,9 +572,14 @@ repeat: | |||
574 | if (jh->b_next_transaction) | 572 | if (jh->b_next_transaction) |
575 | J_ASSERT_JH(jh, jh->b_next_transaction == | 573 | J_ASSERT_JH(jh, jh->b_next_transaction == |
576 | transaction); | 574 | transaction); |
577 | JBUFFER_TRACE(jh, "Unexpected dirty buffer"); | 575 | } |
578 | jbd_unexpected_dirty_buffer(jh); | 576 | /* |
579 | } | 577 | * In any case we need to clean the dirty flag and we must |
578 | * do it under the buffer lock to be sure we don't race | ||
579 | * with running write-out. | ||
580 | */ | ||
581 | JBUFFER_TRACE(jh, "Unexpected dirty buffer"); | ||
582 | jbd_unexpected_dirty_buffer(jh); | ||
580 | } | 583 | } |
581 | 584 | ||
582 | unlock_buffer(bh); | 585 | unlock_buffer(bh); |