diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d91b0de7c502..4edfdc2acc5f 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -137,11 +137,20 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
137 | 137 | ||
138 | mutex_lock(&root->log_mutex); | 138 | mutex_lock(&root->log_mutex); |
139 | if (root->log_root) { | 139 | if (root->log_root) { |
140 | if (!root->log_start_pid) { | ||
141 | root->log_start_pid = current->pid; | ||
142 | root->log_multiple_pids = false; | ||
143 | } else if (root->log_start_pid != current->pid) { | ||
144 | root->log_multiple_pids = true; | ||
145 | } | ||
146 | |||
140 | root->log_batch++; | 147 | root->log_batch++; |
141 | atomic_inc(&root->log_writers); | 148 | atomic_inc(&root->log_writers); |
142 | mutex_unlock(&root->log_mutex); | 149 | mutex_unlock(&root->log_mutex); |
143 | return 0; | 150 | return 0; |
144 | } | 151 | } |
152 | root->log_multiple_pids = false; | ||
153 | root->log_start_pid = current->pid; | ||
145 | mutex_lock(&root->fs_info->tree_log_mutex); | 154 | mutex_lock(&root->fs_info->tree_log_mutex); |
146 | if (!root->fs_info->log_root_tree) { | 155 | if (!root->fs_info->log_root_tree) { |
147 | ret = btrfs_init_log_root_tree(trans, root->fs_info); | 156 | ret = btrfs_init_log_root_tree(trans, root->fs_info); |
@@ -263,8 +272,8 @@ static int process_one_buffer(struct btrfs_root *log, | |||
263 | struct walk_control *wc, u64 gen) | 272 | struct walk_control *wc, u64 gen) |
264 | { | 273 | { |
265 | if (wc->pin) | 274 | if (wc->pin) |
266 | btrfs_update_pinned_extents(log->fs_info->extent_root, | 275 | btrfs_pin_extent(log->fs_info->extent_root, |
267 | eb->start, eb->len, 1); | 276 | eb->start, eb->len, 0); |
268 | 277 | ||
269 | if (btrfs_buffer_uptodate(eb, gen)) { | 278 | if (btrfs_buffer_uptodate(eb, gen)) { |
270 | if (wc->write) | 279 | if (wc->write) |
@@ -534,7 +543,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
534 | saved_nbytes = inode_get_bytes(inode); | 543 | saved_nbytes = inode_get_bytes(inode); |
535 | /* drop any overlapping extents */ | 544 | /* drop any overlapping extents */ |
536 | ret = btrfs_drop_extents(trans, root, inode, | 545 | ret = btrfs_drop_extents(trans, root, inode, |
537 | start, extent_end, extent_end, start, &alloc_hint); | 546 | start, extent_end, extent_end, start, &alloc_hint, 1); |
538 | BUG_ON(ret); | 547 | BUG_ON(ret); |
539 | 548 | ||
540 | if (found_type == BTRFS_FILE_EXTENT_REG || | 549 | if (found_type == BTRFS_FILE_EXTENT_REG || |
@@ -1985,7 +1994,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
1985 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) | 1994 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) |
1986 | wait_log_commit(trans, root, root->log_transid - 1); | 1995 | wait_log_commit(trans, root, root->log_transid - 1); |
1987 | 1996 | ||
1988 | while (1) { | 1997 | while (root->log_multiple_pids) { |
1989 | unsigned long batch = root->log_batch; | 1998 | unsigned long batch = root->log_batch; |
1990 | mutex_unlock(&root->log_mutex); | 1999 | mutex_unlock(&root->log_mutex); |
1991 | schedule_timeout_uninterruptible(1); | 2000 | schedule_timeout_uninterruptible(1); |
@@ -2011,6 +2020,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2011 | root->log_batch = 0; | 2020 | root->log_batch = 0; |
2012 | root->log_transid++; | 2021 | root->log_transid++; |
2013 | log->log_transid = root->log_transid; | 2022 | log->log_transid = root->log_transid; |
2023 | root->log_start_pid = 0; | ||
2014 | smp_mb(); | 2024 | smp_mb(); |
2015 | /* | 2025 | /* |
2016 | * log tree has been flushed to disk, new modifications of | 2026 | * log tree has been flushed to disk, new modifications of |
@@ -2605,7 +2615,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
2605 | extent); | 2615 | extent); |
2606 | cs = btrfs_file_extent_offset(src, extent); | 2616 | cs = btrfs_file_extent_offset(src, extent); |
2607 | cl = btrfs_file_extent_num_bytes(src, | 2617 | cl = btrfs_file_extent_num_bytes(src, |
2608 | extent);; | 2618 | extent); |
2609 | if (btrfs_file_extent_compression(src, | 2619 | if (btrfs_file_extent_compression(src, |
2610 | extent)) { | 2620 | extent)) { |
2611 | cs = 0; | 2621 | cs = 0; |
@@ -2841,7 +2851,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
2841 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) | 2851 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) |
2842 | break; | 2852 | break; |
2843 | 2853 | ||
2844 | if (parent == sb->s_root) | 2854 | if (IS_ROOT(parent)) |
2845 | break; | 2855 | break; |
2846 | 2856 | ||
2847 | parent = parent->d_parent; | 2857 | parent = parent->d_parent; |
@@ -2880,6 +2890,12 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
2880 | goto end_no_trans; | 2890 | goto end_no_trans; |
2881 | } | 2891 | } |
2882 | 2892 | ||
2893 | if (root != BTRFS_I(inode)->root || | ||
2894 | btrfs_root_refs(&root->root_item) == 0) { | ||
2895 | ret = 1; | ||
2896 | goto end_no_trans; | ||
2897 | } | ||
2898 | |||
2883 | ret = check_parent_dirs_for_sync(trans, inode, parent, | 2899 | ret = check_parent_dirs_for_sync(trans, inode, parent, |
2884 | sb, last_committed); | 2900 | sb, last_committed); |
2885 | if (ret) | 2901 | if (ret) |
@@ -2907,12 +2923,15 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
2907 | break; | 2923 | break; |
2908 | 2924 | ||
2909 | inode = parent->d_inode; | 2925 | inode = parent->d_inode; |
2926 | if (root != BTRFS_I(inode)->root) | ||
2927 | break; | ||
2928 | |||
2910 | if (BTRFS_I(inode)->generation > | 2929 | if (BTRFS_I(inode)->generation > |
2911 | root->fs_info->last_trans_committed) { | 2930 | root->fs_info->last_trans_committed) { |
2912 | ret = btrfs_log_inode(trans, root, inode, inode_only); | 2931 | ret = btrfs_log_inode(trans, root, inode, inode_only); |
2913 | BUG_ON(ret); | 2932 | BUG_ON(ret); |
2914 | } | 2933 | } |
2915 | if (parent == sb->s_root) | 2934 | if (IS_ROOT(parent)) |
2916 | break; | 2935 | break; |
2917 | 2936 | ||
2918 | parent = parent->d_parent; | 2937 | parent = parent->d_parent; |
@@ -2951,7 +2970,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) | |||
2951 | struct btrfs_key tmp_key; | 2970 | struct btrfs_key tmp_key; |
2952 | struct btrfs_root *log; | 2971 | struct btrfs_root *log; |
2953 | struct btrfs_fs_info *fs_info = log_root_tree->fs_info; | 2972 | struct btrfs_fs_info *fs_info = log_root_tree->fs_info; |
2954 | u64 highest_inode; | ||
2955 | struct walk_control wc = { | 2973 | struct walk_control wc = { |
2956 | .process_func = process_one_buffer, | 2974 | .process_func = process_one_buffer, |
2957 | .stage = 0, | 2975 | .stage = 0, |
@@ -3010,11 +3028,6 @@ again: | |||
3010 | path); | 3028 | path); |
3011 | BUG_ON(ret); | 3029 | BUG_ON(ret); |
3012 | } | 3030 | } |
3013 | ret = btrfs_find_highest_inode(wc.replay_dest, &highest_inode); | ||
3014 | if (ret == 0) { | ||
3015 | wc.replay_dest->highest_inode = highest_inode; | ||
3016 | wc.replay_dest->last_inode_alloc = highest_inode; | ||
3017 | } | ||
3018 | 3031 | ||
3019 | key.offset = found_key.offset - 1; | 3032 | key.offset = found_key.offset - 1; |
3020 | wc.replay_dest->log_root = NULL; | 3033 | wc.replay_dest->log_root = NULL; |