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.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 66e4c66cc63..e7144c48ed7 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -163,6 +163,7 @@ enum btrfs_trans_type {
163 TRANS_START, 163 TRANS_START,
164 TRANS_JOIN, 164 TRANS_JOIN,
165 TRANS_USERSPACE, 165 TRANS_USERSPACE,
166 TRANS_JOIN_NOLOCK,
166}; 167};
167 168
168static int may_wait_transaction(struct btrfs_root *root, int type) 169static int may_wait_transaction(struct btrfs_root *root, int type)
@@ -186,7 +187,8 @@ again:
186 if (!h) 187 if (!h)
187 return ERR_PTR(-ENOMEM); 188 return ERR_PTR(-ENOMEM);
188 189
189 mutex_lock(&root->fs_info->trans_mutex); 190 if (type != TRANS_JOIN_NOLOCK)
191 mutex_lock(&root->fs_info->trans_mutex);
190 if (may_wait_transaction(root, type)) 192 if (may_wait_transaction(root, type))
191 wait_current_trans(root); 193 wait_current_trans(root);
192 194
@@ -195,7 +197,8 @@ again:
195 197
196 cur_trans = root->fs_info->running_transaction; 198 cur_trans = root->fs_info->running_transaction;
197 cur_trans->use_count++; 199 cur_trans->use_count++;
198 mutex_unlock(&root->fs_info->trans_mutex); 200 if (type != TRANS_JOIN_NOLOCK)
201 mutex_unlock(&root->fs_info->trans_mutex);
199 202
200 h->transid = cur_trans->transid; 203 h->transid = cur_trans->transid;
201 h->transaction = cur_trans; 204 h->transaction = cur_trans;
@@ -224,9 +227,11 @@ again:
224 } 227 }
225 } 228 }
226 229
227 mutex_lock(&root->fs_info->trans_mutex); 230 if (type != TRANS_JOIN_NOLOCK)
231 mutex_lock(&root->fs_info->trans_mutex);
228 record_root_in_trans(h, root); 232 record_root_in_trans(h, root);
229 mutex_unlock(&root->fs_info->trans_mutex); 233 if (type != TRANS_JOIN_NOLOCK)
234 mutex_unlock(&root->fs_info->trans_mutex);
230 235
231 if (!current->journal_info && type != TRANS_USERSPACE) 236 if (!current->journal_info && type != TRANS_USERSPACE)
232 current->journal_info = h; 237 current->journal_info = h;
@@ -244,6 +249,12 @@ struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
244 return start_transaction(root, 0, TRANS_JOIN); 249 return start_transaction(root, 0, TRANS_JOIN);
245} 250}
246 251
252struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
253 int num_blocks)
254{
255 return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
256}
257
247struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, 258struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
248 int num_blocks) 259 int num_blocks)
249{ 260{
@@ -348,7 +359,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
348} 359}
349 360
350static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, 361static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
351 struct btrfs_root *root, int throttle) 362 struct btrfs_root *root, int throttle, int lock)
352{ 363{
353 struct btrfs_transaction *cur_trans = trans->transaction; 364 struct btrfs_transaction *cur_trans = trans->transaction;
354 struct btrfs_fs_info *info = root->fs_info; 365 struct btrfs_fs_info *info = root->fs_info;
@@ -376,18 +387,19 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
376 387
377 btrfs_trans_release_metadata(trans, root); 388 btrfs_trans_release_metadata(trans, root);
378 389
379 if (!root->fs_info->open_ioctl_trans && 390 if (lock && !root->fs_info->open_ioctl_trans &&
380 should_end_transaction(trans, root)) 391 should_end_transaction(trans, root))
381 trans->transaction->blocked = 1; 392 trans->transaction->blocked = 1;
382 393
383 if (cur_trans->blocked && !cur_trans->in_commit) { 394 if (lock && cur_trans->blocked && !cur_trans->in_commit) {
384 if (throttle) 395 if (throttle)
385 return btrfs_commit_transaction(trans, root); 396 return btrfs_commit_transaction(trans, root);
386 else 397 else
387 wake_up_process(info->transaction_kthread); 398 wake_up_process(info->transaction_kthread);
388 } 399 }
389 400
390 mutex_lock(&info->trans_mutex); 401 if (lock)
402 mutex_lock(&info->trans_mutex);
391 WARN_ON(cur_trans != info->running_transaction); 403 WARN_ON(cur_trans != info->running_transaction);
392 WARN_ON(cur_trans->num_writers < 1); 404 WARN_ON(cur_trans->num_writers < 1);
393 cur_trans->num_writers--; 405 cur_trans->num_writers--;
@@ -395,7 +407,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
395 if (waitqueue_active(&cur_trans->writer_wait)) 407 if (waitqueue_active(&cur_trans->writer_wait))
396 wake_up(&cur_trans->writer_wait); 408 wake_up(&cur_trans->writer_wait);
397 put_transaction(cur_trans); 409 put_transaction(cur_trans);
398 mutex_unlock(&info->trans_mutex); 410 if (lock)
411 mutex_unlock(&info->trans_mutex);
399 412
400 if (current->journal_info == trans) 413 if (current->journal_info == trans)
401 current->journal_info = NULL; 414 current->journal_info = NULL;
@@ -411,13 +424,19 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
411int btrfs_end_transaction(struct btrfs_trans_handle *trans, 424int btrfs_end_transaction(struct btrfs_trans_handle *trans,
412 struct btrfs_root *root) 425 struct btrfs_root *root)
413{ 426{
414 return __btrfs_end_transaction(trans, root, 0); 427 return __btrfs_end_transaction(trans, root, 0, 1);
415} 428}
416 429
417int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, 430int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
418 struct btrfs_root *root) 431 struct btrfs_root *root)
419{ 432{
420 return __btrfs_end_transaction(trans, root, 1); 433 return __btrfs_end_transaction(trans, root, 1, 1);
434}
435
436int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
437 struct btrfs_root *root)
438{
439 return __btrfs_end_transaction(trans, root, 0, 0);
421} 440}
422 441
423/* 442/*
@@ -966,6 +985,8 @@ static void update_super_roots(struct btrfs_root *root)
966 super->root = root_item->bytenr; 985 super->root = root_item->bytenr;
967 super->generation = root_item->generation; 986 super->generation = root_item->generation;
968 super->root_level = root_item->level; 987 super->root_level = root_item->level;
988 if (super->cache_generation != 0 || btrfs_test_opt(root, SPACE_CACHE))
989 super->cache_generation = root_item->generation;
969} 990}
970 991
971int btrfs_transaction_in_commit(struct btrfs_fs_info *info) 992int btrfs_transaction_in_commit(struct btrfs_fs_info *info)