aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd/transaction.c')
-rw-r--r--fs/jbd/transaction.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index e1b3c8af4d..cceaf57e37 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -27,6 +27,8 @@
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/highmem.h> 28#include <linux/highmem.h>
29 29
30static void __journal_temp_unlink_buffer(struct journal_head *jh);
31
30/* 32/*
31 * get_transaction: obtain a new transaction_t object. 33 * get_transaction: obtain a new transaction_t object.
32 * 34 *
@@ -53,7 +55,7 @@ get_transaction(journal_t *journal, transaction_t *transaction)
53 spin_lock_init(&transaction->t_handle_lock); 55 spin_lock_init(&transaction->t_handle_lock);
54 56
55 /* Set up the commit timer for the new transaction. */ 57 /* Set up the commit timer for the new transaction. */
56 journal->j_commit_timer.expires = transaction->t_expires; 58 journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
57 add_timer(&journal->j_commit_timer); 59 add_timer(&journal->j_commit_timer);
58 60
59 J_ASSERT(journal->j_running_transaction == NULL); 61 J_ASSERT(journal->j_running_transaction == NULL);
@@ -967,6 +969,13 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
967 */ 969 */
968 jbd_lock_bh_state(bh); 970 jbd_lock_bh_state(bh);
969 spin_lock(&journal->j_list_lock); 971 spin_lock(&journal->j_list_lock);
972
973 /* Now that we have bh_state locked, are we really still mapped? */
974 if (!buffer_mapped(bh)) {
975 JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
976 goto no_journal;
977 }
978
970 if (jh->b_transaction) { 979 if (jh->b_transaction) {
971 JBUFFER_TRACE(jh, "has transaction"); 980 JBUFFER_TRACE(jh, "has transaction");
972 if (jh->b_transaction != handle->h_transaction) { 981 if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1037,11 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
1028 sync_dirty_buffer(bh); 1037 sync_dirty_buffer(bh);
1029 jbd_lock_bh_state(bh); 1038 jbd_lock_bh_state(bh);
1030 spin_lock(&journal->j_list_lock); 1039 spin_lock(&journal->j_list_lock);
1040 /* Since we dropped the lock... */
1041 if (!buffer_mapped(bh)) {
1042 JBUFFER_TRACE(jh, "buffer got unmapped");
1043 goto no_journal;
1044 }
1031 /* The buffer may become locked again at any 1045 /* The buffer may become locked again at any
1032 time if it is redirtied */ 1046 time if it is redirtied */
1033 } 1047 }
@@ -1314,13 +1328,14 @@ int journal_stop(handle_t *handle)
1314 int old_handle_count, err; 1328 int old_handle_count, err;
1315 pid_t pid; 1329 pid_t pid;
1316 1330
1317 J_ASSERT(transaction->t_updates > 0);
1318 J_ASSERT(journal_current_handle() == handle); 1331 J_ASSERT(journal_current_handle() == handle);
1319 1332
1320 if (is_handle_aborted(handle)) 1333 if (is_handle_aborted(handle))
1321 err = -EIO; 1334 err = -EIO;
1322 else 1335 else {
1336 J_ASSERT(transaction->t_updates > 0);
1323 err = 0; 1337 err = 0;
1338 }
1324 1339
1325 if (--handle->h_ref > 0) { 1340 if (--handle->h_ref > 0) {
1326 jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, 1341 jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
@@ -1486,7 +1501,7 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh)
1486 * 1501 *
1487 * Called under j_list_lock. The journal may not be locked. 1502 * Called under j_list_lock. The journal may not be locked.
1488 */ 1503 */
1489void __journal_temp_unlink_buffer(struct journal_head *jh) 1504static void __journal_temp_unlink_buffer(struct journal_head *jh)
1490{ 1505{
1491 struct journal_head **list = NULL; 1506 struct journal_head **list = NULL;
1492 transaction_t *transaction; 1507 transaction_t *transaction;
@@ -1823,6 +1838,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
1823 } 1838 }
1824 } 1839 }
1825 } else if (transaction == journal->j_committing_transaction) { 1840 } else if (transaction == journal->j_committing_transaction) {
1841 JBUFFER_TRACE(jh, "on committing transaction");
1826 if (jh->b_jlist == BJ_Locked) { 1842 if (jh->b_jlist == BJ_Locked) {
1827 /* 1843 /*
1828 * The buffer is on the committing transaction's locked 1844 * The buffer is on the committing transaction's locked
@@ -1837,7 +1853,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
1837 * can remove it's next_transaction pointer from the 1853 * can remove it's next_transaction pointer from the
1838 * running transaction if that is set, but nothing 1854 * running transaction if that is set, but nothing
1839 * else. */ 1855 * else. */
1840 JBUFFER_TRACE(jh, "on committing transaction");
1841 set_buffer_freed(bh); 1856 set_buffer_freed(bh);
1842 if (jh->b_next_transaction) { 1857 if (jh->b_next_transaction) {
1843 J_ASSERT(jh->b_next_transaction == 1858 J_ASSERT(jh->b_next_transaction ==
@@ -1857,6 +1872,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
1857 * i_size already for this truncate so recovery will not 1872 * i_size already for this truncate so recovery will not
1858 * expose the disk blocks we are discarding here.) */ 1873 * expose the disk blocks we are discarding here.) */
1859 J_ASSERT_JH(jh, transaction == journal->j_running_transaction); 1874 J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
1875 JBUFFER_TRACE(jh, "on running transaction");
1860 may_free = __dispose_buffer(jh, transaction); 1876 may_free = __dispose_buffer(jh, transaction);
1861 } 1877 }
1862 1878