diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2012-09-06 06:04:27 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-10-01 15:19:12 -0400 |
commit | 2ecb79239bcd04c9d410f4cdce16adb6840b19da (patch) | |
tree | 9a2194dde73a1a822fa011c35745c3aafa316f86 /fs/btrfs/tree-log.c | |
parent | 48c03c4bcfd7a1fcb1e05e9b1db1188cdbecf49a (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.c | 12 |
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 | ||