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/josef/btrfs-next

Pull btrfs fixes from Josef Bacik:
"I'm playing the role of Chris Mason this week while he's on vacation.
There are a few critical fixes for btrfs here, all regressions and
have been tested well"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next:
Btrfs: fix wrong write offset when replacing a device
Btrfs: re-add root to dead root list if we stop dropping it
Btrfs: fix lock leak when resuming snapshot deletion
Btrfs: update drop progress before stopping snapshot dropping

+22 -7
+21 -6
fs/btrfs/extent-tree.c
··· 7466 7466 int err = 0; 7467 7467 int ret; 7468 7468 int level; 7469 + bool root_dropped = false; 7469 7470 7470 7471 path = btrfs_alloc_path(); 7471 7472 if (!path) { ··· 7524 7523 while (1) { 7525 7524 btrfs_tree_lock(path->nodes[level]); 7526 7525 btrfs_set_lock_blocking(path->nodes[level]); 7526 + path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; 7527 7527 7528 7528 ret = btrfs_lookup_extent_info(trans, root, 7529 7529 path->nodes[level]->start, ··· 7540 7538 break; 7541 7539 7542 7540 btrfs_tree_unlock(path->nodes[level]); 7541 + path->locks[level] = 0; 7543 7542 WARN_ON(wc->refs[level] != 1); 7544 7543 level--; 7545 7544 } ··· 7555 7552 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); 7556 7553 7557 7554 while (1) { 7558 - if (!for_reloc && btrfs_need_cleaner_sleep(root)) { 7559 - pr_debug("btrfs: drop snapshot early exit\n"); 7560 - err = -EAGAIN; 7561 - goto out_end_trans; 7562 - } 7563 7555 7564 7556 ret = walk_down_tree(trans, root, path, wc); 7565 7557 if (ret < 0) { ··· 7582 7584 } 7583 7585 7584 7586 BUG_ON(wc->level == 0); 7585 - if (btrfs_should_end_transaction(trans, tree_root)) { 7587 + if (btrfs_should_end_transaction(trans, tree_root) || 7588 + (!for_reloc && btrfs_need_cleaner_sleep(root))) { 7586 7589 ret = btrfs_update_root(trans, tree_root, 7587 7590 &root->root_key, 7588 7591 root_item); ··· 7594 7595 } 7595 7596 7596 7597 btrfs_end_transaction_throttle(trans, tree_root); 7598 + if (!for_reloc && btrfs_need_cleaner_sleep(root)) { 7599 + pr_debug("btrfs: drop snapshot early exit\n"); 7600 + err = -EAGAIN; 7601 + goto out_free; 7602 + } 7603 + 7597 7604 trans = btrfs_start_transaction(tree_root, 0); 7598 7605 if (IS_ERR(trans)) { 7599 7606 err = PTR_ERR(trans); ··· 7644 7639 free_extent_buffer(root->commit_root); 7645 7640 btrfs_put_fs_root(root); 7646 7641 } 7642 + root_dropped = true; 7647 7643 out_end_trans: 7648 7644 btrfs_end_transaction_throttle(trans, tree_root); 7649 7645 out_free: 7650 7646 kfree(wc); 7651 7647 btrfs_free_path(path); 7652 7648 out: 7649 + /* 7650 + * So if we need to stop dropping the snapshot for whatever reason we 7651 + * need to make sure to add it back to the dead root list so that we 7652 + * keep trying to do the work later. This also cleans up roots if we 7653 + * don't have it in the radix (like when we recover after a power fail 7654 + * or unmount) so we don't leak memory. 7655 + */ 7656 + if (root_dropped == false) 7657 + btrfs_add_dead_root(root); 7653 7658 if (err) 7654 7659 btrfs_std_error(root->fs_info, err); 7655 7660 return err;
+1 -1
fs/btrfs/scrub.c
··· 2495 2495 ret = scrub_extent(sctx, extent_logical, extent_len, 2496 2496 extent_physical, extent_dev, flags, 2497 2497 generation, extent_mirror_num, 2498 - extent_physical); 2498 + extent_logical - logical + physical); 2499 2499 if (ret) 2500 2500 goto out; 2501 2501