aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-09-06 06:04:27 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:19:12 -0400
commit2ecb79239bcd04c9d410f4cdce16adb6840b19da (patch)
tree9a2194dde73a1a822fa011c35745c3aafa316f86 /fs/btrfs/tree-log.c
parent48c03c4bcfd7a1fcb1e05e9b1db1188cdbecf49a (diff)
Btrfs: fix unprotected ->log_batch
We forget to protect ->log_batch when syncing a file, this patch fix this problem by atomic operation. And ->log_batch is used to check if there are parallel sync operations or not, so it is unnecessary to reset it to 0 after the sync operation of the current log tree complete. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f9b0fc911661..038a5229404a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -147,7 +147,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
147 root->log_multiple_pids = true; 147 root->log_multiple_pids = true;
148 } 148 }
149 149
150 root->log_batch++; 150 atomic_inc(&root->log_batch);
151 atomic_inc(&root->log_writers); 151 atomic_inc(&root->log_writers);
152 mutex_unlock(&root->log_mutex); 152 mutex_unlock(&root->log_mutex);
153 return 0; 153 return 0;
@@ -166,7 +166,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
166 err = ret; 166 err = ret;
167 } 167 }
168 mutex_unlock(&root->fs_info->tree_log_mutex); 168 mutex_unlock(&root->fs_info->tree_log_mutex);
169 root->log_batch++; 169 atomic_inc(&root->log_batch);
170 atomic_inc(&root->log_writers); 170 atomic_inc(&root->log_writers);
171 mutex_unlock(&root->log_mutex); 171 mutex_unlock(&root->log_mutex);
172 return err; 172 return err;
@@ -2036,7 +2036,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2036 if (atomic_read(&root->log_commit[(index1 + 1) % 2])) 2036 if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
2037 wait_log_commit(trans, root, root->log_transid - 1); 2037 wait_log_commit(trans, root, root->log_transid - 1);
2038 while (1) { 2038 while (1) {
2039 unsigned long batch = root->log_batch; 2039 int batch = atomic_read(&root->log_batch);
2040 /* when we're on an ssd, just kick the log commit out */ 2040 /* when we're on an ssd, just kick the log commit out */
2041 if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) { 2041 if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) {
2042 mutex_unlock(&root->log_mutex); 2042 mutex_unlock(&root->log_mutex);
@@ -2044,7 +2044,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2044 mutex_lock(&root->log_mutex); 2044 mutex_lock(&root->log_mutex);
2045 } 2045 }
2046 wait_for_writer(trans, root); 2046 wait_for_writer(trans, root);
2047 if (batch == root->log_batch) 2047 if (batch == atomic_read(&root->log_batch))
2048 break; 2048 break;
2049 } 2049 }
2050 2050
@@ -2073,7 +2073,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2073 2073
2074 btrfs_set_root_node(&log->root_item, log->node); 2074 btrfs_set_root_node(&log->root_item, log->node);
2075 2075
2076 root->log_batch = 0;
2077 root->log_transid++; 2076 root->log_transid++;
2078 log->log_transid = root->log_transid; 2077 log->log_transid = root->log_transid;
2079 root->log_start_pid = 0; 2078 root->log_start_pid = 0;
@@ -2086,7 +2085,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2086 mutex_unlock(&root->log_mutex); 2085 mutex_unlock(&root->log_mutex);
2087 2086
2088 mutex_lock(&log_root_tree->log_mutex); 2087 mutex_lock(&log_root_tree->log_mutex);
2089 log_root_tree->log_batch++; 2088 atomic_inc(&log_root_tree->log_batch);
2090 atomic_inc(&log_root_tree->log_writers); 2089 atomic_inc(&log_root_tree->log_writers);
2091 mutex_unlock(&log_root_tree->log_mutex); 2090 mutex_unlock(&log_root_tree->log_mutex);
2092 2091
@@ -2156,7 +2155,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2156 btrfs_set_super_log_root_level(root->fs_info->super_for_commit, 2155 btrfs_set_super_log_root_level(root->fs_info->super_for_commit,
2157 btrfs_header_level(log_root_tree->node)); 2156 btrfs_header_level(log_root_tree->node));
2158 2157
2159 log_root_tree->log_batch = 0;
2160 log_root_tree->log_transid++; 2158 log_root_tree->log_transid++;
2161 smp_mb(); 2159 smp_mb();
2162 2160