diff options
| -rw-r--r-- | fs/jbd2/transaction.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index cc35537232f2..6f4dff182c91 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -1609,14 +1609,21 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
| 1609 | /* However, if the buffer is still owned by a prior | 1609 | /* However, if the buffer is still owned by a prior |
| 1610 | * (committing) transaction, we can't drop it yet... */ | 1610 | * (committing) transaction, we can't drop it yet... */ |
| 1611 | JBUFFER_TRACE(jh, "belongs to older transaction"); | 1611 | JBUFFER_TRACE(jh, "belongs to older transaction"); |
| 1612 | /* ... but we CAN drop it from the new transaction if we | 1612 | /* ... but we CAN drop it from the new transaction through |
| 1613 | * have also modified it since the original commit. */ | 1613 | * marking the buffer as freed and set j_next_transaction to |
| 1614 | * the new transaction, so that not only the commit code | ||
| 1615 | * knows it should clear dirty bits when it is done with the | ||
| 1616 | * buffer, but also the buffer can be checkpointed only | ||
| 1617 | * after the new transaction commits. */ | ||
| 1614 | 1618 | ||
| 1615 | if (jh->b_next_transaction) { | 1619 | set_buffer_freed(bh); |
| 1616 | J_ASSERT(jh->b_next_transaction == transaction); | 1620 | |
| 1621 | if (!jh->b_next_transaction) { | ||
| 1617 | spin_lock(&journal->j_list_lock); | 1622 | spin_lock(&journal->j_list_lock); |
| 1618 | jh->b_next_transaction = NULL; | 1623 | jh->b_next_transaction = transaction; |
| 1619 | spin_unlock(&journal->j_list_lock); | 1624 | spin_unlock(&journal->j_list_lock); |
| 1625 | } else { | ||
| 1626 | J_ASSERT(jh->b_next_transaction == transaction); | ||
| 1620 | 1627 | ||
| 1621 | /* | 1628 | /* |
| 1622 | * only drop a reference if this transaction modified | 1629 | * only drop a reference if this transaction modified |
