return 0;
                }
 
+               if (p->nowait) {
+                       free_extent_buffer(tmp);
+                       return -EAGAIN;
+               }
+
                if (unlock_up)
                        btrfs_unlock_up_safe(p, level + 1);
 
                        ret = -EAGAIN;
 
                goto out;
+       } else if (p->nowait) {
+               return -EAGAIN;
        }
 
        if (unlock_up) {
                 * We don't know the level of the root node until we actually
                 * have it read locked
                 */
-               b = btrfs_read_lock_root_node(root);
+               if (p->nowait) {
+                       b = btrfs_try_read_lock_root_node(root);
+                       if (IS_ERR(b))
+                               return b;
+               } else {
+                       b = btrfs_read_lock_root_node(root);
+               }
                level = btrfs_header_level(b);
                if (level > write_lock_level)
                        goto out;
        WARN_ON(p->nodes[0] != NULL);
        BUG_ON(!cow && ins_len);
 
+       /*
+        * For now only allow nowait for read only operations.  There's no
+        * strict reason why we can't, we just only need it for reads so it's
+        * only implemented for reads.
+        */
+       ASSERT(!p->nowait || !cow);
+
        if (ins_len < 0) {
                lowest_unlock = 2;
 
 
        if (p->need_commit_sem) {
                ASSERT(p->search_commit_root);
-               down_read(&fs_info->commit_root_sem);
+               if (p->nowait) {
+                       if (!down_read_trylock(&fs_info->commit_root_sem))
+                               return -EAGAIN;
+               } else {
+                       down_read(&fs_info->commit_root_sem);
+               }
        }
 
 again:
                                btrfs_tree_lock(b);
                                p->locks[level] = BTRFS_WRITE_LOCK;
                        } else {
-                               btrfs_tree_read_lock(b);
+                               if (p->nowait) {
+                                       if (!btrfs_try_tree_read_lock(b)) {
+                                               free_extent_buffer(b);
+                                               ret = -EAGAIN;
+                                               goto done;
+                                       }
+                               } else {
+                                       btrfs_tree_read_lock(b);
+                               }
                                p->locks[level] = BTRFS_READ_LOCK;
                        }
                        p->nodes[level] = b;
 
         * header (ie. sizeof(struct btrfs_item) is not included).
         */
        unsigned int search_for_extension:1;
+       /* Stop search if any locks need to be taken (for read) */
+       unsigned int nowait:1;
 };
 
 struct btrfs_dev_replace {
 
        return eb;
 }
 
+/*
+ * Loop around taking references on and locking the root node of the tree in
+ * nowait mode until we end up with a lock on the root node or returning to
+ * avoid blocking.
+ *
+ * Return: root extent buffer with read lock held or -EAGAIN.
+ */
+struct extent_buffer *btrfs_try_read_lock_root_node(struct btrfs_root *root)
+{
+       struct extent_buffer *eb;
+
+       while (1) {
+               eb = btrfs_root_node(root);
+               if (!btrfs_try_tree_read_lock(eb)) {
+                       free_extent_buffer(eb);
+                       return ERR_PTR(-EAGAIN);
+               }
+               if (eb == root->node)
+                       break;
+               btrfs_tree_read_unlock(eb);
+               free_extent_buffer(eb);
+       }
+       return eb;
+}
+
 /*
  * DREW locks
  * ==========
 
 int btrfs_try_tree_write_lock(struct extent_buffer *eb);
 struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
 struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root);
+struct extent_buffer *btrfs_try_read_lock_root_node(struct btrfs_root *root);
 
 #ifdef CONFIG_BTRFS_DEBUG
 static inline void btrfs_assert_tree_write_locked(struct extent_buffer *eb)