btrfs: wakeup cleaner thread when adding delayed iput
[sfrench/cifs-2.6.git] / fs / btrfs / ctree.c
index a436259c71b16e43fe0e91b3ec92732eaf20267c..f64aad61372763188bbbe252864685c862b766c3 100644 (file)
@@ -12,6 +12,7 @@
 #include "transaction.h"
 #include "print-tree.h"
 #include "locking.h"
+#include "volumes.h"
 
 static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
                      *root, struct btrfs_path *path, int level);
@@ -224,7 +225,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
        else
                btrfs_set_header_owner(cow, new_root_objectid);
 
-       write_extent_buffer_fsid(cow, fs_info->fsid);
+       write_extent_buffer_fsid(cow, fs_info->fs_devices->metadata_uuid);
 
        WARN_ON(btrfs_header_generation(buf) > trans->transid);
        if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID)
@@ -1015,19 +1016,21 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
                parent_start = parent->start;
 
        /*
-        * If we are COWing a node/leaf from the extent, chunk or device trees,
-        * make sure that we do not finish block group creation of pending block
-        * groups. We do this to avoid a deadlock.
+        * If we are COWing a node/leaf from the extent, chunk, device or free
+        * space trees, make sure that we do not finish block group creation of
+        * pending block groups. We do this to avoid a deadlock.
         * COWing can result in allocation of a new chunk, and flushing pending
         * block groups (btrfs_create_pending_block_groups()) can be triggered
         * when finishing allocation of a new chunk. Creation of a pending block
-        * group modifies the extent, chunk and device trees, therefore we could
-        * deadlock with ourselves since we are holding a lock on an extent
-        * buffer that btrfs_create_pending_block_groups() may try to COW later.
+        * group modifies the extent, chunk, device and free space trees,
+        * therefore we could deadlock with ourselves since we are holding a
+        * lock on an extent buffer that btrfs_create_pending_block_groups() may
+        * try to COW later.
         */
        if (root == fs_info->extent_root ||
            root == fs_info->chunk_root ||
-           root == fs_info->dev_root)
+           root == fs_info->dev_root ||
+           root == fs_info->free_space_root)
                trans->can_flush_pending_bgs = false;
 
        cow = btrfs_alloc_tree_block(trans, root, parent_start,
@@ -1050,7 +1053,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
        else
                btrfs_set_header_owner(cow, root->root_key.objectid);
 
-       write_extent_buffer_fsid(cow, fs_info->fsid);
+       write_extent_buffer_fsid(cow, fs_info->fs_devices->metadata_uuid);
 
        ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
        if (ret) {
@@ -1413,7 +1416,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
         *
         * What is forced COW:
         *    when we create snapshot during committing the transaction,
-        *    after we've finished coping src root, we must COW the shared
+        *    after we've finished copying src root, we must COW the shared
         *    block to ensure the metadata consistency.
         */
        if (btrfs_header_generation(buf) == trans->transid &&
@@ -1439,6 +1442,10 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
        u64 search_start;
        int ret;
 
+       if (test_bit(BTRFS_ROOT_DELETING, &root->state))
+               btrfs_err(fs_info,
+                       "COW'ing blocks on a fs root that's being dropped");
+
        if (trans->transaction != fs_info->running_transaction)
                WARN(1, KERN_CRIT "trans %llu running %llu\n",
                       trans->transid,
@@ -2582,14 +2589,27 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root,
        root_lock = BTRFS_READ_LOCK;
 
        if (p->search_commit_root) {
-               /* The commit roots are read only so we always do read locks */
-               if (p->need_commit_sem)
+               /*
+                * The commit roots are read only so we always do read locks,
+                * and we always must hold the commit_root_sem when doing
+                * searches on them, the only exception is send where we don't
+                * want to block transaction commits for a long time, so
+                * we need to clone the commit root in order to avoid races
+                * with transaction commits that create a snapshot of one of
+                * the roots used by a send operation.
+                */
+               if (p->need_commit_sem) {
                        down_read(&fs_info->commit_root_sem);
-               b = root->commit_root;
-               extent_buffer_get(b);
-               level = btrfs_header_level(b);
-               if (p->need_commit_sem)
+                       b = btrfs_clone_extent_buffer(root->commit_root);
                        up_read(&fs_info->commit_root_sem);
+                       if (!b)
+                               return ERR_PTR(-ENOMEM);
+
+               } else {
+                       b = root->commit_root;
+                       extent_buffer_get(b);
+               }
+               level = btrfs_header_level(b);
                /*
                 * Ensure that all callers have set skip_locking when
                 * p->search_commit_root = 1.
@@ -2715,6 +2735,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 again:
        prev_cmp = -1;
        b = btrfs_search_slot_get_root(root, p, write_lock_level);
+       if (IS_ERR(b)) {
+               ret = PTR_ERR(b);
+               goto done;
+       }
 
        while (b) {
                level = btrfs_header_level(b);
@@ -3749,7 +3773,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
                /* Key greater than all keys in the leaf, right neighbor has
                 * enough room for it and we're not emptying our leaf to delete
                 * it, therefore use right neighbor to insert the new item and
-                * no need to touch/dirty our left leaft. */
+                * no need to touch/dirty our left leaf. */
                btrfs_tree_unlock(left);
                free_extent_buffer(left);
                path->nodes[0] = right;