summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jbd2/transaction.c42
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
1637not_jbd:
1638 jbd_unlock_bh_state(bh); 1667 jbd_unlock_bh_state(bh);
1639 __brelse(bh); 1668 __brelse(bh);
1640drop: 1669drop:
@@ -1643,6 +1672,11 @@ drop:
1643 handle->h_buffer_credits++; 1672 handle->h_buffer_credits++;
1644 } 1673 }
1645 return err; 1674 return err;
1675
1676not_jbd:
1677 jbd_unlock_bh_state(bh);
1678 __bforget(bh);
1679 goto drop;
1646} 1680}
1647 1681
1648/** 1682/**