aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/transaction.c')
-rw-r--r--fs/jbd2/transaction.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 60bb365f54a5..38cfcf5f6fce 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1073,7 +1073,6 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
1073 * reused here. 1073 * reused here.
1074 */ 1074 */
1075 jbd_lock_bh_state(bh); 1075 jbd_lock_bh_state(bh);
1076 spin_lock(&journal->j_list_lock);
1077 J_ASSERT_JH(jh, (jh->b_transaction == transaction || 1076 J_ASSERT_JH(jh, (jh->b_transaction == transaction ||
1078 jh->b_transaction == NULL || 1077 jh->b_transaction == NULL ||
1079 (jh->b_transaction == journal->j_committing_transaction && 1078 (jh->b_transaction == journal->j_committing_transaction &&
@@ -1096,12 +1095,14 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
1096 jh->b_modified = 0; 1095 jh->b_modified = 0;
1097 1096
1098 JBUFFER_TRACE(jh, "file as BJ_Reserved"); 1097 JBUFFER_TRACE(jh, "file as BJ_Reserved");
1098 spin_lock(&journal->j_list_lock);
1099 __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); 1099 __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
1100 } else if (jh->b_transaction == journal->j_committing_transaction) { 1100 } else if (jh->b_transaction == journal->j_committing_transaction) {
1101 /* first access by this transaction */ 1101 /* first access by this transaction */
1102 jh->b_modified = 0; 1102 jh->b_modified = 0;
1103 1103
1104 JBUFFER_TRACE(jh, "set next transaction"); 1104 JBUFFER_TRACE(jh, "set next transaction");
1105 spin_lock(&journal->j_list_lock);
1105 jh->b_next_transaction = transaction; 1106 jh->b_next_transaction = transaction;
1106 } 1107 }
1107 spin_unlock(&journal->j_list_lock); 1108 spin_unlock(&journal->j_list_lock);
@@ -1312,7 +1313,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
1312 journal->j_running_transaction)) { 1313 journal->j_running_transaction)) {
1313 printk(KERN_ERR "JBD2: %s: " 1314 printk(KERN_ERR "JBD2: %s: "
1314 "jh->b_transaction (%llu, %p, %u) != " 1315 "jh->b_transaction (%llu, %p, %u) != "
1315 "journal->j_running_transaction (%p, %u)", 1316 "journal->j_running_transaction (%p, %u)\n",
1316 journal->j_devname, 1317 journal->j_devname,
1317 (unsigned long long) bh->b_blocknr, 1318 (unsigned long long) bh->b_blocknr,
1318 jh->b_transaction, 1319 jh->b_transaction,
@@ -1335,30 +1336,25 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
1335 */ 1336 */
1336 if (jh->b_transaction != transaction) { 1337 if (jh->b_transaction != transaction) {
1337 JBUFFER_TRACE(jh, "already on other transaction"); 1338 JBUFFER_TRACE(jh, "already on other transaction");
1338 if (unlikely(jh->b_transaction != 1339 if (unlikely(((jh->b_transaction !=
1339 journal->j_committing_transaction)) { 1340 journal->j_committing_transaction)) ||
1340 printk(KERN_ERR "JBD2: %s: " 1341 (jh->b_next_transaction != transaction))) {
1341 "jh->b_transaction (%llu, %p, %u) != " 1342 printk(KERN_ERR "jbd2_journal_dirty_metadata: %s: "
1342 "journal->j_committing_transaction (%p, %u)", 1343 "bad jh for block %llu: "
1344 "transaction (%p, %u), "
1345 "jh->b_transaction (%p, %u), "
1346 "jh->b_next_transaction (%p, %u), jlist %u\n",
1343 journal->j_devname, 1347 journal->j_devname,
1344 (unsigned long long) bh->b_blocknr, 1348 (unsigned long long) bh->b_blocknr,
1349 transaction, transaction->t_tid,
1345 jh->b_transaction, 1350 jh->b_transaction,
1346 jh->b_transaction ? jh->b_transaction->t_tid : 0, 1351 jh->b_transaction ?
1347 journal->j_committing_transaction, 1352 jh->b_transaction->t_tid : 0,
1348 journal->j_committing_transaction ?
1349 journal->j_committing_transaction->t_tid : 0);
1350 ret = -EINVAL;
1351 }
1352 if (unlikely(jh->b_next_transaction != transaction)) {
1353 printk(KERN_ERR "JBD2: %s: "
1354 "jh->b_next_transaction (%llu, %p, %u) != "
1355 "transaction (%p, %u)",
1356 journal->j_devname,
1357 (unsigned long long) bh->b_blocknr,
1358 jh->b_next_transaction, 1353 jh->b_next_transaction,
1359 jh->b_next_transaction ? 1354 jh->b_next_transaction ?
1360 jh->b_next_transaction->t_tid : 0, 1355 jh->b_next_transaction->t_tid : 0,
1361 transaction, transaction->t_tid); 1356 jh->b_jlist);
1357 WARN_ON(1);
1362 ret = -EINVAL; 1358 ret = -EINVAL;
1363 } 1359 }
1364 /* And this case is illegal: we can't reuse another 1360 /* And this case is illegal: we can't reuse another
@@ -1415,7 +1411,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
1415 BUFFER_TRACE(bh, "entry"); 1411 BUFFER_TRACE(bh, "entry");
1416 1412
1417 jbd_lock_bh_state(bh); 1413 jbd_lock_bh_state(bh);
1418 spin_lock(&journal->j_list_lock);
1419 1414
1420 if (!buffer_jbd(bh)) 1415 if (!buffer_jbd(bh))
1421 goto not_jbd; 1416 goto not_jbd;
@@ -1468,6 +1463,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
1468 * we know to remove the checkpoint after we commit. 1463 * we know to remove the checkpoint after we commit.
1469 */ 1464 */
1470 1465
1466 spin_lock(&journal->j_list_lock);
1471 if (jh->b_cp_transaction) { 1467 if (jh->b_cp_transaction) {
1472 __jbd2_journal_temp_unlink_buffer(jh); 1468 __jbd2_journal_temp_unlink_buffer(jh);
1473 __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); 1469 __jbd2_journal_file_buffer(jh, transaction, BJ_Forget);
@@ -1480,6 +1476,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
1480 goto drop; 1476 goto drop;
1481 } 1477 }
1482 } 1478 }
1479 spin_unlock(&journal->j_list_lock);
1483 } else if (jh->b_transaction) { 1480 } else if (jh->b_transaction) {
1484 J_ASSERT_JH(jh, (jh->b_transaction == 1481 J_ASSERT_JH(jh, (jh->b_transaction ==
1485 journal->j_committing_transaction)); 1482 journal->j_committing_transaction));
@@ -1491,7 +1488,9 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
1491 1488
1492 if (jh->b_next_transaction) { 1489 if (jh->b_next_transaction) {
1493 J_ASSERT(jh->b_next_transaction == transaction); 1490 J_ASSERT(jh->b_next_transaction == transaction);
1491 spin_lock(&journal->j_list_lock);
1494 jh->b_next_transaction = NULL; 1492 jh->b_next_transaction = NULL;
1493 spin_unlock(&journal->j_list_lock);
1495 1494
1496 /* 1495 /*
1497 * only drop a reference if this transaction modified 1496 * only drop a reference if this transaction modified
@@ -1503,7 +1502,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
1503 } 1502 }
1504 1503
1505not_jbd: 1504not_jbd:
1506 spin_unlock(&journal->j_list_lock);
1507 jbd_unlock_bh_state(bh); 1505 jbd_unlock_bh_state(bh);
1508 __brelse(bh); 1506 __brelse(bh);
1509drop: 1507drop:
@@ -1821,11 +1819,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
1821 if (buffer_locked(bh) || buffer_dirty(bh)) 1819 if (buffer_locked(bh) || buffer_dirty(bh))
1822 goto out; 1820 goto out;
1823 1821
1824 if (jh->b_next_transaction != NULL) 1822 if (jh->b_next_transaction != NULL || jh->b_transaction != NULL)
1825 goto out; 1823 goto out;
1826 1824
1827 spin_lock(&journal->j_list_lock); 1825 spin_lock(&journal->j_list_lock);
1828 if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { 1826 if (jh->b_cp_transaction != NULL) {
1829 /* written-back checkpointed metadata buffer */ 1827 /* written-back checkpointed metadata buffer */
1830 JBUFFER_TRACE(jh, "remove from checkpoint list"); 1828 JBUFFER_TRACE(jh, "remove from checkpoint list");
1831 __jbd2_journal_remove_checkpoint(jh); 1829 __jbd2_journal_remove_checkpoint(jh);