Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs fixes from Chris Mason:
"This is a small collection of fixes, including a regression fix from
Liu Bo that solves rare crashes with compression on.

I've merged my for-linus up to 3.12-rc3 because the top commit is only
meant for 3.12. The rest of the fixes are also available in my master
branch on top of my last 3.11 based pull"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
btrfs: Fix crash due to not allocating integrity data for a bioset
Btrfs: fix a use-after-free bug in btrfs_dev_replace_finishing
Btrfs: eliminate races in worker stopping code
Btrfs: fix crash of compressed writes
Btrfs: fix transid verify errors when recovering log tree

+39 -17
+19 -6
fs/btrfs/async-thread.c
··· 107 107 worker->idle = 1; 108 108 109 109 /* the list may be empty if the worker is just starting */ 110 - if (!list_empty(&worker->worker_list)) { 110 + if (!list_empty(&worker->worker_list) && 111 + !worker->workers->stopping) { 111 112 list_move(&worker->worker_list, 112 113 &worker->workers->idle_list); 113 114 } ··· 128 127 spin_lock_irqsave(&worker->workers->lock, flags); 129 128 worker->idle = 0; 130 129 131 - if (!list_empty(&worker->worker_list)) { 130 + if (!list_empty(&worker->worker_list) && 131 + !worker->workers->stopping) { 132 132 list_move_tail(&worker->worker_list, 133 133 &worker->workers->worker_list); 134 134 } ··· 414 412 int can_stop; 415 413 416 414 spin_lock_irq(&workers->lock); 415 + workers->stopping = 1; 417 416 list_splice_init(&workers->idle_list, &workers->worker_list); 418 417 while (!list_empty(&workers->worker_list)) { 419 418 cur = workers->worker_list.next; ··· 458 455 workers->ordered = 0; 459 456 workers->atomic_start_pending = 0; 460 457 workers->atomic_worker_start = async_helper; 458 + workers->stopping = 0; 461 459 } 462 460 463 461 /* ··· 484 480 atomic_set(&worker->num_pending, 0); 485 481 atomic_set(&worker->refs, 1); 486 482 worker->workers = workers; 487 - worker->task = kthread_run(worker_loop, worker, 488 - "btrfs-%s-%d", workers->name, 489 - workers->num_workers + 1); 483 + worker->task = kthread_create(worker_loop, worker, 484 + "btrfs-%s-%d", workers->name, 485 + workers->num_workers + 1); 490 486 if (IS_ERR(worker->task)) { 491 487 ret = PTR_ERR(worker->task); 492 - kfree(worker); 493 488 goto fail; 494 489 } 490 + 495 491 spin_lock_irq(&workers->lock); 492 + if (workers->stopping) { 493 + spin_unlock_irq(&workers->lock); 494 + goto fail_kthread; 495 + } 496 496 list_add_tail(&worker->worker_list, &workers->idle_list); 497 497 worker->idle = 1; 498 498 workers->num_workers++; ··· 504 496 WARN_ON(workers->num_workers_starting < 0); 505 497 spin_unlock_irq(&workers->lock); 506 498 499 + wake_up_process(worker->task); 507 500 return 0; 501 + 502 + fail_kthread: 503 + kthread_stop(worker->task); 508 504 fail: 505 + kfree(worker); 509 506 spin_lock_irq(&workers->lock); 510 507 workers->num_workers_starting--; 511 508 spin_unlock_irq(&workers->lock);
+2
fs/btrfs/async-thread.h
··· 107 107 108 108 /* extra name for this worker, used for current->name */ 109 109 char *name; 110 + 111 + int stopping; 110 112 }; 111 113 112 114 void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
+1 -4
fs/btrfs/dev-replace.c
··· 535 535 list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); 536 536 537 537 btrfs_rm_dev_replace_srcdev(fs_info, src_device); 538 - if (src_device->bdev) { 539 - /* zero out the old super */ 540 - btrfs_scratch_superblock(src_device); 541 - } 538 + 542 539 /* 543 540 * this is again a consistent state where no dev_replace procedure 544 541 * is running, the target device is part of the filesystem, the
+9 -1
fs/btrfs/extent_io.c
··· 145 145 offsetof(struct btrfs_io_bio, bio)); 146 146 if (!btrfs_bioset) 147 147 goto free_buffer_cache; 148 + 149 + if (bioset_integrity_create(btrfs_bioset, BIO_POOL_SIZE)) 150 + goto free_bioset; 151 + 148 152 return 0; 153 + 154 + free_bioset: 155 + bioset_free(btrfs_bioset); 156 + btrfs_bioset = NULL; 149 157 150 158 free_buffer_cache: 151 159 kmem_cache_destroy(extent_buffer_cache); ··· 1622 1614 *start = delalloc_start; 1623 1615 *end = delalloc_end; 1624 1616 free_extent_state(cached_state); 1625 - return found; 1617 + return 0; 1626 1618 } 1627 1619 1628 1620 /*
+2 -5
fs/btrfs/transaction.c
··· 1838 1838 assert_qgroups_uptodate(trans); 1839 1839 update_super_roots(root); 1840 1840 1841 - if (!root->fs_info->log_root_recovering) { 1842 - btrfs_set_super_log_root(root->fs_info->super_copy, 0); 1843 - btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); 1844 - } 1845 - 1841 + btrfs_set_super_log_root(root->fs_info->super_copy, 0); 1842 + btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); 1846 1843 memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, 1847 1844 sizeof(*root->fs_info->super_copy)); 1848 1845
+6 -1
fs/btrfs/volumes.c
··· 1716 1716 struct btrfs_device *srcdev) 1717 1717 { 1718 1718 WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex)); 1719 + 1719 1720 list_del_rcu(&srcdev->dev_list); 1720 1721 list_del_rcu(&srcdev->dev_alloc_list); 1721 1722 fs_info->fs_devices->num_devices--; ··· 1726 1725 } 1727 1726 if (srcdev->can_discard) 1728 1727 fs_info->fs_devices->num_can_discard--; 1729 - if (srcdev->bdev) 1728 + if (srcdev->bdev) { 1730 1729 fs_info->fs_devices->open_devices--; 1730 + 1731 + /* zero out the old super */ 1732 + btrfs_scratch_superblock(srcdev); 1733 + } 1731 1734 1732 1735 call_rcu(&srcdev->rcu, free_device); 1733 1736 }