diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 170 |
1 files changed, 99 insertions, 71 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 04bbfb1052eb..87fac9a21ea5 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "tree-log.h" | 30 | #include "tree-log.h" |
31 | #include "inode-map.h" | 31 | #include "inode-map.h" |
32 | #include "volumes.h" | 32 | #include "volumes.h" |
33 | #include "dev-replace.h" | ||
33 | 34 | ||
34 | #define BTRFS_ROOT_TRANS_TAG 0 | 35 | #define BTRFS_ROOT_TRANS_TAG 0 |
35 | 36 | ||
@@ -145,16 +146,12 @@ loop: | |||
145 | * the log must never go across transaction boundaries. | 146 | * the log must never go across transaction boundaries. |
146 | */ | 147 | */ |
147 | smp_mb(); | 148 | smp_mb(); |
148 | if (!list_empty(&fs_info->tree_mod_seq_list)) { | 149 | if (!list_empty(&fs_info->tree_mod_seq_list)) |
149 | printk(KERN_ERR "btrfs: tree_mod_seq_list not empty when " | 150 | WARN(1, KERN_ERR "btrfs: tree_mod_seq_list not empty when " |
150 | "creating a fresh transaction\n"); | 151 | "creating a fresh transaction\n"); |
151 | WARN_ON(1); | 152 | if (!RB_EMPTY_ROOT(&fs_info->tree_mod_log)) |
152 | } | 153 | WARN(1, KERN_ERR "btrfs: tree_mod_log rb tree not empty when " |
153 | if (!RB_EMPTY_ROOT(&fs_info->tree_mod_log)) { | ||
154 | printk(KERN_ERR "btrfs: tree_mod_log rb tree not empty when " | ||
155 | "creating a fresh transaction\n"); | 154 | "creating a fresh transaction\n"); |
156 | WARN_ON(1); | ||
157 | } | ||
158 | atomic_set(&fs_info->tree_mod_seq, 0); | 155 | atomic_set(&fs_info->tree_mod_seq, 0); |
159 | 156 | ||
160 | spin_lock_init(&cur_trans->commit_lock); | 157 | spin_lock_init(&cur_trans->commit_lock); |
@@ -295,9 +292,9 @@ static int may_wait_transaction(struct btrfs_root *root, int type) | |||
295 | return 0; | 292 | return 0; |
296 | } | 293 | } |
297 | 294 | ||
298 | static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | 295 | static struct btrfs_trans_handle * |
299 | u64 num_items, int type, | 296 | start_transaction(struct btrfs_root *root, u64 num_items, int type, |
300 | int noflush) | 297 | enum btrfs_reserve_flush_enum flush) |
301 | { | 298 | { |
302 | struct btrfs_trans_handle *h; | 299 | struct btrfs_trans_handle *h; |
303 | struct btrfs_transaction *cur_trans; | 300 | struct btrfs_transaction *cur_trans; |
@@ -312,6 +309,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
312 | WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK); | 309 | WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK); |
313 | h = current->journal_info; | 310 | h = current->journal_info; |
314 | h->use_count++; | 311 | h->use_count++; |
312 | WARN_ON(h->use_count > 2); | ||
315 | h->orig_rsv = h->block_rsv; | 313 | h->orig_rsv = h->block_rsv; |
316 | h->block_rsv = NULL; | 314 | h->block_rsv = NULL; |
317 | goto got_it; | 315 | goto got_it; |
@@ -331,14 +329,9 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
331 | } | 329 | } |
332 | 330 | ||
333 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); | 331 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); |
334 | if (noflush) | 332 | ret = btrfs_block_rsv_add(root, |
335 | ret = btrfs_block_rsv_add_noflush(root, | 333 | &root->fs_info->trans_block_rsv, |
336 | &root->fs_info->trans_block_rsv, | 334 | num_bytes, flush); |
337 | num_bytes); | ||
338 | else | ||
339 | ret = btrfs_block_rsv_add(root, | ||
340 | &root->fs_info->trans_block_rsv, | ||
341 | num_bytes); | ||
342 | if (ret) | 335 | if (ret) |
343 | return ERR_PTR(ret); | 336 | return ERR_PTR(ret); |
344 | } | 337 | } |
@@ -422,13 +415,15 @@ got_it: | |||
422 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 415 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |
423 | int num_items) | 416 | int num_items) |
424 | { | 417 | { |
425 | return start_transaction(root, num_items, TRANS_START, 0); | 418 | return start_transaction(root, num_items, TRANS_START, |
419 | BTRFS_RESERVE_FLUSH_ALL); | ||
426 | } | 420 | } |
427 | 421 | ||
428 | struct btrfs_trans_handle *btrfs_start_transaction_noflush( | 422 | struct btrfs_trans_handle *btrfs_start_transaction_lflush( |
429 | struct btrfs_root *root, int num_items) | 423 | struct btrfs_root *root, int num_items) |
430 | { | 424 | { |
431 | return start_transaction(root, num_items, TRANS_START, 1); | 425 | return start_transaction(root, num_items, TRANS_START, |
426 | BTRFS_RESERVE_FLUSH_LIMIT); | ||
432 | } | 427 | } |
433 | 428 | ||
434 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root) | 429 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root) |
@@ -461,28 +456,31 @@ static noinline void wait_for_commit(struct btrfs_root *root, | |||
461 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | 456 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) |
462 | { | 457 | { |
463 | struct btrfs_transaction *cur_trans = NULL, *t; | 458 | struct btrfs_transaction *cur_trans = NULL, *t; |
464 | int ret; | 459 | int ret = 0; |
465 | 460 | ||
466 | ret = 0; | ||
467 | if (transid) { | 461 | if (transid) { |
468 | if (transid <= root->fs_info->last_trans_committed) | 462 | if (transid <= root->fs_info->last_trans_committed) |
469 | goto out; | 463 | goto out; |
470 | 464 | ||
465 | ret = -EINVAL; | ||
471 | /* find specified transaction */ | 466 | /* find specified transaction */ |
472 | spin_lock(&root->fs_info->trans_lock); | 467 | spin_lock(&root->fs_info->trans_lock); |
473 | list_for_each_entry(t, &root->fs_info->trans_list, list) { | 468 | list_for_each_entry(t, &root->fs_info->trans_list, list) { |
474 | if (t->transid == transid) { | 469 | if (t->transid == transid) { |
475 | cur_trans = t; | 470 | cur_trans = t; |
476 | atomic_inc(&cur_trans->use_count); | 471 | atomic_inc(&cur_trans->use_count); |
472 | ret = 0; | ||
477 | break; | 473 | break; |
478 | } | 474 | } |
479 | if (t->transid > transid) | 475 | if (t->transid > transid) { |
476 | ret = 0; | ||
480 | break; | 477 | break; |
478 | } | ||
481 | } | 479 | } |
482 | spin_unlock(&root->fs_info->trans_lock); | 480 | spin_unlock(&root->fs_info->trans_lock); |
483 | ret = -EINVAL; | 481 | /* The specified transaction doesn't exist */ |
484 | if (!cur_trans) | 482 | if (!cur_trans) |
485 | goto out; /* bad transid */ | 483 | goto out; |
486 | } else { | 484 | } else { |
487 | /* find newest transaction that is committing | committed */ | 485 | /* find newest transaction that is committing | committed */ |
488 | spin_lock(&root->fs_info->trans_lock); | 486 | spin_lock(&root->fs_info->trans_lock); |
@@ -502,9 +500,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
502 | } | 500 | } |
503 | 501 | ||
504 | wait_for_commit(root, cur_trans); | 502 | wait_for_commit(root, cur_trans); |
505 | |||
506 | put_transaction(cur_trans); | 503 | put_transaction(cur_trans); |
507 | ret = 0; | ||
508 | out: | 504 | out: |
509 | return ret; | 505 | return ret; |
510 | } | 506 | } |
@@ -851,7 +847,9 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
851 | return ret; | 847 | return ret; |
852 | 848 | ||
853 | ret = btrfs_run_dev_stats(trans, root->fs_info); | 849 | ret = btrfs_run_dev_stats(trans, root->fs_info); |
854 | BUG_ON(ret); | 850 | WARN_ON(ret); |
851 | ret = btrfs_run_dev_replace(trans, root->fs_info); | ||
852 | WARN_ON(ret); | ||
855 | 853 | ||
856 | ret = btrfs_run_qgroups(trans, root->fs_info); | 854 | ret = btrfs_run_qgroups(trans, root->fs_info); |
857 | BUG_ON(ret); | 855 | BUG_ON(ret); |
@@ -874,6 +872,8 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
874 | switch_commit_root(fs_info->extent_root); | 872 | switch_commit_root(fs_info->extent_root); |
875 | up_write(&fs_info->extent_commit_sem); | 873 | up_write(&fs_info->extent_commit_sem); |
876 | 874 | ||
875 | btrfs_after_dev_replace_commit(fs_info); | ||
876 | |||
877 | return 0; | 877 | return 0; |
878 | } | 878 | } |
879 | 879 | ||
@@ -958,7 +958,6 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
958 | struct btrfs_fs_info *info = root->fs_info; | 958 | struct btrfs_fs_info *info = root->fs_info; |
959 | struct btrfs_trans_handle *trans; | 959 | struct btrfs_trans_handle *trans; |
960 | int ret; | 960 | int ret; |
961 | unsigned long nr; | ||
962 | 961 | ||
963 | if (xchg(&root->defrag_running, 1)) | 962 | if (xchg(&root->defrag_running, 1)) |
964 | return 0; | 963 | return 0; |
@@ -970,9 +969,8 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
970 | 969 | ||
971 | ret = btrfs_defrag_leaves(trans, root, cacheonly); | 970 | ret = btrfs_defrag_leaves(trans, root, cacheonly); |
972 | 971 | ||
973 | nr = trans->blocks_used; | ||
974 | btrfs_end_transaction(trans, root); | 972 | btrfs_end_transaction(trans, root); |
975 | btrfs_btree_balance_dirty(info->tree_root, nr); | 973 | btrfs_btree_balance_dirty(info->tree_root); |
976 | cond_resched(); | 974 | cond_resched(); |
977 | 975 | ||
978 | if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN) | 976 | if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN) |
@@ -1032,8 +1030,9 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1032 | btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); | 1030 | btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); |
1033 | 1031 | ||
1034 | if (to_reserve > 0) { | 1032 | if (to_reserve > 0) { |
1035 | ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv, | 1033 | ret = btrfs_block_rsv_add(root, &pending->block_rsv, |
1036 | to_reserve); | 1034 | to_reserve, |
1035 | BTRFS_RESERVE_NO_FLUSH); | ||
1037 | if (ret) { | 1036 | if (ret) { |
1038 | pending->error = ret; | 1037 | pending->error = ret; |
1039 | goto no_free_objectid; | 1038 | goto no_free_objectid; |
@@ -1191,7 +1190,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1191 | parent_inode, &key, | 1190 | parent_inode, &key, |
1192 | BTRFS_FT_DIR, index); | 1191 | BTRFS_FT_DIR, index); |
1193 | /* We have check then name at the beginning, so it is impossible. */ | 1192 | /* We have check then name at the beginning, so it is impossible. */ |
1194 | BUG_ON(ret == -EEXIST); | 1193 | BUG_ON(ret == -EEXIST || ret == -EOVERFLOW); |
1195 | if (ret) { | 1194 | if (ret) { |
1196 | btrfs_abort_transaction(trans, root, ret); | 1195 | btrfs_abort_transaction(trans, root, ret); |
1197 | goto fail; | 1196 | goto fail; |
@@ -1309,9 +1308,10 @@ static void do_async_commit(struct work_struct *work) | |||
1309 | * We've got freeze protection passed with the transaction. | 1308 | * We've got freeze protection passed with the transaction. |
1310 | * Tell lockdep about it. | 1309 | * Tell lockdep about it. |
1311 | */ | 1310 | */ |
1312 | rwsem_acquire_read( | 1311 | if (ac->newtrans->type < TRANS_JOIN_NOLOCK) |
1313 | &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | 1312 | rwsem_acquire_read( |
1314 | 0, 1, _THIS_IP_); | 1313 | &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], |
1314 | 0, 1, _THIS_IP_); | ||
1315 | 1315 | ||
1316 | current->journal_info = ac->newtrans; | 1316 | current->journal_info = ac->newtrans; |
1317 | 1317 | ||
@@ -1349,8 +1349,10 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1349 | * Tell lockdep we've released the freeze rwsem, since the | 1349 | * Tell lockdep we've released the freeze rwsem, since the |
1350 | * async commit thread will be the one to unlock it. | 1350 | * async commit thread will be the one to unlock it. |
1351 | */ | 1351 | */ |
1352 | rwsem_release(&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | 1352 | if (trans->type < TRANS_JOIN_NOLOCK) |
1353 | 1, _THIS_IP_); | 1353 | rwsem_release( |
1354 | &root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | ||
1355 | 1, _THIS_IP_); | ||
1354 | 1356 | ||
1355 | schedule_delayed_work(&ac->work, 0); | 1357 | schedule_delayed_work(&ac->work, 0); |
1356 | 1358 | ||
@@ -1400,6 +1402,48 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1400 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 1402 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
1401 | } | 1403 | } |
1402 | 1404 | ||
1405 | static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | ||
1406 | struct btrfs_root *root) | ||
1407 | { | ||
1408 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | ||
1409 | int snap_pending = 0; | ||
1410 | int ret; | ||
1411 | |||
1412 | if (!flush_on_commit) { | ||
1413 | spin_lock(&root->fs_info->trans_lock); | ||
1414 | if (!list_empty(&trans->transaction->pending_snapshots)) | ||
1415 | snap_pending = 1; | ||
1416 | spin_unlock(&root->fs_info->trans_lock); | ||
1417 | } | ||
1418 | |||
1419 | if (flush_on_commit || snap_pending) { | ||
1420 | btrfs_start_delalloc_inodes(root, 1); | ||
1421 | btrfs_wait_ordered_extents(root, 1); | ||
1422 | } | ||
1423 | |||
1424 | ret = btrfs_run_delayed_items(trans, root); | ||
1425 | if (ret) | ||
1426 | return ret; | ||
1427 | |||
1428 | /* | ||
1429 | * running the delayed items may have added new refs. account | ||
1430 | * them now so that they hinder processing of more delayed refs | ||
1431 | * as little as possible. | ||
1432 | */ | ||
1433 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1434 | |||
1435 | /* | ||
1436 | * rename don't use btrfs_join_transaction, so, once we | ||
1437 | * set the transaction to blocked above, we aren't going | ||
1438 | * to get any new ordered operations. We can safely run | ||
1439 | * it here and no for sure that nothing new will be added | ||
1440 | * to the list | ||
1441 | */ | ||
1442 | btrfs_run_ordered_operations(root, 1); | ||
1443 | |||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1403 | /* | 1447 | /* |
1404 | * btrfs_transaction state sequence: | 1448 | * btrfs_transaction state sequence: |
1405 | * in_commit = 0, blocked = 0 (initial) | 1449 | * in_commit = 0, blocked = 0 (initial) |
@@ -1414,15 +1458,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1414 | struct btrfs_transaction *cur_trans = trans->transaction; | 1458 | struct btrfs_transaction *cur_trans = trans->transaction; |
1415 | struct btrfs_transaction *prev_trans = NULL; | 1459 | struct btrfs_transaction *prev_trans = NULL; |
1416 | DEFINE_WAIT(wait); | 1460 | DEFINE_WAIT(wait); |
1417 | int ret = -EIO; | 1461 | int ret; |
1418 | int should_grow = 0; | 1462 | int should_grow = 0; |
1419 | unsigned long now = get_seconds(); | 1463 | unsigned long now = get_seconds(); |
1420 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | ||
1421 | 1464 | ||
1422 | btrfs_run_ordered_operations(root, 0); | 1465 | ret = btrfs_run_ordered_operations(root, 0); |
1466 | if (ret) { | ||
1467 | btrfs_abort_transaction(trans, root, ret); | ||
1468 | goto cleanup_transaction; | ||
1469 | } | ||
1423 | 1470 | ||
1424 | if (cur_trans->aborted) | 1471 | if (cur_trans->aborted) { |
1472 | ret = cur_trans->aborted; | ||
1425 | goto cleanup_transaction; | 1473 | goto cleanup_transaction; |
1474 | } | ||
1426 | 1475 | ||
1427 | /* make a pass through all the delayed refs we have so far | 1476 | /* make a pass through all the delayed refs we have so far |
1428 | * any runnings procs may add more while we are here | 1477 | * any runnings procs may add more while we are here |
@@ -1490,39 +1539,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1490 | should_grow = 1; | 1539 | should_grow = 1; |
1491 | 1540 | ||
1492 | do { | 1541 | do { |
1493 | int snap_pending = 0; | ||
1494 | |||
1495 | joined = cur_trans->num_joined; | 1542 | joined = cur_trans->num_joined; |
1496 | if (!list_empty(&trans->transaction->pending_snapshots)) | ||
1497 | snap_pending = 1; | ||
1498 | 1543 | ||
1499 | WARN_ON(cur_trans != trans->transaction); | 1544 | WARN_ON(cur_trans != trans->transaction); |
1500 | 1545 | ||
1501 | if (flush_on_commit || snap_pending) { | 1546 | ret = btrfs_flush_all_pending_stuffs(trans, root); |
1502 | btrfs_start_delalloc_inodes(root, 1); | ||
1503 | btrfs_wait_ordered_extents(root, 1); | ||
1504 | } | ||
1505 | |||
1506 | ret = btrfs_run_delayed_items(trans, root); | ||
1507 | if (ret) | 1547 | if (ret) |
1508 | goto cleanup_transaction; | 1548 | goto cleanup_transaction; |
1509 | 1549 | ||
1510 | /* | ||
1511 | * running the delayed items may have added new refs. account | ||
1512 | * them now so that they hinder processing of more delayed refs | ||
1513 | * as little as possible. | ||
1514 | */ | ||
1515 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1516 | |||
1517 | /* | ||
1518 | * rename don't use btrfs_join_transaction, so, once we | ||
1519 | * set the transaction to blocked above, we aren't going | ||
1520 | * to get any new ordered operations. We can safely run | ||
1521 | * it here and no for sure that nothing new will be added | ||
1522 | * to the list | ||
1523 | */ | ||
1524 | btrfs_run_ordered_operations(root, 1); | ||
1525 | |||
1526 | prepare_to_wait(&cur_trans->writer_wait, &wait, | 1550 | prepare_to_wait(&cur_trans->writer_wait, &wait, |
1527 | TASK_UNINTERRUPTIBLE); | 1551 | TASK_UNINTERRUPTIBLE); |
1528 | 1552 | ||
@@ -1535,6 +1559,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1535 | } while (atomic_read(&cur_trans->num_writers) > 1 || | 1559 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
1536 | (should_grow && cur_trans->num_joined != joined)); | 1560 | (should_grow && cur_trans->num_joined != joined)); |
1537 | 1561 | ||
1562 | ret = btrfs_flush_all_pending_stuffs(trans, root); | ||
1563 | if (ret) | ||
1564 | goto cleanup_transaction; | ||
1565 | |||
1538 | /* | 1566 | /* |
1539 | * Ok now we need to make sure to block out any other joins while we | 1567 | * Ok now we need to make sure to block out any other joins while we |
1540 | * commit the transaction. We could have started a join before setting | 1568 | * commit the transaction. We could have started a join before setting |