aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-11-01 03:33:14 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:21 -0500
commitca46963718ef7368c84267c9f5e7394c3890442a (patch)
treea6799d2d2f1b624bca121c0bd3d019d6794bdc03 /fs
parentb7d5b0a819498a9c04e1d18201a42468f7edd92a (diff)
Btrfs: fix missing flush when committing a transaction
Consider the following case: Task1 Task2 start_transaction commit_transaction check pending snapshots list and the list is empty. add pending snapshot into list skip the delalloc flush end_transaction ... And then the problem that the snapshot is different with the source subvolume happen. This patch fixes the above problem by flush all pending stuffs when all the other tasks end the transaction. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/transaction.c82
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
1402static 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