diff options
-rw-r--r-- | fs/jbd2/transaction.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 6f4dff182c91..135f0a10f557 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -1597,9 +1597,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1597 | __jbd2_journal_unfile_buffer(jh); | 1597 | __jbd2_journal_unfile_buffer(jh); |
1598 | if (!buffer_jbd(bh)) { | 1598 | if (!buffer_jbd(bh)) { |
1599 | spin_unlock(&journal->j_list_lock); | 1599 | spin_unlock(&journal->j_list_lock); |
1600 | jbd_unlock_bh_state(bh); | 1600 | goto not_jbd; |
1601 | __bforget(bh); | ||
1602 | goto drop; | ||
1603 | } | 1601 | } |
1604 | } | 1602 | } |
1605 | spin_unlock(&journal->j_list_lock); | 1603 | spin_unlock(&journal->j_list_lock); |
@@ -1632,9 +1630,40 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1632 | if (was_modified) | 1630 | if (was_modified) |
1633 | drop_reserve = 1; | 1631 | drop_reserve = 1; |
1634 | } | 1632 | } |
1633 | } else { | ||
1634 | /* | ||
1635 | * Finally, if the buffer is not belongs to any | ||
1636 | * transaction, we can just drop it now if it has no | ||
1637 | * checkpoint. | ||
1638 | */ | ||
1639 | spin_lock(&journal->j_list_lock); | ||
1640 | if (!jh->b_cp_transaction) { | ||
1641 | JBUFFER_TRACE(jh, "belongs to none transaction"); | ||
1642 | spin_unlock(&journal->j_list_lock); | ||
1643 | goto not_jbd; | ||
1644 | } | ||
1645 | |||
1646 | /* | ||
1647 | * Otherwise, if the buffer has been written to disk, | ||
1648 | * it is safe to remove the checkpoint and drop it. | ||
1649 | */ | ||
1650 | if (!buffer_dirty(bh)) { | ||
1651 | __jbd2_journal_remove_checkpoint(jh); | ||
1652 | spin_unlock(&journal->j_list_lock); | ||
1653 | goto not_jbd; | ||
1654 | } | ||
1655 | |||
1656 | /* | ||
1657 | * The buffer is still not written to disk, we should | ||
1658 | * attach this buffer to current transaction so that the | ||
1659 | * buffer can be checkpointed only after the current | ||
1660 | * transaction commits. | ||
1661 | */ | ||
1662 | clear_buffer_dirty(bh); | ||
1663 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); | ||
1664 | spin_unlock(&journal->j_list_lock); | ||
1635 | } | 1665 | } |
1636 | 1666 | ||
1637 | not_jbd: | ||
1638 | jbd_unlock_bh_state(bh); | 1667 | jbd_unlock_bh_state(bh); |
1639 | __brelse(bh); | 1668 | __brelse(bh); |
1640 | drop: | 1669 | drop: |
@@ -1643,6 +1672,11 @@ drop: | |||
1643 | handle->h_buffer_credits++; | 1672 | handle->h_buffer_credits++; |
1644 | } | 1673 | } |
1645 | return err; | 1674 | return err; |
1675 | |||
1676 | not_jbd: | ||
1677 | jbd_unlock_bh_state(bh); | ||
1678 | __bforget(bh); | ||
1679 | goto drop; | ||
1646 | } | 1680 | } |
1647 | 1681 | ||
1648 | /** | 1682 | /** |