diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 94 |
1 files changed, 65 insertions, 29 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9c9ecc93ae2c..1306487c82cf 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -419,7 +419,7 @@ static noinline void caching_thread(struct btrfs_work *work) | |||
419 | again: | 419 | again: |
420 | mutex_lock(&caching_ctl->mutex); | 420 | mutex_lock(&caching_ctl->mutex); |
421 | /* need to make sure the commit_root doesn't disappear */ | 421 | /* need to make sure the commit_root doesn't disappear */ |
422 | down_read(&fs_info->extent_commit_sem); | 422 | down_read(&fs_info->commit_root_sem); |
423 | 423 | ||
424 | next: | 424 | next: |
425 | ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); | 425 | ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); |
@@ -443,10 +443,10 @@ next: | |||
443 | break; | 443 | break; |
444 | 444 | ||
445 | if (need_resched() || | 445 | if (need_resched() || |
446 | rwsem_is_contended(&fs_info->extent_commit_sem)) { | 446 | rwsem_is_contended(&fs_info->commit_root_sem)) { |
447 | caching_ctl->progress = last; | 447 | caching_ctl->progress = last; |
448 | btrfs_release_path(path); | 448 | btrfs_release_path(path); |
449 | up_read(&fs_info->extent_commit_sem); | 449 | up_read(&fs_info->commit_root_sem); |
450 | mutex_unlock(&caching_ctl->mutex); | 450 | mutex_unlock(&caching_ctl->mutex); |
451 | cond_resched(); | 451 | cond_resched(); |
452 | goto again; | 452 | goto again; |
@@ -513,7 +513,7 @@ next: | |||
513 | 513 | ||
514 | err: | 514 | err: |
515 | btrfs_free_path(path); | 515 | btrfs_free_path(path); |
516 | up_read(&fs_info->extent_commit_sem); | 516 | up_read(&fs_info->commit_root_sem); |
517 | 517 | ||
518 | free_excluded_extents(extent_root, block_group); | 518 | free_excluded_extents(extent_root, block_group); |
519 | 519 | ||
@@ -549,7 +549,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
549 | caching_ctl->block_group = cache; | 549 | caching_ctl->block_group = cache; |
550 | caching_ctl->progress = cache->key.objectid; | 550 | caching_ctl->progress = cache->key.objectid; |
551 | atomic_set(&caching_ctl->count, 1); | 551 | atomic_set(&caching_ctl->count, 1); |
552 | caching_ctl->work.func = caching_thread; | 552 | btrfs_init_work(&caching_ctl->work, caching_thread, NULL, NULL); |
553 | 553 | ||
554 | spin_lock(&cache->lock); | 554 | spin_lock(&cache->lock); |
555 | /* | 555 | /* |
@@ -633,14 +633,14 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
633 | return 0; | 633 | return 0; |
634 | } | 634 | } |
635 | 635 | ||
636 | down_write(&fs_info->extent_commit_sem); | 636 | down_write(&fs_info->commit_root_sem); |
637 | atomic_inc(&caching_ctl->count); | 637 | atomic_inc(&caching_ctl->count); |
638 | list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups); | 638 | list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups); |
639 | up_write(&fs_info->extent_commit_sem); | 639 | up_write(&fs_info->commit_root_sem); |
640 | 640 | ||
641 | btrfs_get_block_group(cache); | 641 | btrfs_get_block_group(cache); |
642 | 642 | ||
643 | btrfs_queue_worker(&fs_info->caching_workers, &caching_ctl->work); | 643 | btrfs_queue_work(fs_info->caching_workers, &caching_ctl->work); |
644 | 644 | ||
645 | return ret; | 645 | return ret; |
646 | } | 646 | } |
@@ -2385,6 +2385,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2385 | spin_unlock(&delayed_refs->lock); | 2385 | spin_unlock(&delayed_refs->lock); |
2386 | locked_ref = NULL; | 2386 | locked_ref = NULL; |
2387 | cond_resched(); | 2387 | cond_resched(); |
2388 | count++; | ||
2388 | continue; | 2389 | continue; |
2389 | } | 2390 | } |
2390 | 2391 | ||
@@ -2443,7 +2444,8 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2443 | spin_unlock(&locked_ref->lock); | 2444 | spin_unlock(&locked_ref->lock); |
2444 | spin_lock(&delayed_refs->lock); | 2445 | spin_lock(&delayed_refs->lock); |
2445 | spin_lock(&locked_ref->lock); | 2446 | spin_lock(&locked_ref->lock); |
2446 | if (rb_first(&locked_ref->ref_root)) { | 2447 | if (rb_first(&locked_ref->ref_root) || |
2448 | locked_ref->extent_op) { | ||
2447 | spin_unlock(&locked_ref->lock); | 2449 | spin_unlock(&locked_ref->lock); |
2448 | spin_unlock(&delayed_refs->lock); | 2450 | spin_unlock(&delayed_refs->lock); |
2449 | continue; | 2451 | continue; |
@@ -3970,7 +3972,7 @@ static int can_overcommit(struct btrfs_root *root, | |||
3970 | } | 3972 | } |
3971 | 3973 | ||
3972 | static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, | 3974 | static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, |
3973 | unsigned long nr_pages) | 3975 | unsigned long nr_pages, int nr_items) |
3974 | { | 3976 | { |
3975 | struct super_block *sb = root->fs_info->sb; | 3977 | struct super_block *sb = root->fs_info->sb; |
3976 | 3978 | ||
@@ -3985,9 +3987,9 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, | |||
3985 | * the filesystem is readonly(all dirty pages are written to | 3987 | * the filesystem is readonly(all dirty pages are written to |
3986 | * the disk). | 3988 | * the disk). |
3987 | */ | 3989 | */ |
3988 | btrfs_start_delalloc_roots(root->fs_info, 0); | 3990 | btrfs_start_delalloc_roots(root->fs_info, 0, nr_items); |
3989 | if (!current->journal_info) | 3991 | if (!current->journal_info) |
3990 | btrfs_wait_ordered_roots(root->fs_info, -1); | 3992 | btrfs_wait_ordered_roots(root->fs_info, nr_items); |
3991 | } | 3993 | } |
3992 | } | 3994 | } |
3993 | 3995 | ||
@@ -4044,7 +4046,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
4044 | while (delalloc_bytes && loops < 3) { | 4046 | while (delalloc_bytes && loops < 3) { |
4045 | max_reclaim = min(delalloc_bytes, to_reclaim); | 4047 | max_reclaim = min(delalloc_bytes, to_reclaim); |
4046 | nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; | 4048 | nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; |
4047 | btrfs_writeback_inodes_sb_nr(root, nr_pages); | 4049 | btrfs_writeback_inodes_sb_nr(root, nr_pages, items); |
4048 | /* | 4050 | /* |
4049 | * We need to wait for the async pages to actually start before | 4051 | * We need to wait for the async pages to actually start before |
4050 | * we do anything. | 4052 | * we do anything. |
@@ -4111,13 +4113,9 @@ static int may_commit_transaction(struct btrfs_root *root, | |||
4111 | goto commit; | 4113 | goto commit; |
4112 | 4114 | ||
4113 | /* See if there is enough pinned space to make this reservation */ | 4115 | /* See if there is enough pinned space to make this reservation */ |
4114 | spin_lock(&space_info->lock); | ||
4115 | if (percpu_counter_compare(&space_info->total_bytes_pinned, | 4116 | if (percpu_counter_compare(&space_info->total_bytes_pinned, |
4116 | bytes) >= 0) { | 4117 | bytes) >= 0) |
4117 | spin_unlock(&space_info->lock); | ||
4118 | goto commit; | 4118 | goto commit; |
4119 | } | ||
4120 | spin_unlock(&space_info->lock); | ||
4121 | 4119 | ||
4122 | /* | 4120 | /* |
4123 | * See if there is some space in the delayed insertion reservation for | 4121 | * See if there is some space in the delayed insertion reservation for |
@@ -4126,16 +4124,13 @@ static int may_commit_transaction(struct btrfs_root *root, | |||
4126 | if (space_info != delayed_rsv->space_info) | 4124 | if (space_info != delayed_rsv->space_info) |
4127 | return -ENOSPC; | 4125 | return -ENOSPC; |
4128 | 4126 | ||
4129 | spin_lock(&space_info->lock); | ||
4130 | spin_lock(&delayed_rsv->lock); | 4127 | spin_lock(&delayed_rsv->lock); |
4131 | if (percpu_counter_compare(&space_info->total_bytes_pinned, | 4128 | if (percpu_counter_compare(&space_info->total_bytes_pinned, |
4132 | bytes - delayed_rsv->size) >= 0) { | 4129 | bytes - delayed_rsv->size) >= 0) { |
4133 | spin_unlock(&delayed_rsv->lock); | 4130 | spin_unlock(&delayed_rsv->lock); |
4134 | spin_unlock(&space_info->lock); | ||
4135 | return -ENOSPC; | 4131 | return -ENOSPC; |
4136 | } | 4132 | } |
4137 | spin_unlock(&delayed_rsv->lock); | 4133 | spin_unlock(&delayed_rsv->lock); |
4138 | spin_unlock(&space_info->lock); | ||
4139 | 4134 | ||
4140 | commit: | 4135 | commit: |
4141 | trans = btrfs_join_transaction(root); | 4136 | trans = btrfs_join_transaction(root); |
@@ -4180,7 +4175,7 @@ static int flush_space(struct btrfs_root *root, | |||
4180 | break; | 4175 | break; |
4181 | case FLUSH_DELALLOC: | 4176 | case FLUSH_DELALLOC: |
4182 | case FLUSH_DELALLOC_WAIT: | 4177 | case FLUSH_DELALLOC_WAIT: |
4183 | shrink_delalloc(root, num_bytes, orig_bytes, | 4178 | shrink_delalloc(root, num_bytes * 2, orig_bytes, |
4184 | state == FLUSH_DELALLOC_WAIT); | 4179 | state == FLUSH_DELALLOC_WAIT); |
4185 | break; | 4180 | break; |
4186 | case ALLOC_CHUNK: | 4181 | case ALLOC_CHUNK: |
@@ -5476,7 +5471,7 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5476 | struct btrfs_block_group_cache *cache; | 5471 | struct btrfs_block_group_cache *cache; |
5477 | struct btrfs_space_info *space_info; | 5472 | struct btrfs_space_info *space_info; |
5478 | 5473 | ||
5479 | down_write(&fs_info->extent_commit_sem); | 5474 | down_write(&fs_info->commit_root_sem); |
5480 | 5475 | ||
5481 | list_for_each_entry_safe(caching_ctl, next, | 5476 | list_for_each_entry_safe(caching_ctl, next, |
5482 | &fs_info->caching_block_groups, list) { | 5477 | &fs_info->caching_block_groups, list) { |
@@ -5495,7 +5490,7 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5495 | else | 5490 | else |
5496 | fs_info->pinned_extents = &fs_info->freed_extents[0]; | 5491 | fs_info->pinned_extents = &fs_info->freed_extents[0]; |
5497 | 5492 | ||
5498 | up_write(&fs_info->extent_commit_sem); | 5493 | up_write(&fs_info->commit_root_sem); |
5499 | 5494 | ||
5500 | list_for_each_entry_rcu(space_info, &fs_info->space_info, list) | 5495 | list_for_each_entry_rcu(space_info, &fs_info->space_info, list) |
5501 | percpu_counter_set(&space_info->total_bytes_pinned, 0); | 5496 | percpu_counter_set(&space_info->total_bytes_pinned, 0); |
@@ -5750,6 +5745,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5750 | "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", | 5745 | "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", |
5751 | bytenr, parent, root_objectid, owner_objectid, | 5746 | bytenr, parent, root_objectid, owner_objectid, |
5752 | owner_offset); | 5747 | owner_offset); |
5748 | btrfs_abort_transaction(trans, extent_root, ret); | ||
5749 | goto out; | ||
5753 | } else { | 5750 | } else { |
5754 | btrfs_abort_transaction(trans, extent_root, ret); | 5751 | btrfs_abort_transaction(trans, extent_root, ret); |
5755 | goto out; | 5752 | goto out; |
@@ -8261,14 +8258,14 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
8261 | struct btrfs_caching_control *caching_ctl; | 8258 | struct btrfs_caching_control *caching_ctl; |
8262 | struct rb_node *n; | 8259 | struct rb_node *n; |
8263 | 8260 | ||
8264 | down_write(&info->extent_commit_sem); | 8261 | down_write(&info->commit_root_sem); |
8265 | while (!list_empty(&info->caching_block_groups)) { | 8262 | while (!list_empty(&info->caching_block_groups)) { |
8266 | caching_ctl = list_entry(info->caching_block_groups.next, | 8263 | caching_ctl = list_entry(info->caching_block_groups.next, |
8267 | struct btrfs_caching_control, list); | 8264 | struct btrfs_caching_control, list); |
8268 | list_del(&caching_ctl->list); | 8265 | list_del(&caching_ctl->list); |
8269 | put_caching_control(caching_ctl); | 8266 | put_caching_control(caching_ctl); |
8270 | } | 8267 | } |
8271 | up_write(&info->extent_commit_sem); | 8268 | up_write(&info->commit_root_sem); |
8272 | 8269 | ||
8273 | spin_lock(&info->block_group_cache_lock); | 8270 | spin_lock(&info->block_group_cache_lock); |
8274 | while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { | 8271 | while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { |
@@ -8342,9 +8339,15 @@ static void __link_block_group(struct btrfs_space_info *space_info, | |||
8342 | struct btrfs_block_group_cache *cache) | 8339 | struct btrfs_block_group_cache *cache) |
8343 | { | 8340 | { |
8344 | int index = get_block_group_index(cache); | 8341 | int index = get_block_group_index(cache); |
8342 | bool first = false; | ||
8345 | 8343 | ||
8346 | down_write(&space_info->groups_sem); | 8344 | down_write(&space_info->groups_sem); |
8347 | if (list_empty(&space_info->block_groups[index])) { | 8345 | if (list_empty(&space_info->block_groups[index])) |
8346 | first = true; | ||
8347 | list_add_tail(&cache->list, &space_info->block_groups[index]); | ||
8348 | up_write(&space_info->groups_sem); | ||
8349 | |||
8350 | if (first) { | ||
8348 | struct kobject *kobj = &space_info->block_group_kobjs[index]; | 8351 | struct kobject *kobj = &space_info->block_group_kobjs[index]; |
8349 | int ret; | 8352 | int ret; |
8350 | 8353 | ||
@@ -8356,8 +8359,6 @@ static void __link_block_group(struct btrfs_space_info *space_info, | |||
8356 | kobject_put(&space_info->kobj); | 8359 | kobject_put(&space_info->kobj); |
8357 | } | 8360 | } |
8358 | } | 8361 | } |
8359 | list_add_tail(&cache->list, &space_info->block_groups[index]); | ||
8360 | up_write(&space_info->groups_sem); | ||
8361 | } | 8362 | } |
8362 | 8363 | ||
8363 | static struct btrfs_block_group_cache * | 8364 | static struct btrfs_block_group_cache * |
@@ -8937,3 +8938,38 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) | |||
8937 | range->len = trimmed; | 8938 | range->len = trimmed; |
8938 | return ret; | 8939 | return ret; |
8939 | } | 8940 | } |
8941 | |||
8942 | /* | ||
8943 | * btrfs_{start,end}_write() is similar to mnt_{want, drop}_write(), | ||
8944 | * they are used to prevent the some tasks writing data into the page cache | ||
8945 | * by nocow before the subvolume is snapshoted, but flush the data into | ||
8946 | * the disk after the snapshot creation. | ||
8947 | */ | ||
8948 | void btrfs_end_nocow_write(struct btrfs_root *root) | ||
8949 | { | ||
8950 | percpu_counter_dec(&root->subv_writers->counter); | ||
8951 | /* | ||
8952 | * Make sure counter is updated before we wake up | ||
8953 | * waiters. | ||
8954 | */ | ||
8955 | smp_mb(); | ||
8956 | if (waitqueue_active(&root->subv_writers->wait)) | ||
8957 | wake_up(&root->subv_writers->wait); | ||
8958 | } | ||
8959 | |||
8960 | int btrfs_start_nocow_write(struct btrfs_root *root) | ||
8961 | { | ||
8962 | if (unlikely(atomic_read(&root->will_be_snapshoted))) | ||
8963 | return 0; | ||
8964 | |||
8965 | percpu_counter_inc(&root->subv_writers->counter); | ||
8966 | /* | ||
8967 | * Make sure counter is updated before we check for snapshot creation. | ||
8968 | */ | ||
8969 | smp_mb(); | ||
8970 | if (unlikely(atomic_read(&root->will_be_snapshoted))) { | ||
8971 | btrfs_end_nocow_write(root); | ||
8972 | return 0; | ||
8973 | } | ||
8974 | return 1; | ||
8975 | } | ||