diff options
author | Olof Johansson <olof@lixom.net> | 2013-08-11 15:33:54 -0700 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-08-11 15:33:54 -0700 |
commit | 4ddbed9618724d52a7a79c1e10ef5adb46fcccf7 (patch) | |
tree | ffe64efb333d7dcdb5b2cf43ffef97b25261702c /fs/btrfs/extent-tree.c | |
parent | 16649596d701c0f4f767bbcad7da4d6343ba8a9e (diff) | |
parent | fa8c5a811e0e7c3e1c49b2e58fcb4db549b5719a (diff) |
Merge tag 'boards-3.12' of git://git.infradead.org/linux-mvebu into next/boards
From Jason Cooper:
mvebu boards changes for v3.12
- convert kirkwood, dove, orion5x to DT init of mv643xx_eth
- _lots_ of board code removal :)
- convert kirkwood, dove and orion5x to DT init of clocksource and irqchip
* tag 'boards-3.12' of git://git.infradead.org/linux-mvebu:
ARM: plat-orion: add reg offset to DT irq driver stub
ARM: kirkwood: remove obsolete SDIO clock gate workaround
ARM: kirkwood: convert to DT irqchip and clocksource
ARM: dove: convert to DT irqchip and clocksource
ARM: orion5x: update intc device tree node to new reg layout
ARM: kirkwood: move device tree nodes to DT irqchip and clocksource
ARM: dove: move device tree nodes to DT irqchip and clocksource
ARM: orion5x: remove legacy mv643xx_eth board setup
ARM: kirkwood: remove legacy clk alias for mv643xx_eth
ARM: kirkwood: remove redundant DT board files
ARM: dove: remove legacy mv643xx_eth setup
ARM: orion5x: add gigabit ethernet and mvmdio device tree nodes
ARM: kirkwood: add gigabit ethernet and mvmdio device tree nodes
ARM: dove: add gigabit ethernet and mvmdio device tree nodes
+ Linux 3.11-rc2
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0236de71198..1204c8ef6f3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -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; |