diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 330 |
1 files changed, 179 insertions, 151 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 0544587d74f4..af1931a5960d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -34,12 +34,43 @@ | |||
34 | 34 | ||
35 | #define BTRFS_ROOT_TRANS_TAG 0 | 35 | #define BTRFS_ROOT_TRANS_TAG 0 |
36 | 36 | ||
37 | static unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = { | ||
38 | [TRANS_STATE_RUNNING] = 0U, | ||
39 | [TRANS_STATE_BLOCKED] = (__TRANS_USERSPACE | | ||
40 | __TRANS_START), | ||
41 | [TRANS_STATE_COMMIT_START] = (__TRANS_USERSPACE | | ||
42 | __TRANS_START | | ||
43 | __TRANS_ATTACH), | ||
44 | [TRANS_STATE_COMMIT_DOING] = (__TRANS_USERSPACE | | ||
45 | __TRANS_START | | ||
46 | __TRANS_ATTACH | | ||
47 | __TRANS_JOIN), | ||
48 | [TRANS_STATE_UNBLOCKED] = (__TRANS_USERSPACE | | ||
49 | __TRANS_START | | ||
50 | __TRANS_ATTACH | | ||
51 | __TRANS_JOIN | | ||
52 | __TRANS_JOIN_NOLOCK), | ||
53 | [TRANS_STATE_COMPLETED] = (__TRANS_USERSPACE | | ||
54 | __TRANS_START | | ||
55 | __TRANS_ATTACH | | ||
56 | __TRANS_JOIN | | ||
57 | __TRANS_JOIN_NOLOCK), | ||
58 | }; | ||
59 | |||
37 | static void put_transaction(struct btrfs_transaction *transaction) | 60 | static void put_transaction(struct btrfs_transaction *transaction) |
38 | { | 61 | { |
39 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 62 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
40 | if (atomic_dec_and_test(&transaction->use_count)) { | 63 | if (atomic_dec_and_test(&transaction->use_count)) { |
41 | BUG_ON(!list_empty(&transaction->list)); | 64 | BUG_ON(!list_empty(&transaction->list)); |
42 | WARN_ON(transaction->delayed_refs.root.rb_node); | 65 | WARN_ON(transaction->delayed_refs.root.rb_node); |
66 | while (!list_empty(&transaction->pending_chunks)) { | ||
67 | struct extent_map *em; | ||
68 | |||
69 | em = list_first_entry(&transaction->pending_chunks, | ||
70 | struct extent_map, list); | ||
71 | list_del_init(&em->list); | ||
72 | free_extent_map(em); | ||
73 | } | ||
43 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 74 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
44 | } | 75 | } |
45 | } | 76 | } |
@@ -50,18 +81,35 @@ static noinline void switch_commit_root(struct btrfs_root *root) | |||
50 | root->commit_root = btrfs_root_node(root); | 81 | root->commit_root = btrfs_root_node(root); |
51 | } | 82 | } |
52 | 83 | ||
53 | static inline int can_join_transaction(struct btrfs_transaction *trans, | 84 | static inline void extwriter_counter_inc(struct btrfs_transaction *trans, |
54 | int type) | 85 | unsigned int type) |
86 | { | ||
87 | if (type & TRANS_EXTWRITERS) | ||
88 | atomic_inc(&trans->num_extwriters); | ||
89 | } | ||
90 | |||
91 | static inline void extwriter_counter_dec(struct btrfs_transaction *trans, | ||
92 | unsigned int type) | ||
93 | { | ||
94 | if (type & TRANS_EXTWRITERS) | ||
95 | atomic_dec(&trans->num_extwriters); | ||
96 | } | ||
97 | |||
98 | static inline void extwriter_counter_init(struct btrfs_transaction *trans, | ||
99 | unsigned int type) | ||
100 | { | ||
101 | atomic_set(&trans->num_extwriters, ((type & TRANS_EXTWRITERS) ? 1 : 0)); | ||
102 | } | ||
103 | |||
104 | static inline int extwriter_counter_read(struct btrfs_transaction *trans) | ||
55 | { | 105 | { |
56 | return !(trans->in_commit && | 106 | return atomic_read(&trans->num_extwriters); |
57 | type != TRANS_JOIN && | ||
58 | type != TRANS_JOIN_NOLOCK); | ||
59 | } | 107 | } |
60 | 108 | ||
61 | /* | 109 | /* |
62 | * either allocate a new transaction or hop into the existing one | 110 | * either allocate a new transaction or hop into the existing one |
63 | */ | 111 | */ |
64 | static noinline int join_transaction(struct btrfs_root *root, int type) | 112 | static noinline int join_transaction(struct btrfs_root *root, unsigned int type) |
65 | { | 113 | { |
66 | struct btrfs_transaction *cur_trans; | 114 | struct btrfs_transaction *cur_trans; |
67 | struct btrfs_fs_info *fs_info = root->fs_info; | 115 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -74,32 +122,19 @@ loop: | |||
74 | return -EROFS; | 122 | return -EROFS; |
75 | } | 123 | } |
76 | 124 | ||
77 | if (fs_info->trans_no_join) { | ||
78 | /* | ||
79 | * If we are JOIN_NOLOCK we're already committing a current | ||
80 | * transaction, we just need a handle to deal with something | ||
81 | * when committing the transaction, such as inode cache and | ||
82 | * space cache. It is a special case. | ||
83 | */ | ||
84 | if (type != TRANS_JOIN_NOLOCK) { | ||
85 | spin_unlock(&fs_info->trans_lock); | ||
86 | return -EBUSY; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | cur_trans = fs_info->running_transaction; | 125 | cur_trans = fs_info->running_transaction; |
91 | if (cur_trans) { | 126 | if (cur_trans) { |
92 | if (cur_trans->aborted) { | 127 | if (cur_trans->aborted) { |
93 | spin_unlock(&fs_info->trans_lock); | 128 | spin_unlock(&fs_info->trans_lock); |
94 | return cur_trans->aborted; | 129 | return cur_trans->aborted; |
95 | } | 130 | } |
96 | if (!can_join_transaction(cur_trans, type)) { | 131 | if (btrfs_blocked_trans_types[cur_trans->state] & type) { |
97 | spin_unlock(&fs_info->trans_lock); | 132 | spin_unlock(&fs_info->trans_lock); |
98 | return -EBUSY; | 133 | return -EBUSY; |
99 | } | 134 | } |
100 | atomic_inc(&cur_trans->use_count); | 135 | atomic_inc(&cur_trans->use_count); |
101 | atomic_inc(&cur_trans->num_writers); | 136 | atomic_inc(&cur_trans->num_writers); |
102 | cur_trans->num_joined++; | 137 | extwriter_counter_inc(cur_trans, type); |
103 | spin_unlock(&fs_info->trans_lock); | 138 | spin_unlock(&fs_info->trans_lock); |
104 | return 0; | 139 | return 0; |
105 | } | 140 | } |
@@ -112,6 +147,12 @@ loop: | |||
112 | if (type == TRANS_ATTACH) | 147 | if (type == TRANS_ATTACH) |
113 | return -ENOENT; | 148 | return -ENOENT; |
114 | 149 | ||
150 | /* | ||
151 | * JOIN_NOLOCK only happens during the transaction commit, so | ||
152 | * it is impossible that ->running_transaction is NULL | ||
153 | */ | ||
154 | BUG_ON(type == TRANS_JOIN_NOLOCK); | ||
155 | |||
115 | cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS); | 156 | cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS); |
116 | if (!cur_trans) | 157 | if (!cur_trans) |
117 | return -ENOMEM; | 158 | return -ENOMEM; |
@@ -120,7 +161,7 @@ loop: | |||
120 | if (fs_info->running_transaction) { | 161 | if (fs_info->running_transaction) { |
121 | /* | 162 | /* |
122 | * someone started a transaction after we unlocked. Make sure | 163 | * someone started a transaction after we unlocked. Make sure |
123 | * to redo the trans_no_join checks above | 164 | * to redo the checks above |
124 | */ | 165 | */ |
125 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); | 166 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); |
126 | goto loop; | 167 | goto loop; |
@@ -131,17 +172,15 @@ loop: | |||
131 | } | 172 | } |
132 | 173 | ||
133 | atomic_set(&cur_trans->num_writers, 1); | 174 | atomic_set(&cur_trans->num_writers, 1); |
134 | cur_trans->num_joined = 0; | 175 | extwriter_counter_init(cur_trans, type); |
135 | init_waitqueue_head(&cur_trans->writer_wait); | 176 | init_waitqueue_head(&cur_trans->writer_wait); |
136 | init_waitqueue_head(&cur_trans->commit_wait); | 177 | init_waitqueue_head(&cur_trans->commit_wait); |
137 | cur_trans->in_commit = 0; | 178 | cur_trans->state = TRANS_STATE_RUNNING; |
138 | cur_trans->blocked = 0; | ||
139 | /* | 179 | /* |
140 | * One for this trans handle, one so it will live on until we | 180 | * One for this trans handle, one so it will live on until we |
141 | * commit the transaction. | 181 | * commit the transaction. |
142 | */ | 182 | */ |
143 | atomic_set(&cur_trans->use_count, 2); | 183 | atomic_set(&cur_trans->use_count, 2); |
144 | cur_trans->commit_done = 0; | ||
145 | cur_trans->start_time = get_seconds(); | 184 | cur_trans->start_time = get_seconds(); |
146 | 185 | ||
147 | cur_trans->delayed_refs.root = RB_ROOT; | 186 | cur_trans->delayed_refs.root = RB_ROOT; |
@@ -164,7 +203,6 @@ loop: | |||
164 | "creating a fresh transaction\n"); | 203 | "creating a fresh transaction\n"); |
165 | atomic64_set(&fs_info->tree_mod_seq, 0); | 204 | atomic64_set(&fs_info->tree_mod_seq, 0); |
166 | 205 | ||
167 | spin_lock_init(&cur_trans->commit_lock); | ||
168 | spin_lock_init(&cur_trans->delayed_refs.lock); | 206 | spin_lock_init(&cur_trans->delayed_refs.lock); |
169 | atomic_set(&cur_trans->delayed_refs.procs_running_refs, 0); | 207 | atomic_set(&cur_trans->delayed_refs.procs_running_refs, 0); |
170 | atomic_set(&cur_trans->delayed_refs.ref_seq, 0); | 208 | atomic_set(&cur_trans->delayed_refs.ref_seq, 0); |
@@ -172,6 +210,7 @@ loop: | |||
172 | 210 | ||
173 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 211 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
174 | INIT_LIST_HEAD(&cur_trans->ordered_operations); | 212 | INIT_LIST_HEAD(&cur_trans->ordered_operations); |
213 | INIT_LIST_HEAD(&cur_trans->pending_chunks); | ||
175 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 214 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
176 | extent_io_tree_init(&cur_trans->dirty_pages, | 215 | extent_io_tree_init(&cur_trans->dirty_pages, |
177 | fs_info->btree_inode->i_mapping); | 216 | fs_info->btree_inode->i_mapping); |
@@ -269,6 +308,13 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, | |||
269 | return 0; | 308 | return 0; |
270 | } | 309 | } |
271 | 310 | ||
311 | static inline int is_transaction_blocked(struct btrfs_transaction *trans) | ||
312 | { | ||
313 | return (trans->state >= TRANS_STATE_BLOCKED && | ||
314 | trans->state < TRANS_STATE_UNBLOCKED && | ||
315 | !trans->aborted); | ||
316 | } | ||
317 | |||
272 | /* wait for commit against the current transaction to become unblocked | 318 | /* wait for commit against the current transaction to become unblocked |
273 | * when this is done, it is safe to start a new transaction, but the current | 319 | * when this is done, it is safe to start a new transaction, but the current |
274 | * transaction might not be fully on disk. | 320 | * transaction might not be fully on disk. |
@@ -279,12 +325,13 @@ static void wait_current_trans(struct btrfs_root *root) | |||
279 | 325 | ||
280 | spin_lock(&root->fs_info->trans_lock); | 326 | spin_lock(&root->fs_info->trans_lock); |
281 | cur_trans = root->fs_info->running_transaction; | 327 | cur_trans = root->fs_info->running_transaction; |
282 | if (cur_trans && cur_trans->blocked) { | 328 | if (cur_trans && is_transaction_blocked(cur_trans)) { |
283 | atomic_inc(&cur_trans->use_count); | 329 | atomic_inc(&cur_trans->use_count); |
284 | spin_unlock(&root->fs_info->trans_lock); | 330 | spin_unlock(&root->fs_info->trans_lock); |
285 | 331 | ||
286 | wait_event(root->fs_info->transaction_wait, | 332 | wait_event(root->fs_info->transaction_wait, |
287 | !cur_trans->blocked); | 333 | cur_trans->state >= TRANS_STATE_UNBLOCKED || |
334 | cur_trans->aborted); | ||
288 | put_transaction(cur_trans); | 335 | put_transaction(cur_trans); |
289 | } else { | 336 | } else { |
290 | spin_unlock(&root->fs_info->trans_lock); | 337 | spin_unlock(&root->fs_info->trans_lock); |
@@ -307,7 +354,7 @@ static int may_wait_transaction(struct btrfs_root *root, int type) | |||
307 | } | 354 | } |
308 | 355 | ||
309 | static struct btrfs_trans_handle * | 356 | static struct btrfs_trans_handle * |
310 | start_transaction(struct btrfs_root *root, u64 num_items, int type, | 357 | start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, |
311 | enum btrfs_reserve_flush_enum flush) | 358 | enum btrfs_reserve_flush_enum flush) |
312 | { | 359 | { |
313 | struct btrfs_trans_handle *h; | 360 | struct btrfs_trans_handle *h; |
@@ -320,7 +367,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type, | |||
320 | return ERR_PTR(-EROFS); | 367 | return ERR_PTR(-EROFS); |
321 | 368 | ||
322 | if (current->journal_info) { | 369 | if (current->journal_info) { |
323 | WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK); | 370 | WARN_ON(type & TRANS_EXTWRITERS); |
324 | h = current->journal_info; | 371 | h = current->journal_info; |
325 | h->use_count++; | 372 | h->use_count++; |
326 | WARN_ON(h->use_count > 2); | 373 | WARN_ON(h->use_count > 2); |
@@ -366,7 +413,7 @@ again: | |||
366 | * If we are ATTACH, it means we just want to catch the current | 413 | * If we are ATTACH, it means we just want to catch the current |
367 | * transaction and commit it, so we needn't do sb_start_intwrite(). | 414 | * transaction and commit it, so we needn't do sb_start_intwrite(). |
368 | */ | 415 | */ |
369 | if (type < TRANS_JOIN_NOLOCK) | 416 | if (type & __TRANS_FREEZABLE) |
370 | sb_start_intwrite(root->fs_info->sb); | 417 | sb_start_intwrite(root->fs_info->sb); |
371 | 418 | ||
372 | if (may_wait_transaction(root, type)) | 419 | if (may_wait_transaction(root, type)) |
@@ -408,7 +455,8 @@ again: | |||
408 | INIT_LIST_HEAD(&h->new_bgs); | 455 | INIT_LIST_HEAD(&h->new_bgs); |
409 | 456 | ||
410 | smp_mb(); | 457 | smp_mb(); |
411 | if (cur_trans->blocked && may_wait_transaction(root, type)) { | 458 | if (cur_trans->state >= TRANS_STATE_BLOCKED && |
459 | may_wait_transaction(root, type)) { | ||
412 | btrfs_commit_transaction(h, root); | 460 | btrfs_commit_transaction(h, root); |
413 | goto again; | 461 | goto again; |
414 | } | 462 | } |
@@ -429,7 +477,7 @@ got_it: | |||
429 | return h; | 477 | return h; |
430 | 478 | ||
431 | join_fail: | 479 | join_fail: |
432 | if (type < TRANS_JOIN_NOLOCK) | 480 | if (type & __TRANS_FREEZABLE) |
433 | sb_end_intwrite(root->fs_info->sb); | 481 | sb_end_intwrite(root->fs_info->sb); |
434 | kmem_cache_free(btrfs_trans_handle_cachep, h); | 482 | kmem_cache_free(btrfs_trans_handle_cachep, h); |
435 | alloc_fail: | 483 | alloc_fail: |
@@ -490,7 +538,7 @@ struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root) | |||
490 | } | 538 | } |
491 | 539 | ||
492 | /* | 540 | /* |
493 | * btrfs_attach_transaction() - catch the running transaction | 541 | * btrfs_attach_transaction_barrier() - catch the running transaction |
494 | * | 542 | * |
495 | * It is similar to the above function, the differentia is this one | 543 | * It is similar to the above function, the differentia is this one |
496 | * will wait for all the inactive transactions until they fully | 544 | * will wait for all the inactive transactions until they fully |
@@ -512,7 +560,7 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root) | |||
512 | static noinline void wait_for_commit(struct btrfs_root *root, | 560 | static noinline void wait_for_commit(struct btrfs_root *root, |
513 | struct btrfs_transaction *commit) | 561 | struct btrfs_transaction *commit) |
514 | { | 562 | { |
515 | wait_event(commit->commit_wait, commit->commit_done); | 563 | wait_event(commit->commit_wait, commit->state == TRANS_STATE_COMPLETED); |
516 | } | 564 | } |
517 | 565 | ||
518 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | 566 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) |
@@ -548,8 +596,8 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
548 | spin_lock(&root->fs_info->trans_lock); | 596 | spin_lock(&root->fs_info->trans_lock); |
549 | list_for_each_entry_reverse(t, &root->fs_info->trans_list, | 597 | list_for_each_entry_reverse(t, &root->fs_info->trans_list, |
550 | list) { | 598 | list) { |
551 | if (t->in_commit) { | 599 | if (t->state >= TRANS_STATE_COMMIT_START) { |
552 | if (t->commit_done) | 600 | if (t->state == TRANS_STATE_COMPLETED) |
553 | break; | 601 | break; |
554 | cur_trans = t; | 602 | cur_trans = t; |
555 | atomic_inc(&cur_trans->use_count); | 603 | atomic_inc(&cur_trans->use_count); |
@@ -576,10 +624,11 @@ void btrfs_throttle(struct btrfs_root *root) | |||
576 | static int should_end_transaction(struct btrfs_trans_handle *trans, | 624 | static int should_end_transaction(struct btrfs_trans_handle *trans, |
577 | struct btrfs_root *root) | 625 | struct btrfs_root *root) |
578 | { | 626 | { |
579 | int ret; | 627 | if (root->fs_info->global_block_rsv.space_info->full && |
628 | btrfs_should_throttle_delayed_refs(trans, root)) | ||
629 | return 1; | ||
580 | 630 | ||
581 | ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5); | 631 | return !!btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5); |
582 | return ret ? 1 : 0; | ||
583 | } | 632 | } |
584 | 633 | ||
585 | int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, | 634 | int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, |
@@ -590,7 +639,8 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, | |||
590 | int err; | 639 | int err; |
591 | 640 | ||
592 | smp_mb(); | 641 | smp_mb(); |
593 | if (cur_trans->blocked || cur_trans->delayed_refs.flushing) | 642 | if (cur_trans->state >= TRANS_STATE_BLOCKED || |
643 | cur_trans->delayed_refs.flushing) | ||
594 | return 1; | 644 | return 1; |
595 | 645 | ||
596 | updates = trans->delayed_ref_updates; | 646 | updates = trans->delayed_ref_updates; |
@@ -609,7 +659,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
609 | { | 659 | { |
610 | struct btrfs_transaction *cur_trans = trans->transaction; | 660 | struct btrfs_transaction *cur_trans = trans->transaction; |
611 | struct btrfs_fs_info *info = root->fs_info; | 661 | struct btrfs_fs_info *info = root->fs_info; |
612 | int count = 0; | 662 | unsigned long cur = trans->delayed_ref_updates; |
613 | int lock = (trans->type != TRANS_JOIN_NOLOCK); | 663 | int lock = (trans->type != TRANS_JOIN_NOLOCK); |
614 | int err = 0; | 664 | int err = 0; |
615 | 665 | ||
@@ -638,17 +688,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
638 | if (!list_empty(&trans->new_bgs)) | 688 | if (!list_empty(&trans->new_bgs)) |
639 | btrfs_create_pending_block_groups(trans, root); | 689 | btrfs_create_pending_block_groups(trans, root); |
640 | 690 | ||
641 | while (count < 1) { | 691 | trans->delayed_ref_updates = 0; |
642 | unsigned long cur = trans->delayed_ref_updates; | 692 | if (btrfs_should_throttle_delayed_refs(trans, root)) { |
693 | cur = max_t(unsigned long, cur, 1); | ||
643 | trans->delayed_ref_updates = 0; | 694 | trans->delayed_ref_updates = 0; |
644 | if (cur && | 695 | btrfs_run_delayed_refs(trans, root, cur); |
645 | trans->transaction->delayed_refs.num_heads_ready > 64) { | ||
646 | trans->delayed_ref_updates = 0; | ||
647 | btrfs_run_delayed_refs(trans, root, cur); | ||
648 | } else { | ||
649 | break; | ||
650 | } | ||
651 | count++; | ||
652 | } | 696 | } |
653 | 697 | ||
654 | btrfs_trans_release_metadata(trans, root); | 698 | btrfs_trans_release_metadata(trans, root); |
@@ -658,12 +702,15 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
658 | btrfs_create_pending_block_groups(trans, root); | 702 | btrfs_create_pending_block_groups(trans, root); |
659 | 703 | ||
660 | if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && | 704 | if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && |
661 | should_end_transaction(trans, root)) { | 705 | should_end_transaction(trans, root) && |
662 | trans->transaction->blocked = 1; | 706 | ACCESS_ONCE(cur_trans->state) == TRANS_STATE_RUNNING) { |
663 | smp_wmb(); | 707 | spin_lock(&info->trans_lock); |
708 | if (cur_trans->state == TRANS_STATE_RUNNING) | ||
709 | cur_trans->state = TRANS_STATE_BLOCKED; | ||
710 | spin_unlock(&info->trans_lock); | ||
664 | } | 711 | } |
665 | 712 | ||
666 | if (lock && cur_trans->blocked && !cur_trans->in_commit) { | 713 | if (lock && ACCESS_ONCE(cur_trans->state) == TRANS_STATE_BLOCKED) { |
667 | if (throttle) { | 714 | if (throttle) { |
668 | /* | 715 | /* |
669 | * We may race with somebody else here so end up having | 716 | * We may race with somebody else here so end up having |
@@ -677,12 +724,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
677 | } | 724 | } |
678 | } | 725 | } |
679 | 726 | ||
680 | if (trans->type < TRANS_JOIN_NOLOCK) | 727 | if (trans->type & __TRANS_FREEZABLE) |
681 | sb_end_intwrite(root->fs_info->sb); | 728 | sb_end_intwrite(root->fs_info->sb); |
682 | 729 | ||
683 | WARN_ON(cur_trans != info->running_transaction); | 730 | WARN_ON(cur_trans != info->running_transaction); |
684 | WARN_ON(atomic_read(&cur_trans->num_writers) < 1); | 731 | WARN_ON(atomic_read(&cur_trans->num_writers) < 1); |
685 | atomic_dec(&cur_trans->num_writers); | 732 | atomic_dec(&cur_trans->num_writers); |
733 | extwriter_counter_dec(cur_trans, trans->type); | ||
686 | 734 | ||
687 | smp_mb(); | 735 | smp_mb(); |
688 | if (waitqueue_active(&cur_trans->writer_wait)) | 736 | if (waitqueue_active(&cur_trans->writer_wait)) |
@@ -736,9 +784,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
736 | struct extent_state *cached_state = NULL; | 784 | struct extent_state *cached_state = NULL; |
737 | u64 start = 0; | 785 | u64 start = 0; |
738 | u64 end; | 786 | u64 end; |
739 | struct blk_plug plug; | ||
740 | 787 | ||
741 | blk_start_plug(&plug); | ||
742 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, | 788 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, |
743 | mark, &cached_state)) { | 789 | mark, &cached_state)) { |
744 | convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, | 790 | convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, |
@@ -752,7 +798,6 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
752 | } | 798 | } |
753 | if (err) | 799 | if (err) |
754 | werr = err; | 800 | werr = err; |
755 | blk_finish_plug(&plug); | ||
756 | return werr; | 801 | return werr; |
757 | } | 802 | } |
758 | 803 | ||
@@ -797,8 +842,11 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
797 | { | 842 | { |
798 | int ret; | 843 | int ret; |
799 | int ret2; | 844 | int ret2; |
845 | struct blk_plug plug; | ||
800 | 846 | ||
847 | blk_start_plug(&plug); | ||
801 | ret = btrfs_write_marked_extents(root, dirty_pages, mark); | 848 | ret = btrfs_write_marked_extents(root, dirty_pages, mark); |
849 | blk_finish_plug(&plug); | ||
802 | ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); | 850 | ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); |
803 | 851 | ||
804 | if (ret) | 852 | if (ret) |
@@ -935,12 +983,12 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
935 | * a dirty root struct and adds it into the list of dead roots that need to | 983 | * a dirty root struct and adds it into the list of dead roots that need to |
936 | * be deleted | 984 | * be deleted |
937 | */ | 985 | */ |
938 | int btrfs_add_dead_root(struct btrfs_root *root) | 986 | void btrfs_add_dead_root(struct btrfs_root *root) |
939 | { | 987 | { |
940 | spin_lock(&root->fs_info->trans_lock); | 988 | spin_lock(&root->fs_info->trans_lock); |
941 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | 989 | if (list_empty(&root->root_list)) |
990 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | ||
942 | spin_unlock(&root->fs_info->trans_lock); | 991 | spin_unlock(&root->fs_info->trans_lock); |
943 | return 0; | ||
944 | } | 992 | } |
945 | 993 | ||
946 | /* | 994 | /* |
@@ -1318,20 +1366,26 @@ static void update_super_roots(struct btrfs_root *root) | |||
1318 | 1366 | ||
1319 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info) | 1367 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info) |
1320 | { | 1368 | { |
1369 | struct btrfs_transaction *trans; | ||
1321 | int ret = 0; | 1370 | int ret = 0; |
1371 | |||
1322 | spin_lock(&info->trans_lock); | 1372 | spin_lock(&info->trans_lock); |
1323 | if (info->running_transaction) | 1373 | trans = info->running_transaction; |
1324 | ret = info->running_transaction->in_commit; | 1374 | if (trans) |
1375 | ret = (trans->state >= TRANS_STATE_COMMIT_START); | ||
1325 | spin_unlock(&info->trans_lock); | 1376 | spin_unlock(&info->trans_lock); |
1326 | return ret; | 1377 | return ret; |
1327 | } | 1378 | } |
1328 | 1379 | ||
1329 | int btrfs_transaction_blocked(struct btrfs_fs_info *info) | 1380 | int btrfs_transaction_blocked(struct btrfs_fs_info *info) |
1330 | { | 1381 | { |
1382 | struct btrfs_transaction *trans; | ||
1331 | int ret = 0; | 1383 | int ret = 0; |
1384 | |||
1332 | spin_lock(&info->trans_lock); | 1385 | spin_lock(&info->trans_lock); |
1333 | if (info->running_transaction) | 1386 | trans = info->running_transaction; |
1334 | ret = info->running_transaction->blocked; | 1387 | if (trans) |
1388 | ret = is_transaction_blocked(trans); | ||
1335 | spin_unlock(&info->trans_lock); | 1389 | spin_unlock(&info->trans_lock); |
1336 | return ret; | 1390 | return ret; |
1337 | } | 1391 | } |
@@ -1343,7 +1397,9 @@ int btrfs_transaction_blocked(struct btrfs_fs_info *info) | |||
1343 | static void wait_current_trans_commit_start(struct btrfs_root *root, | 1397 | static void wait_current_trans_commit_start(struct btrfs_root *root, |
1344 | struct btrfs_transaction *trans) | 1398 | struct btrfs_transaction *trans) |
1345 | { | 1399 | { |
1346 | wait_event(root->fs_info->transaction_blocked_wait, trans->in_commit); | 1400 | wait_event(root->fs_info->transaction_blocked_wait, |
1401 | trans->state >= TRANS_STATE_COMMIT_START || | ||
1402 | trans->aborted); | ||
1347 | } | 1403 | } |
1348 | 1404 | ||
1349 | /* | 1405 | /* |
@@ -1354,7 +1410,8 @@ static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root, | |||
1354 | struct btrfs_transaction *trans) | 1410 | struct btrfs_transaction *trans) |
1355 | { | 1411 | { |
1356 | wait_event(root->fs_info->transaction_wait, | 1412 | wait_event(root->fs_info->transaction_wait, |
1357 | trans->commit_done || (trans->in_commit && !trans->blocked)); | 1413 | trans->state >= TRANS_STATE_UNBLOCKED || |
1414 | trans->aborted); | ||
1358 | } | 1415 | } |
1359 | 1416 | ||
1360 | /* | 1417 | /* |
@@ -1450,26 +1507,31 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1450 | 1507 | ||
1451 | spin_lock(&root->fs_info->trans_lock); | 1508 | spin_lock(&root->fs_info->trans_lock); |
1452 | 1509 | ||
1453 | if (list_empty(&cur_trans->list)) { | 1510 | /* |
1454 | spin_unlock(&root->fs_info->trans_lock); | 1511 | * If the transaction is removed from the list, it means this |
1455 | btrfs_end_transaction(trans, root); | 1512 | * transaction has been committed successfully, so it is impossible |
1456 | return; | 1513 | * to call the cleanup function. |
1457 | } | 1514 | */ |
1515 | BUG_ON(list_empty(&cur_trans->list)); | ||
1458 | 1516 | ||
1459 | list_del_init(&cur_trans->list); | 1517 | list_del_init(&cur_trans->list); |
1460 | if (cur_trans == root->fs_info->running_transaction) { | 1518 | if (cur_trans == root->fs_info->running_transaction) { |
1461 | root->fs_info->trans_no_join = 1; | 1519 | cur_trans->state = TRANS_STATE_COMMIT_DOING; |
1462 | spin_unlock(&root->fs_info->trans_lock); | 1520 | spin_unlock(&root->fs_info->trans_lock); |
1463 | wait_event(cur_trans->writer_wait, | 1521 | wait_event(cur_trans->writer_wait, |
1464 | atomic_read(&cur_trans->num_writers) == 1); | 1522 | atomic_read(&cur_trans->num_writers) == 1); |
1465 | 1523 | ||
1466 | spin_lock(&root->fs_info->trans_lock); | 1524 | spin_lock(&root->fs_info->trans_lock); |
1467 | root->fs_info->running_transaction = NULL; | ||
1468 | } | 1525 | } |
1469 | spin_unlock(&root->fs_info->trans_lock); | 1526 | spin_unlock(&root->fs_info->trans_lock); |
1470 | 1527 | ||
1471 | btrfs_cleanup_one_transaction(trans->transaction, root); | 1528 | btrfs_cleanup_one_transaction(trans->transaction, root); |
1472 | 1529 | ||
1530 | spin_lock(&root->fs_info->trans_lock); | ||
1531 | if (cur_trans == root->fs_info->running_transaction) | ||
1532 | root->fs_info->running_transaction = NULL; | ||
1533 | spin_unlock(&root->fs_info->trans_lock); | ||
1534 | |||
1473 | put_transaction(cur_trans); | 1535 | put_transaction(cur_trans); |
1474 | put_transaction(cur_trans); | 1536 | put_transaction(cur_trans); |
1475 | 1537 | ||
@@ -1481,33 +1543,13 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1481 | current->journal_info = NULL; | 1543 | current->journal_info = NULL; |
1482 | 1544 | ||
1483 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 1545 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
1484 | |||
1485 | spin_lock(&root->fs_info->trans_lock); | ||
1486 | root->fs_info->trans_no_join = 0; | ||
1487 | spin_unlock(&root->fs_info->trans_lock); | ||
1488 | } | 1546 | } |
1489 | 1547 | ||
1490 | static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | 1548 | static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, |
1491 | struct btrfs_root *root) | 1549 | struct btrfs_root *root) |
1492 | { | 1550 | { |
1493 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | ||
1494 | int snap_pending = 0; | ||
1495 | int ret; | 1551 | int ret; |
1496 | 1552 | ||
1497 | if (!flush_on_commit) { | ||
1498 | spin_lock(&root->fs_info->trans_lock); | ||
1499 | if (!list_empty(&trans->transaction->pending_snapshots)) | ||
1500 | snap_pending = 1; | ||
1501 | spin_unlock(&root->fs_info->trans_lock); | ||
1502 | } | ||
1503 | |||
1504 | if (flush_on_commit || snap_pending) { | ||
1505 | ret = btrfs_start_delalloc_inodes(root, 1); | ||
1506 | if (ret) | ||
1507 | return ret; | ||
1508 | btrfs_wait_ordered_extents(root, 1); | ||
1509 | } | ||
1510 | |||
1511 | ret = btrfs_run_delayed_items(trans, root); | 1553 | ret = btrfs_run_delayed_items(trans, root); |
1512 | if (ret) | 1554 | if (ret) |
1513 | return ret; | 1555 | return ret; |
@@ -1531,23 +1573,25 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1531 | return ret; | 1573 | return ret; |
1532 | } | 1574 | } |
1533 | 1575 | ||
1534 | /* | 1576 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) |
1535 | * btrfs_transaction state sequence: | 1577 | { |
1536 | * in_commit = 0, blocked = 0 (initial) | 1578 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
1537 | * in_commit = 1, blocked = 1 | 1579 | return btrfs_start_all_delalloc_inodes(fs_info, 1); |
1538 | * blocked = 0 | 1580 | return 0; |
1539 | * commit_done = 1 | 1581 | } |
1540 | */ | 1582 | |
1583 | static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) | ||
1584 | { | ||
1585 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | ||
1586 | btrfs_wait_all_ordered_extents(fs_info, 1); | ||
1587 | } | ||
1588 | |||
1541 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 1589 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
1542 | struct btrfs_root *root) | 1590 | struct btrfs_root *root) |
1543 | { | 1591 | { |
1544 | unsigned long joined = 0; | ||
1545 | struct btrfs_transaction *cur_trans = trans->transaction; | 1592 | struct btrfs_transaction *cur_trans = trans->transaction; |
1546 | struct btrfs_transaction *prev_trans = NULL; | 1593 | struct btrfs_transaction *prev_trans = NULL; |
1547 | DEFINE_WAIT(wait); | ||
1548 | int ret; | 1594 | int ret; |
1549 | int should_grow = 0; | ||
1550 | unsigned long now = get_seconds(); | ||
1551 | 1595 | ||
1552 | ret = btrfs_run_ordered_operations(trans, root, 0); | 1596 | ret = btrfs_run_ordered_operations(trans, root, 0); |
1553 | if (ret) { | 1597 | if (ret) { |
@@ -1586,6 +1630,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1586 | * start sending their work down. | 1630 | * start sending their work down. |
1587 | */ | 1631 | */ |
1588 | cur_trans->delayed_refs.flushing = 1; | 1632 | cur_trans->delayed_refs.flushing = 1; |
1633 | smp_wmb(); | ||
1589 | 1634 | ||
1590 | if (!list_empty(&trans->new_bgs)) | 1635 | if (!list_empty(&trans->new_bgs)) |
1591 | btrfs_create_pending_block_groups(trans, root); | 1636 | btrfs_create_pending_block_groups(trans, root); |
@@ -1596,9 +1641,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1596 | return ret; | 1641 | return ret; |
1597 | } | 1642 | } |
1598 | 1643 | ||
1599 | spin_lock(&cur_trans->commit_lock); | 1644 | spin_lock(&root->fs_info->trans_lock); |
1600 | if (cur_trans->in_commit) { | 1645 | if (cur_trans->state >= TRANS_STATE_COMMIT_START) { |
1601 | spin_unlock(&cur_trans->commit_lock); | 1646 | spin_unlock(&root->fs_info->trans_lock); |
1602 | atomic_inc(&cur_trans->use_count); | 1647 | atomic_inc(&cur_trans->use_count); |
1603 | ret = btrfs_end_transaction(trans, root); | 1648 | ret = btrfs_end_transaction(trans, root); |
1604 | 1649 | ||
@@ -1609,16 +1654,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1609 | return ret; | 1654 | return ret; |
1610 | } | 1655 | } |
1611 | 1656 | ||
1612 | trans->transaction->in_commit = 1; | 1657 | cur_trans->state = TRANS_STATE_COMMIT_START; |
1613 | trans->transaction->blocked = 1; | ||
1614 | spin_unlock(&cur_trans->commit_lock); | ||
1615 | wake_up(&root->fs_info->transaction_blocked_wait); | 1658 | wake_up(&root->fs_info->transaction_blocked_wait); |
1616 | 1659 | ||
1617 | spin_lock(&root->fs_info->trans_lock); | ||
1618 | if (cur_trans->list.prev != &root->fs_info->trans_list) { | 1660 | if (cur_trans->list.prev != &root->fs_info->trans_list) { |
1619 | prev_trans = list_entry(cur_trans->list.prev, | 1661 | prev_trans = list_entry(cur_trans->list.prev, |
1620 | struct btrfs_transaction, list); | 1662 | struct btrfs_transaction, list); |
1621 | if (!prev_trans->commit_done) { | 1663 | if (prev_trans->state != TRANS_STATE_COMPLETED) { |
1622 | atomic_inc(&prev_trans->use_count); | 1664 | atomic_inc(&prev_trans->use_count); |
1623 | spin_unlock(&root->fs_info->trans_lock); | 1665 | spin_unlock(&root->fs_info->trans_lock); |
1624 | 1666 | ||
@@ -1632,42 +1674,32 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1632 | spin_unlock(&root->fs_info->trans_lock); | 1674 | spin_unlock(&root->fs_info->trans_lock); |
1633 | } | 1675 | } |
1634 | 1676 | ||
1635 | if (!btrfs_test_opt(root, SSD) && | 1677 | extwriter_counter_dec(cur_trans, trans->type); |
1636 | (now < cur_trans->start_time || now - cur_trans->start_time < 1)) | ||
1637 | should_grow = 1; | ||
1638 | |||
1639 | do { | ||
1640 | joined = cur_trans->num_joined; | ||
1641 | |||
1642 | WARN_ON(cur_trans != trans->transaction); | ||
1643 | |||
1644 | ret = btrfs_flush_all_pending_stuffs(trans, root); | ||
1645 | if (ret) | ||
1646 | goto cleanup_transaction; | ||
1647 | 1678 | ||
1648 | prepare_to_wait(&cur_trans->writer_wait, &wait, | 1679 | ret = btrfs_start_delalloc_flush(root->fs_info); |
1649 | TASK_UNINTERRUPTIBLE); | 1680 | if (ret) |
1681 | goto cleanup_transaction; | ||
1650 | 1682 | ||
1651 | if (atomic_read(&cur_trans->num_writers) > 1) | 1683 | ret = btrfs_flush_all_pending_stuffs(trans, root); |
1652 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); | 1684 | if (ret) |
1653 | else if (should_grow) | 1685 | goto cleanup_transaction; |
1654 | schedule_timeout(1); | ||
1655 | 1686 | ||
1656 | finish_wait(&cur_trans->writer_wait, &wait); | 1687 | wait_event(cur_trans->writer_wait, |
1657 | } while (atomic_read(&cur_trans->num_writers) > 1 || | 1688 | extwriter_counter_read(cur_trans) == 0); |
1658 | (should_grow && cur_trans->num_joined != joined)); | ||
1659 | 1689 | ||
1690 | /* some pending stuffs might be added after the previous flush. */ | ||
1660 | ret = btrfs_flush_all_pending_stuffs(trans, root); | 1691 | ret = btrfs_flush_all_pending_stuffs(trans, root); |
1661 | if (ret) | 1692 | if (ret) |
1662 | goto cleanup_transaction; | 1693 | goto cleanup_transaction; |
1663 | 1694 | ||
1695 | btrfs_wait_delalloc_flush(root->fs_info); | ||
1664 | /* | 1696 | /* |
1665 | * Ok now we need to make sure to block out any other joins while we | 1697 | * Ok now we need to make sure to block out any other joins while we |
1666 | * commit the transaction. We could have started a join before setting | 1698 | * commit the transaction. We could have started a join before setting |
1667 | * no_join so make sure to wait for num_writers to == 1 again. | 1699 | * COMMIT_DOING so make sure to wait for num_writers to == 1 again. |
1668 | */ | 1700 | */ |
1669 | spin_lock(&root->fs_info->trans_lock); | 1701 | spin_lock(&root->fs_info->trans_lock); |
1670 | root->fs_info->trans_no_join = 1; | 1702 | cur_trans->state = TRANS_STATE_COMMIT_DOING; |
1671 | spin_unlock(&root->fs_info->trans_lock); | 1703 | spin_unlock(&root->fs_info->trans_lock); |
1672 | wait_event(cur_trans->writer_wait, | 1704 | wait_event(cur_trans->writer_wait, |
1673 | atomic_read(&cur_trans->num_writers) == 1); | 1705 | atomic_read(&cur_trans->num_writers) == 1); |
@@ -1794,10 +1826,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1794 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, | 1826 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, |
1795 | sizeof(*root->fs_info->super_copy)); | 1827 | sizeof(*root->fs_info->super_copy)); |
1796 | 1828 | ||
1797 | trans->transaction->blocked = 0; | ||
1798 | spin_lock(&root->fs_info->trans_lock); | 1829 | spin_lock(&root->fs_info->trans_lock); |
1830 | cur_trans->state = TRANS_STATE_UNBLOCKED; | ||
1799 | root->fs_info->running_transaction = NULL; | 1831 | root->fs_info->running_transaction = NULL; |
1800 | root->fs_info->trans_no_join = 0; | ||
1801 | spin_unlock(&root->fs_info->trans_lock); | 1832 | spin_unlock(&root->fs_info->trans_lock); |
1802 | mutex_unlock(&root->fs_info->reloc_mutex); | 1833 | mutex_unlock(&root->fs_info->reloc_mutex); |
1803 | 1834 | ||
@@ -1825,10 +1856,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1825 | 1856 | ||
1826 | btrfs_finish_extent_commit(trans, root); | 1857 | btrfs_finish_extent_commit(trans, root); |
1827 | 1858 | ||
1828 | cur_trans->commit_done = 1; | ||
1829 | |||
1830 | root->fs_info->last_trans_committed = cur_trans->transid; | 1859 | root->fs_info->last_trans_committed = cur_trans->transid; |
1831 | 1860 | /* | |
1861 | * We needn't acquire the lock here because there is no other task | ||
1862 | * which can change it. | ||
1863 | */ | ||
1864 | cur_trans->state = TRANS_STATE_COMPLETED; | ||
1832 | wake_up(&cur_trans->commit_wait); | 1865 | wake_up(&cur_trans->commit_wait); |
1833 | 1866 | ||
1834 | spin_lock(&root->fs_info->trans_lock); | 1867 | spin_lock(&root->fs_info->trans_lock); |
@@ -1838,7 +1871,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1838 | put_transaction(cur_trans); | 1871 | put_transaction(cur_trans); |
1839 | put_transaction(cur_trans); | 1872 | put_transaction(cur_trans); |
1840 | 1873 | ||
1841 | if (trans->type < TRANS_JOIN_NOLOCK) | 1874 | if (trans->type & __TRANS_FREEZABLE) |
1842 | sb_end_intwrite(root->fs_info->sb); | 1875 | sb_end_intwrite(root->fs_info->sb); |
1843 | 1876 | ||
1844 | trace_btrfs_transaction_commit(root); | 1877 | trace_btrfs_transaction_commit(root); |
@@ -1885,11 +1918,6 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root) | |||
1885 | int ret; | 1918 | int ret; |
1886 | struct btrfs_fs_info *fs_info = root->fs_info; | 1919 | struct btrfs_fs_info *fs_info = root->fs_info; |
1887 | 1920 | ||
1888 | if (fs_info->sb->s_flags & MS_RDONLY) { | ||
1889 | pr_debug("btrfs: cleaner called for RO fs!\n"); | ||
1890 | return 0; | ||
1891 | } | ||
1892 | |||
1893 | spin_lock(&fs_info->trans_lock); | 1921 | spin_lock(&fs_info->trans_lock); |
1894 | if (list_empty(&fs_info->dead_roots)) { | 1922 | if (list_empty(&fs_info->dead_roots)) { |
1895 | spin_unlock(&fs_info->trans_lock); | 1923 | spin_unlock(&fs_info->trans_lock); |
@@ -1897,7 +1925,7 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root) | |||
1897 | } | 1925 | } |
1898 | root = list_first_entry(&fs_info->dead_roots, | 1926 | root = list_first_entry(&fs_info->dead_roots, |
1899 | struct btrfs_root, root_list); | 1927 | struct btrfs_root, root_list); |
1900 | list_del(&root->root_list); | 1928 | list_del_init(&root->root_list); |
1901 | spin_unlock(&fs_info->trans_lock); | 1929 | spin_unlock(&fs_info->trans_lock); |
1902 | 1930 | ||
1903 | pr_debug("btrfs: cleaner removing %llu\n", | 1931 | pr_debug("btrfs: cleaner removing %llu\n", |