diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index c6b6a6e3e735..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 | ||
@@ -633,10 +633,10 @@ 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 | ||
@@ -2444,7 +2444,8 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2444 | spin_unlock(&locked_ref->lock); | 2444 | spin_unlock(&locked_ref->lock); |
2445 | spin_lock(&delayed_refs->lock); | 2445 | spin_lock(&delayed_refs->lock); |
2446 | spin_lock(&locked_ref->lock); | 2446 | spin_lock(&locked_ref->lock); |
2447 | if (rb_first(&locked_ref->ref_root)) { | 2447 | if (rb_first(&locked_ref->ref_root) || |
2448 | locked_ref->extent_op) { | ||
2448 | spin_unlock(&locked_ref->lock); | 2449 | spin_unlock(&locked_ref->lock); |
2449 | spin_unlock(&delayed_refs->lock); | 2450 | spin_unlock(&delayed_refs->lock); |
2450 | continue; | 2451 | continue; |
@@ -5470,7 +5471,7 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5470 | struct btrfs_block_group_cache *cache; | 5471 | struct btrfs_block_group_cache *cache; |
5471 | struct btrfs_space_info *space_info; | 5472 | struct btrfs_space_info *space_info; |
5472 | 5473 | ||
5473 | down_write(&fs_info->extent_commit_sem); | 5474 | down_write(&fs_info->commit_root_sem); |
5474 | 5475 | ||
5475 | list_for_each_entry_safe(caching_ctl, next, | 5476 | list_for_each_entry_safe(caching_ctl, next, |
5476 | &fs_info->caching_block_groups, list) { | 5477 | &fs_info->caching_block_groups, list) { |
@@ -5489,7 +5490,7 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5489 | else | 5490 | else |
5490 | fs_info->pinned_extents = &fs_info->freed_extents[0]; | 5491 | fs_info->pinned_extents = &fs_info->freed_extents[0]; |
5491 | 5492 | ||
5492 | up_write(&fs_info->extent_commit_sem); | 5493 | up_write(&fs_info->commit_root_sem); |
5493 | 5494 | ||
5494 | 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) |
5495 | percpu_counter_set(&space_info->total_bytes_pinned, 0); | 5496 | percpu_counter_set(&space_info->total_bytes_pinned, 0); |
@@ -5744,6 +5745,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5744 | "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", |
5745 | bytenr, parent, root_objectid, owner_objectid, | 5746 | bytenr, parent, root_objectid, owner_objectid, |
5746 | owner_offset); | 5747 | owner_offset); |
5748 | btrfs_abort_transaction(trans, extent_root, ret); | ||
5749 | goto out; | ||
5747 | } else { | 5750 | } else { |
5748 | btrfs_abort_transaction(trans, extent_root, ret); | 5751 | btrfs_abort_transaction(trans, extent_root, ret); |
5749 | goto out; | 5752 | goto out; |
@@ -8255,14 +8258,14 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
8255 | struct btrfs_caching_control *caching_ctl; | 8258 | struct btrfs_caching_control *caching_ctl; |
8256 | struct rb_node *n; | 8259 | struct rb_node *n; |
8257 | 8260 | ||
8258 | down_write(&info->extent_commit_sem); | 8261 | down_write(&info->commit_root_sem); |
8259 | while (!list_empty(&info->caching_block_groups)) { | 8262 | while (!list_empty(&info->caching_block_groups)) { |
8260 | caching_ctl = list_entry(info->caching_block_groups.next, | 8263 | caching_ctl = list_entry(info->caching_block_groups.next, |
8261 | struct btrfs_caching_control, list); | 8264 | struct btrfs_caching_control, list); |
8262 | list_del(&caching_ctl->list); | 8265 | list_del(&caching_ctl->list); |
8263 | put_caching_control(caching_ctl); | 8266 | put_caching_control(caching_ctl); |
8264 | } | 8267 | } |
8265 | up_write(&info->extent_commit_sem); | 8268 | up_write(&info->commit_root_sem); |
8266 | 8269 | ||
8267 | spin_lock(&info->block_group_cache_lock); | 8270 | spin_lock(&info->block_group_cache_lock); |
8268 | while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { | 8271 | while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { |
@@ -8336,9 +8339,15 @@ static void __link_block_group(struct btrfs_space_info *space_info, | |||
8336 | struct btrfs_block_group_cache *cache) | 8339 | struct btrfs_block_group_cache *cache) |
8337 | { | 8340 | { |
8338 | int index = get_block_group_index(cache); | 8341 | int index = get_block_group_index(cache); |
8342 | bool first = false; | ||
8339 | 8343 | ||
8340 | down_write(&space_info->groups_sem); | 8344 | down_write(&space_info->groups_sem); |
8341 | 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) { | ||
8342 | struct kobject *kobj = &space_info->block_group_kobjs[index]; | 8351 | struct kobject *kobj = &space_info->block_group_kobjs[index]; |
8343 | int ret; | 8352 | int ret; |
8344 | 8353 | ||
@@ -8350,8 +8359,6 @@ static void __link_block_group(struct btrfs_space_info *space_info, | |||
8350 | kobject_put(&space_info->kobj); | 8359 | kobject_put(&space_info->kobj); |
8351 | } | 8360 | } |
8352 | } | 8361 | } |
8353 | list_add_tail(&cache->list, &space_info->block_groups[index]); | ||
8354 | up_write(&space_info->groups_sem); | ||
8355 | } | 8362 | } |
8356 | 8363 | ||
8357 | static struct btrfs_block_group_cache * | 8364 | static struct btrfs_block_group_cache * |