diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
| -rw-r--r-- | fs/btrfs/tree-log.c | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index e2f45fc02610..9e1f2cd5e67a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -20,13 +20,11 @@ | |||
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/list_sort.h> | 22 | #include <linux/list_sort.h> |
| 23 | #include "ctree.h" | 23 | #include "tree-log.h" |
| 24 | #include "transaction.h" | ||
| 25 | #include "disk-io.h" | 24 | #include "disk-io.h" |
| 26 | #include "locking.h" | 25 | #include "locking.h" |
| 27 | #include "print-tree.h" | 26 | #include "print-tree.h" |
| 28 | #include "backref.h" | 27 | #include "backref.h" |
| 29 | #include "tree-log.h" | ||
| 30 | #include "hash.h" | 28 | #include "hash.h" |
| 31 | 29 | ||
| 32 | /* magic values for the inode_only field in btrfs_log_inode: | 30 | /* magic values for the inode_only field in btrfs_log_inode: |
| @@ -144,17 +142,15 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 144 | 142 | ||
| 145 | mutex_lock(&root->log_mutex); | 143 | mutex_lock(&root->log_mutex); |
| 146 | if (root->log_root) { | 144 | if (root->log_root) { |
| 147 | if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) == | 145 | if (btrfs_need_log_full_commit(root->fs_info, trans)) { |
| 148 | trans->transid) { | ||
| 149 | ret = -EAGAIN; | 146 | ret = -EAGAIN; |
| 150 | goto out; | 147 | goto out; |
| 151 | } | 148 | } |
| 152 | |||
| 153 | if (!root->log_start_pid) { | 149 | if (!root->log_start_pid) { |
| 154 | root->log_start_pid = current->pid; | 150 | root->log_start_pid = current->pid; |
| 155 | root->log_multiple_pids = false; | 151 | clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); |
| 156 | } else if (root->log_start_pid != current->pid) { | 152 | } else if (root->log_start_pid != current->pid) { |
| 157 | root->log_multiple_pids = true; | 153 | set_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); |
| 158 | } | 154 | } |
| 159 | 155 | ||
| 160 | atomic_inc(&root->log_batch); | 156 | atomic_inc(&root->log_batch); |
| @@ -181,7 +177,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 181 | if (ret) | 177 | if (ret) |
| 182 | goto out; | 178 | goto out; |
| 183 | } | 179 | } |
| 184 | root->log_multiple_pids = false; | 180 | clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state); |
| 185 | root->log_start_pid = current->pid; | 181 | root->log_start_pid = current->pid; |
| 186 | atomic_inc(&root->log_batch); | 182 | atomic_inc(&root->log_batch); |
| 187 | atomic_inc(&root->log_writers); | 183 | atomic_inc(&root->log_writers); |
| @@ -2500,7 +2496,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2500 | while (1) { | 2496 | while (1) { |
| 2501 | int batch = atomic_read(&root->log_batch); | 2497 | int batch = atomic_read(&root->log_batch); |
| 2502 | /* when we're on an ssd, just kick the log commit out */ | 2498 | /* when we're on an ssd, just kick the log commit out */ |
| 2503 | if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) { | 2499 | if (!btrfs_test_opt(root, SSD) && |
| 2500 | test_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state)) { | ||
| 2504 | mutex_unlock(&root->log_mutex); | 2501 | mutex_unlock(&root->log_mutex); |
| 2505 | schedule_timeout_uninterruptible(1); | 2502 | schedule_timeout_uninterruptible(1); |
| 2506 | mutex_lock(&root->log_mutex); | 2503 | mutex_lock(&root->log_mutex); |
| @@ -2511,8 +2508,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2511 | } | 2508 | } |
| 2512 | 2509 | ||
| 2513 | /* bail out if we need to do a full commit */ | 2510 | /* bail out if we need to do a full commit */ |
| 2514 | if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) == | 2511 | if (btrfs_need_log_full_commit(root->fs_info, trans)) { |
| 2515 | trans->transid) { | ||
| 2516 | ret = -EAGAIN; | 2512 | ret = -EAGAIN; |
| 2517 | btrfs_free_logged_extents(log, log_transid); | 2513 | btrfs_free_logged_extents(log, log_transid); |
| 2518 | mutex_unlock(&root->log_mutex); | 2514 | mutex_unlock(&root->log_mutex); |
| @@ -2533,8 +2529,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2533 | blk_finish_plug(&plug); | 2529 | blk_finish_plug(&plug); |
| 2534 | btrfs_abort_transaction(trans, root, ret); | 2530 | btrfs_abort_transaction(trans, root, ret); |
| 2535 | btrfs_free_logged_extents(log, log_transid); | 2531 | btrfs_free_logged_extents(log, log_transid); |
| 2536 | ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) = | 2532 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2537 | trans->transid; | ||
| 2538 | mutex_unlock(&root->log_mutex); | 2533 | mutex_unlock(&root->log_mutex); |
| 2539 | goto out; | 2534 | goto out; |
| 2540 | } | 2535 | } |
| @@ -2577,8 +2572,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2577 | list_del_init(&root_log_ctx.list); | 2572 | list_del_init(&root_log_ctx.list); |
| 2578 | 2573 | ||
| 2579 | blk_finish_plug(&plug); | 2574 | blk_finish_plug(&plug); |
| 2580 | ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) = | 2575 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2581 | trans->transid; | 2576 | |
| 2582 | if (ret != -ENOSPC) { | 2577 | if (ret != -ENOSPC) { |
| 2583 | btrfs_abort_transaction(trans, root, ret); | 2578 | btrfs_abort_transaction(trans, root, ret); |
| 2584 | mutex_unlock(&log_root_tree->log_mutex); | 2579 | mutex_unlock(&log_root_tree->log_mutex); |
| @@ -2622,8 +2617,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2622 | * now that we've moved on to the tree of log tree roots, | 2617 | * now that we've moved on to the tree of log tree roots, |
| 2623 | * check the full commit flag again | 2618 | * check the full commit flag again |
| 2624 | */ | 2619 | */ |
| 2625 | if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) == | 2620 | if (btrfs_need_log_full_commit(root->fs_info, trans)) { |
| 2626 | trans->transid) { | ||
| 2627 | blk_finish_plug(&plug); | 2621 | blk_finish_plug(&plug); |
| 2628 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); | 2622 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
| 2629 | btrfs_free_logged_extents(log, log_transid); | 2623 | btrfs_free_logged_extents(log, log_transid); |
| @@ -2637,8 +2631,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2637 | EXTENT_DIRTY | EXTENT_NEW); | 2631 | EXTENT_DIRTY | EXTENT_NEW); |
| 2638 | blk_finish_plug(&plug); | 2632 | blk_finish_plug(&plug); |
| 2639 | if (ret) { | 2633 | if (ret) { |
| 2640 | ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) = | 2634 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2641 | trans->transid; | ||
| 2642 | btrfs_abort_transaction(trans, root, ret); | 2635 | btrfs_abort_transaction(trans, root, ret); |
| 2643 | btrfs_free_logged_extents(log, log_transid); | 2636 | btrfs_free_logged_extents(log, log_transid); |
| 2644 | mutex_unlock(&log_root_tree->log_mutex); | 2637 | mutex_unlock(&log_root_tree->log_mutex); |
| @@ -2667,8 +2660,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2667 | */ | 2660 | */ |
| 2668 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); | 2661 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); |
| 2669 | if (ret) { | 2662 | if (ret) { |
| 2670 | ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) = | 2663 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2671 | trans->transid; | ||
| 2672 | btrfs_abort_transaction(trans, root, ret); | 2664 | btrfs_abort_transaction(trans, root, ret); |
| 2673 | goto out_wake_log_root; | 2665 | goto out_wake_log_root; |
| 2674 | } | 2666 | } |
| @@ -2886,7 +2878,7 @@ fail: | |||
| 2886 | out_unlock: | 2878 | out_unlock: |
| 2887 | mutex_unlock(&BTRFS_I(dir)->log_mutex); | 2879 | mutex_unlock(&BTRFS_I(dir)->log_mutex); |
| 2888 | if (ret == -ENOSPC) { | 2880 | if (ret == -ENOSPC) { |
| 2889 | root->fs_info->last_trans_log_full_commit = trans->transid; | 2881 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2890 | ret = 0; | 2882 | ret = 0; |
| 2891 | } else if (ret < 0) | 2883 | } else if (ret < 0) |
| 2892 | btrfs_abort_transaction(trans, root, ret); | 2884 | btrfs_abort_transaction(trans, root, ret); |
| @@ -2919,7 +2911,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, | |||
| 2919 | dirid, &index); | 2911 | dirid, &index); |
| 2920 | mutex_unlock(&BTRFS_I(inode)->log_mutex); | 2912 | mutex_unlock(&BTRFS_I(inode)->log_mutex); |
| 2921 | if (ret == -ENOSPC) { | 2913 | if (ret == -ENOSPC) { |
| 2922 | root->fs_info->last_trans_log_full_commit = trans->transid; | 2914 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 2923 | ret = 0; | 2915 | ret = 0; |
| 2924 | } else if (ret < 0 && ret != -ENOENT) | 2916 | } else if (ret < 0 && ret != -ENOENT) |
| 2925 | btrfs_abort_transaction(trans, root, ret); | 2917 | btrfs_abort_transaction(trans, root, ret); |
| @@ -4130,8 +4122,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 4130 | * make sure any commits to the log are forced | 4122 | * make sure any commits to the log are forced |
| 4131 | * to be full commits | 4123 | * to be full commits |
| 4132 | */ | 4124 | */ |
| 4133 | root->fs_info->last_trans_log_full_commit = | 4125 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 4134 | trans->transid; | ||
| 4135 | ret = 1; | 4126 | ret = 1; |
| 4136 | break; | 4127 | break; |
| 4137 | } | 4128 | } |
| @@ -4177,6 +4168,10 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 4177 | goto end_no_trans; | 4168 | goto end_no_trans; |
| 4178 | } | 4169 | } |
| 4179 | 4170 | ||
| 4171 | /* | ||
| 4172 | * The prev transaction commit doesn't complete, we need do | ||
| 4173 | * full commit by ourselves. | ||
| 4174 | */ | ||
| 4180 | if (root->fs_info->last_trans_log_full_commit > | 4175 | if (root->fs_info->last_trans_log_full_commit > |
| 4181 | root->fs_info->last_trans_committed) { | 4176 | root->fs_info->last_trans_committed) { |
| 4182 | ret = 1; | 4177 | ret = 1; |
| @@ -4246,7 +4241,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 4246 | end_trans: | 4241 | end_trans: |
| 4247 | dput(old_parent); | 4242 | dput(old_parent); |
| 4248 | if (ret < 0) { | 4243 | if (ret < 0) { |
| 4249 | root->fs_info->last_trans_log_full_commit = trans->transid; | 4244 | btrfs_set_log_full_commit(root->fs_info, trans); |
| 4250 | ret = 1; | 4245 | ret = 1; |
| 4251 | } | 4246 | } |
| 4252 | 4247 | ||
