diff options
Diffstat (limited to 'fs/jbd2/transaction.c')
| -rw-r--r-- | fs/jbd2/transaction.c | 46 |
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 | ||
| 1505 | not_jbd: | 1504 | not_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); |
| 1509 | drop: | 1507 | drop: |
| @@ -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); |
