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
This commit is contained in:
Коммит
90290c4ebe
|
@ -7466,6 +7466,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
int err = 0;
|
||||
int ret;
|
||||
int level;
|
||||
bool root_dropped = false;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
|
@ -7523,6 +7524,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
while (1) {
|
||||
btrfs_tree_lock(path->nodes[level]);
|
||||
btrfs_set_lock_blocking(path->nodes[level]);
|
||||
path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
|
||||
|
||||
ret = btrfs_lookup_extent_info(trans, root,
|
||||
path->nodes[level]->start,
|
||||
|
@ -7538,6 +7540,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
break;
|
||||
|
||||
btrfs_tree_unlock(path->nodes[level]);
|
||||
path->locks[level] = 0;
|
||||
WARN_ON(wc->refs[level] != 1);
|
||||
level--;
|
||||
}
|
||||
|
@ -7552,11 +7555,6 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
|
||||
|
||||
while (1) {
|
||||
if (!for_reloc && btrfs_need_cleaner_sleep(root)) {
|
||||
pr_debug("btrfs: drop snapshot early exit\n");
|
||||
err = -EAGAIN;
|
||||
goto out_end_trans;
|
||||
}
|
||||
|
||||
ret = walk_down_tree(trans, root, path, wc);
|
||||
if (ret < 0) {
|
||||
|
@ -7584,7 +7582,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
}
|
||||
|
||||
BUG_ON(wc->level == 0);
|
||||
if (btrfs_should_end_transaction(trans, tree_root)) {
|
||||
if (btrfs_should_end_transaction(trans, tree_root) ||
|
||||
(!for_reloc && btrfs_need_cleaner_sleep(root))) {
|
||||
ret = btrfs_update_root(trans, tree_root,
|
||||
&root->root_key,
|
||||
root_item);
|
||||
|
@ -7595,6 +7594,12 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
}
|
||||
|
||||
btrfs_end_transaction_throttle(trans, tree_root);
|
||||
if (!for_reloc && btrfs_need_cleaner_sleep(root)) {
|
||||
pr_debug("btrfs: drop snapshot early exit\n");
|
||||
err = -EAGAIN;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
trans = btrfs_start_transaction(tree_root, 0);
|
||||
if (IS_ERR(trans)) {
|
||||
err = PTR_ERR(trans);
|
||||
|
@ -7639,12 +7644,22 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
|
|||
free_extent_buffer(root->commit_root);
|
||||
btrfs_put_fs_root(root);
|
||||
}
|
||||
root_dropped = true;
|
||||
out_end_trans:
|
||||
btrfs_end_transaction_throttle(trans, tree_root);
|
||||
out_free:
|
||||
kfree(wc);
|
||||
btrfs_free_path(path);
|
||||
out:
|
||||
/*
|
||||
* So if we need to stop dropping the snapshot for whatever reason we
|
||||
* need to make sure to add it back to the dead root list so that we
|
||||
* keep trying to do the work later. This also cleans up roots if we
|
||||
* don't have it in the radix (like when we recover after a power fail
|
||||
* or unmount) so we don't leak memory.
|
||||
*/
|
||||
if (root_dropped == false)
|
||||
btrfs_add_dead_root(root);
|
||||
if (err)
|
||||
btrfs_std_error(root->fs_info, err);
|
||||
return err;
|
||||
|
|
|
@ -2495,7 +2495,7 @@ again:
|
|||
ret = scrub_extent(sctx, extent_logical, extent_len,
|
||||
extent_physical, extent_dev, flags,
|
||||
generation, extent_mirror_num,
|
||||
extent_physical);
|
||||
extent_logical - logical + physical);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче