diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 44a5d73fddbe..bc1f52397334 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1399,6 +1399,48 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1399 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 1399 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | ||
1403 | struct btrfs_root *root) | ||
1404 | { | ||
1405 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | ||
1406 | int snap_pending = 0; | ||
1407 | int ret; | ||
1408 | |||
1409 | if (!flush_on_commit) { | ||
1410 | spin_lock(&root->fs_info->trans_lock); | ||
1411 | if (!list_empty(&trans->transaction->pending_snapshots)) | ||
1412 | snap_pending = 1; | ||
1413 | spin_unlock(&root->fs_info->trans_lock); | ||
1414 | } | ||
1415 | |||
1416 | if (flush_on_commit || snap_pending) { | ||
1417 | btrfs_start_delalloc_inodes(root, 1); | ||
1418 | btrfs_wait_ordered_extents(root, 1); | ||
1419 | } | ||
1420 | |||
1421 | ret = btrfs_run_delayed_items(trans, root); | ||
1422 | if (ret) | ||
1423 | return ret; | ||
1424 | |||
1425 | /* | ||
1426 | * running the delayed items may have added new refs. account | ||
1427 | * them now so that they hinder processing of more delayed refs | ||
1428 | * as little as possible. | ||
1429 | */ | ||
1430 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1431 | |||
1432 | /* | ||
1433 | * rename don't use btrfs_join_transaction, so, once we | ||
1434 | * set the transaction to blocked above, we aren't going | ||
1435 | * to get any new ordered operations. We can safely run | ||
1436 | * it here and no for sure that nothing new will be added | ||
1437 | * to the list | ||
1438 | */ | ||
1439 | btrfs_run_ordered_operations(root, 1); | ||
1440 | |||
1441 | return 0; | ||
1442 | } | ||
1443 | |||
1402 | /* | 1444 | /* |
1403 | * btrfs_transaction state sequence: | 1445 | * btrfs_transaction state sequence: |
1404 | * in_commit = 0, blocked = 0 (initial) | 1446 | * in_commit = 0, blocked = 0 (initial) |
@@ -1416,7 +1458,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1416 | int ret; | 1458 | int ret; |
1417 | int should_grow = 0; | 1459 | int should_grow = 0; |
1418 | unsigned long now = get_seconds(); | 1460 | unsigned long now = get_seconds(); |
1419 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | ||
1420 | 1461 | ||
1421 | ret = btrfs_run_ordered_operations(root, 0); | 1462 | ret = btrfs_run_ordered_operations(root, 0); |
1422 | if (ret) { | 1463 | if (ret) { |
@@ -1495,47 +1536,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1495 | should_grow = 1; | 1536 | should_grow = 1; |
1496 | 1537 | ||
1497 | do { | 1538 | do { |
1498 | int snap_pending = 0; | ||
1499 | |||
1500 | joined = cur_trans->num_joined; | 1539 | joined = cur_trans->num_joined; |
1501 | if (!list_empty(&trans->transaction->pending_snapshots)) | ||
1502 | snap_pending = 1; | ||
1503 | 1540 | ||
1504 | WARN_ON(cur_trans != trans->transaction); | 1541 | WARN_ON(cur_trans != trans->transaction); |
1505 | 1542 | ||
1506 | if (flush_on_commit || snap_pending) { | 1543 | ret = btrfs_flush_all_pending_stuffs(trans, root); |
1507 | ret = btrfs_start_delalloc_inodes(root, 1); | ||
1508 | if (ret) { | ||
1509 | btrfs_abort_transaction(trans, root, ret); | ||
1510 | goto cleanup_transaction; | ||
1511 | } | ||
1512 | btrfs_wait_ordered_extents(root, 1); | ||
1513 | } | ||
1514 | |||
1515 | ret = btrfs_run_delayed_items(trans, root); | ||
1516 | if (ret) | 1544 | if (ret) |
1517 | goto cleanup_transaction; | 1545 | goto cleanup_transaction; |
1518 | 1546 | ||
1519 | /* | ||
1520 | * running the delayed items may have added new refs. account | ||
1521 | * them now so that they hinder processing of more delayed refs | ||
1522 | * as little as possible. | ||
1523 | */ | ||
1524 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1525 | |||
1526 | /* | ||
1527 | * rename don't use btrfs_join_transaction, so, once we | ||
1528 | * set the transaction to blocked above, we aren't going | ||
1529 | * to get any new ordered operations. We can safely run | ||
1530 | * it here and no for sure that nothing new will be added | ||
1531 | * to the list | ||
1532 | */ | ||
1533 | ret = btrfs_run_ordered_operations(root, 1); | ||
1534 | if (ret) { | ||
1535 | btrfs_abort_transaction(trans, root, ret); | ||
1536 | goto cleanup_transaction; | ||
1537 | } | ||
1538 | |||
1539 | prepare_to_wait(&cur_trans->writer_wait, &wait, | 1547 | prepare_to_wait(&cur_trans->writer_wait, &wait, |
1540 | TASK_UNINTERRUPTIBLE); | 1548 | TASK_UNINTERRUPTIBLE); |
1541 | 1549 | ||
@@ -1548,6 +1556,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1548 | } while (atomic_read(&cur_trans->num_writers) > 1 || | 1556 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
1549 | (should_grow && cur_trans->num_joined != joined)); | 1557 | (should_grow && cur_trans->num_joined != joined)); |
1550 | 1558 | ||
1559 | ret = btrfs_flush_all_pending_stuffs(trans, root); | ||
1560 | if (ret) | ||
1561 | goto cleanup_transaction; | ||
1562 | |||
1551 | /* | 1563 | /* |
1552 | * Ok now we need to make sure to block out any other joins while we | 1564 | * Ok now we need to make sure to block out any other joins while we |
1553 | * commit the transaction. We could have started a join before setting | 1565 | * commit the transaction. We could have started a join before setting |