aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index ce48eb59d615..c571734d5e5a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -32,10 +32,8 @@
32 32
33static noinline void put_transaction(struct btrfs_transaction *transaction) 33static noinline void put_transaction(struct btrfs_transaction *transaction)
34{ 34{
35 WARN_ON(transaction->use_count == 0); 35 WARN_ON(atomic_read(&transaction->use_count) == 0);
36 transaction->use_count--; 36 if (atomic_dec_and_test(&transaction->use_count)) {
37 if (transaction->use_count == 0) {
38 list_del_init(&transaction->list);
39 memset(transaction, 0, sizeof(*transaction)); 37 memset(transaction, 0, sizeof(*transaction));
40 kmem_cache_free(btrfs_transaction_cachep, transaction); 38 kmem_cache_free(btrfs_transaction_cachep, transaction);
41 } 39 }
@@ -60,14 +58,14 @@ static noinline int join_transaction(struct btrfs_root *root)
60 if (!cur_trans) 58 if (!cur_trans)
61 return -ENOMEM; 59 return -ENOMEM;
62 root->fs_info->generation++; 60 root->fs_info->generation++;
63 cur_trans->num_writers = 1; 61 atomic_set(&cur_trans->num_writers, 1);
64 cur_trans->num_joined = 0; 62 cur_trans->num_joined = 0;
65 cur_trans->transid = root->fs_info->generation; 63 cur_trans->transid = root->fs_info->generation;
66 init_waitqueue_head(&cur_trans->writer_wait); 64 init_waitqueue_head(&cur_trans->writer_wait);
67 init_waitqueue_head(&cur_trans->commit_wait); 65 init_waitqueue_head(&cur_trans->commit_wait);
68 cur_trans->in_commit = 0; 66 cur_trans->in_commit = 0;
69 cur_trans->blocked = 0; 67 cur_trans->blocked = 0;
70 cur_trans->use_count = 1; 68 atomic_set(&cur_trans->use_count, 1);
71 cur_trans->commit_done = 0; 69 cur_trans->commit_done = 0;
72 cur_trans->start_time = get_seconds(); 70 cur_trans->start_time = get_seconds();
73 71
@@ -88,7 +86,7 @@ static noinline int join_transaction(struct btrfs_root *root)
88 root->fs_info->running_transaction = cur_trans; 86 root->fs_info->running_transaction = cur_trans;
89 spin_unlock(&root->fs_info->new_trans_lock); 87 spin_unlock(&root->fs_info->new_trans_lock);
90 } else { 88 } else {
91 cur_trans->num_writers++; 89 atomic_inc(&cur_trans->num_writers);
92 cur_trans->num_joined++; 90 cur_trans->num_joined++;
93 } 91 }
94 92
@@ -145,7 +143,7 @@ static void wait_current_trans(struct btrfs_root *root)
145 cur_trans = root->fs_info->running_transaction; 143 cur_trans = root->fs_info->running_transaction;
146 if (cur_trans && cur_trans->blocked) { 144 if (cur_trans && cur_trans->blocked) {
147 DEFINE_WAIT(wait); 145 DEFINE_WAIT(wait);
148 cur_trans->use_count++; 146 atomic_inc(&cur_trans->use_count);
149 while (1) { 147 while (1) {
150 prepare_to_wait(&root->fs_info->transaction_wait, &wait, 148 prepare_to_wait(&root->fs_info->transaction_wait, &wait,
151 TASK_UNINTERRUPTIBLE); 149 TASK_UNINTERRUPTIBLE);
@@ -181,6 +179,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
181{ 179{
182 struct btrfs_trans_handle *h; 180 struct btrfs_trans_handle *h;
183 struct btrfs_transaction *cur_trans; 181 struct btrfs_transaction *cur_trans;
182 int retries = 0;
184 int ret; 183 int ret;
185 184
186 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) 185 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
@@ -197,13 +196,14 @@ again:
197 196
198 ret = join_transaction(root); 197 ret = join_transaction(root);
199 if (ret < 0) { 198 if (ret < 0) {
199 kmem_cache_free(btrfs_trans_handle_cachep, h);
200 if (type != TRANS_JOIN_NOLOCK) 200 if (type != TRANS_JOIN_NOLOCK)
201 mutex_unlock(&root->fs_info->trans_mutex); 201 mutex_unlock(&root->fs_info->trans_mutex);
202 return ERR_PTR(ret); 202 return ERR_PTR(ret);
203 } 203 }
204 204
205 cur_trans = root->fs_info->running_transaction; 205 cur_trans = root->fs_info->running_transaction;
206 cur_trans->use_count++; 206 atomic_inc(&cur_trans->use_count);
207 if (type != TRANS_JOIN_NOLOCK) 207 if (type != TRANS_JOIN_NOLOCK)
208 mutex_unlock(&root->fs_info->trans_mutex); 208 mutex_unlock(&root->fs_info->trans_mutex);
209 209
@@ -223,10 +223,18 @@ again:
223 223
224 if (num_items > 0) { 224 if (num_items > 0) {
225 ret = btrfs_trans_reserve_metadata(h, root, num_items); 225 ret = btrfs_trans_reserve_metadata(h, root, num_items);
226 if (ret == -EAGAIN) { 226 if (ret == -EAGAIN && !retries) {
227 retries++;
227 btrfs_commit_transaction(h, root); 228 btrfs_commit_transaction(h, root);
228 goto again; 229 goto again;
230 } else if (ret == -EAGAIN) {
231 /*
232 * We have already retried and got EAGAIN, so really we
233 * don't have space, so set ret to -ENOSPC.
234 */
235 ret = -ENOSPC;
229 } 236 }
237
230 if (ret < 0) { 238 if (ret < 0) {
231 btrfs_end_transaction(h, root); 239 btrfs_end_transaction(h, root);
232 return ERR_PTR(ret); 240 return ERR_PTR(ret);
@@ -326,7 +334,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
326 goto out_unlock; /* nothing committing|committed */ 334 goto out_unlock; /* nothing committing|committed */
327 } 335 }
328 336
329 cur_trans->use_count++; 337 atomic_inc(&cur_trans->use_count);
330 mutex_unlock(&root->fs_info->trans_mutex); 338 mutex_unlock(&root->fs_info->trans_mutex);
331 339
332 wait_for_commit(root, cur_trans); 340 wait_for_commit(root, cur_trans);
@@ -456,18 +464,14 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
456 wake_up_process(info->transaction_kthread); 464 wake_up_process(info->transaction_kthread);
457 } 465 }
458 466
459 if (lock)
460 mutex_lock(&info->trans_mutex);
461 WARN_ON(cur_trans != info->running_transaction); 467 WARN_ON(cur_trans != info->running_transaction);
462 WARN_ON(cur_trans->num_writers < 1); 468 WARN_ON(atomic_read(&cur_trans->num_writers) < 1);
463 cur_trans->num_writers--; 469 atomic_dec(&cur_trans->num_writers);
464 470
465 smp_mb(); 471 smp_mb();
466 if (waitqueue_active(&cur_trans->writer_wait)) 472 if (waitqueue_active(&cur_trans->writer_wait))
467 wake_up(&cur_trans->writer_wait); 473 wake_up(&cur_trans->writer_wait);
468 put_transaction(cur_trans); 474 put_transaction(cur_trans);
469 if (lock)
470 mutex_unlock(&info->trans_mutex);
471 475
472 if (current->journal_info == trans) 476 if (current->journal_info == trans)
473 current->journal_info = NULL; 477 current->journal_info = NULL;
@@ -975,6 +979,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
975 record_root_in_trans(trans, root); 979 record_root_in_trans(trans, root);
976 btrfs_set_root_last_snapshot(&root->root_item, trans->transid); 980 btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
977 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); 981 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
982 btrfs_check_and_init_root_item(new_root_item);
978 983
979 root_flags = btrfs_root_flags(new_root_item); 984 root_flags = btrfs_root_flags(new_root_item);
980 if (pending->readonly) 985 if (pending->readonly)
@@ -1176,7 +1181,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
1176 /* take transaction reference */ 1181 /* take transaction reference */
1177 mutex_lock(&root->fs_info->trans_mutex); 1182 mutex_lock(&root->fs_info->trans_mutex);
1178 cur_trans = trans->transaction; 1183 cur_trans = trans->transaction;
1179 cur_trans->use_count++; 1184 atomic_inc(&cur_trans->use_count);
1180 mutex_unlock(&root->fs_info->trans_mutex); 1185 mutex_unlock(&root->fs_info->trans_mutex);
1181 1186
1182 btrfs_end_transaction(trans, root); 1187 btrfs_end_transaction(trans, root);
@@ -1235,7 +1240,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1235 1240
1236 mutex_lock(&root->fs_info->trans_mutex); 1241 mutex_lock(&root->fs_info->trans_mutex);
1237 if (cur_trans->in_commit) { 1242 if (cur_trans->in_commit) {
1238 cur_trans->use_count++; 1243 atomic_inc(&cur_trans->use_count);
1239 mutex_unlock(&root->fs_info->trans_mutex); 1244 mutex_unlock(&root->fs_info->trans_mutex);
1240 btrfs_end_transaction(trans, root); 1245 btrfs_end_transaction(trans, root);
1241 1246
@@ -1257,7 +1262,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1257 prev_trans = list_entry(cur_trans->list.prev, 1262 prev_trans = list_entry(cur_trans->list.prev,
1258 struct btrfs_transaction, list); 1263 struct btrfs_transaction, list);
1259 if (!prev_trans->commit_done) { 1264 if (!prev_trans->commit_done) {
1260 prev_trans->use_count++; 1265 atomic_inc(&prev_trans->use_count);
1261 mutex_unlock(&root->fs_info->trans_mutex); 1266 mutex_unlock(&root->fs_info->trans_mutex);
1262 1267
1263 wait_for_commit(root, prev_trans); 1268 wait_for_commit(root, prev_trans);
@@ -1298,14 +1303,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1298 TASK_UNINTERRUPTIBLE); 1303 TASK_UNINTERRUPTIBLE);
1299 1304
1300 smp_mb(); 1305 smp_mb();
1301 if (cur_trans->num_writers > 1) 1306 if (atomic_read(&cur_trans->num_writers) > 1)
1302 schedule_timeout(MAX_SCHEDULE_TIMEOUT); 1307 schedule_timeout(MAX_SCHEDULE_TIMEOUT);
1303 else if (should_grow) 1308 else if (should_grow)
1304 schedule_timeout(1); 1309 schedule_timeout(1);
1305 1310
1306 mutex_lock(&root->fs_info->trans_mutex); 1311 mutex_lock(&root->fs_info->trans_mutex);
1307 finish_wait(&cur_trans->writer_wait, &wait); 1312 finish_wait(&cur_trans->writer_wait, &wait);
1308 } while (cur_trans->num_writers > 1 || 1313 } while (atomic_read(&cur_trans->num_writers) > 1 ||
1309 (should_grow && cur_trans->num_joined != joined)); 1314 (should_grow && cur_trans->num_joined != joined));
1310 1315
1311 ret = create_pending_snapshots(trans, root->fs_info); 1316 ret = create_pending_snapshots(trans, root->fs_info);
@@ -1392,6 +1397,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1392 1397
1393 wake_up(&cur_trans->commit_wait); 1398 wake_up(&cur_trans->commit_wait);
1394 1399
1400 list_del_init(&cur_trans->list);
1395 put_transaction(cur_trans); 1401 put_transaction(cur_trans);
1396 put_transaction(cur_trans); 1402 put_transaction(cur_trans);
1397 1403