Merge branch 'for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 4 Aug 2016 23:56:16 +0000 (19:56 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 4 Aug 2016 23:56:16 +0000 (19:56 -0400)
Pull more btrfs updates from Chris Mason:
 "This is part two of my btrfs pull, which is some cleanups and a batch
  of fixes.

  Most of the code here is from Jeff Mahoney, making the pointers we
  pass around internally more consistent and less confusing overall.  I
  noticed a small problem right before I sent this out yesterday, so I
  fixed it up and re-tested overnight"

* 'for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (40 commits)
  Btrfs: fix __MAX_CSUM_ITEMS
  btrfs: btrfs_abort_transaction, drop root parameter
  btrfs: add btrfs_trans_handle->fs_info pointer
  btrfs: btrfs_relocate_chunk pass extent_root to btrfs_end_transaction
  btrfs: convert nodesize macros to static inlines
  btrfs: introduce BTRFS_MAX_ITEM_SIZE
  btrfs: cleanup, remove prototype for btrfs_find_root_ref
  btrfs: copy_to_sk drop unused root parameter
  btrfs: simpilify btrfs_subvol_inherit_props
  btrfs: tests, use BTRFS_FS_STATE_DUMMY_FS_INFO instead of dummy root
  btrfs: tests, require fs_info for root
  btrfs: tests, move initialization into tests/
  btrfs: btrfs_test_opt and friends should take a btrfs_fs_info
  btrfs: prefix fsid to all trace events
  btrfs: plumb fs_info into btrfs_work
  btrfs: remove obsolete part of comment in statfs
  btrfs: hide test-only member under ifdef
  btrfs: Ratelimit "no csum found" info message
  btrfs: Add ratelimit to btrfs printing
  Btrfs: fix unexpected balance crash due to BUG_ON
  ...

45 files changed:
fs/btrfs/acl.c
fs/btrfs/async-thread.c
fs/btrfs/async-thread.h
fs/btrfs/backref.c
fs/btrfs/compression.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/dedupe.h [new file with mode: 0644]
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-ref.c
fs/btrfs/dev-replace.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/free-space-tree.c
fs/btrfs/inode-map.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/props.c
fs/btrfs/qgroup.c
fs/btrfs/qgroup.h
fs/btrfs/relocation.c
fs/btrfs/root-tree.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/sysfs.c
fs/btrfs/tests/btrfs-tests.c
fs/btrfs/tests/btrfs-tests.h
fs/btrfs/tests/extent-buffer-tests.c
fs/btrfs/tests/free-space-tests.c
fs/btrfs/tests/free-space-tree-tests.c
fs/btrfs/tests/inode-tests.c
fs/btrfs/tests/qgroup-tests.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
include/trace/events/btrfs.h
include/uapi/linux/btrfs.h

index 67a607709d4f7eb18d941cf1a70c7d00a7afba66..53bb7af4e5f06cfb1b0a38e167b7cc880fd8aefe 100644 (file)
@@ -55,8 +55,7 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
        }
        if (size > 0) {
                acl = posix_acl_from_xattr(&init_user_ns, value, size);
-       } else if (size == -ENOENT || size == -ENODATA || size == 0) {
-               /* FIXME, who returns -ENOENT?  I think nobody */
+       } else if (size == -ERANGE || size == -ENODATA || size == 0) {
                acl = NULL;
        } else {
                acl = ERR_PTR(-EIO);
index 5fb60ea7eee2b2c28e067d11b54c2fad7127c7d8..e0f071f6b5a761faa6a00b741017a759c91e100a 100644 (file)
 
 struct __btrfs_workqueue {
        struct workqueue_struct *normal_wq;
+
+       /* File system this workqueue services */
+       struct btrfs_fs_info *fs_info;
+
        /* List head pointing to ordered work list */
        struct list_head ordered_list;
 
@@ -70,6 +74,18 @@ void btrfs_##name(struct work_struct *arg)                           \
        normal_work_helper(work);                                       \
 }
 
+struct btrfs_fs_info *
+btrfs_workqueue_owner(struct __btrfs_workqueue *wq)
+{
+       return wq->fs_info;
+}
+
+struct btrfs_fs_info *
+btrfs_work_owner(struct btrfs_work *work)
+{
+       return work->wq->fs_info;
+}
+
 BTRFS_WORK_HELPER(worker_helper);
 BTRFS_WORK_HELPER(delalloc_helper);
 BTRFS_WORK_HELPER(flush_delalloc_helper);
@@ -94,14 +110,15 @@ BTRFS_WORK_HELPER(scrubnc_helper);
 BTRFS_WORK_HELPER(scrubparity_helper);
 
 static struct __btrfs_workqueue *
-__btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active,
-                        int thresh)
+__btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, const char *name,
+                       unsigned int flags, int limit_active, int thresh)
 {
        struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL);
 
        if (!ret)
                return NULL;
 
+       ret->fs_info = fs_info;
        ret->limit_active = limit_active;
        atomic_set(&ret->pending, 0);
        if (thresh == 0)
@@ -143,7 +160,8 @@ __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active,
 static inline void
 __btrfs_destroy_workqueue(struct __btrfs_workqueue *wq);
 
-struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
+                                             const char *name,
                                              unsigned int flags,
                                              int limit_active,
                                              int thresh)
@@ -153,7 +171,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
        if (!ret)
                return NULL;
 
-       ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI,
+       ret->normal = __btrfs_alloc_workqueue(fs_info, name,
+                                             flags & ~WQ_HIGHPRI,
                                              limit_active, thresh);
        if (!ret->normal) {
                kfree(ret);
@@ -161,8 +180,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
        }
 
        if (flags & WQ_HIGHPRI) {
-               ret->high = __btrfs_alloc_workqueue(name, flags, limit_active,
-                                                   thresh);
+               ret->high = __btrfs_alloc_workqueue(fs_info, name, flags,
+                                                   limit_active, thresh);
                if (!ret->high) {
                        __btrfs_destroy_workqueue(ret->normal);
                        kfree(ret);
index ad4d0647d1a6c03b6b3ba9d1b4aae9a1ceff6df5..8e52484cd4615544a9d25687ba33f36a56c29d52 100644 (file)
@@ -21,6 +21,7 @@
 #define __BTRFS_ASYNC_THREAD_
 #include <linux/workqueue.h>
 
+struct btrfs_fs_info;
 struct btrfs_workqueue;
 /* Internal use only */
 struct __btrfs_workqueue;
@@ -67,7 +68,8 @@ BTRFS_WORK_HELPER_PROTO(scrubnc_helper);
 BTRFS_WORK_HELPER_PROTO(scrubparity_helper);
 
 
-struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
+                                             const char *name,
                                              unsigned int flags,
                                              int limit_active,
                                              int thresh);
@@ -80,4 +82,6 @@ void btrfs_queue_work(struct btrfs_workqueue *wq,
 void btrfs_destroy_workqueue(struct btrfs_workqueue *wq);
 void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
 void btrfs_set_work_high_priority(struct btrfs_work *work);
+struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work);
+struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq);
 #endif
index 8bb3509099e8fd802f871ecde0505ab5bd173005..2b88439c2ee864ffcec7a1e43f6e620a729bdbff 100644 (file)
@@ -139,7 +139,7 @@ int __init btrfs_prelim_ref_init(void)
        btrfs_prelim_ref_cache = kmem_cache_create("btrfs_prelim_ref",
                                        sizeof(struct __prelim_ref),
                                        0,
-                                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+                                       SLAB_MEM_SPREAD,
                                        NULL);
        if (!btrfs_prelim_ref_cache)
                return -ENOMEM;
@@ -361,7 +361,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
                goto out;
        }
 
-       if (btrfs_test_is_dummy_root(root)) {
+       if (btrfs_is_testing(fs_info)) {
                srcu_read_unlock(&fs_info->subvol_srcu, index);
                ret = -ENOENT;
                goto out;
index cefedabf0a92fd6aaa4c4986d4899fc9cac3b859..029db6e1105c7eb2bd42a4abc06a9f910bf9e346 100644 (file)
@@ -403,7 +403,10 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
                        }
 
                        ret = btrfs_map_bio(root, bio, 0, 1);
-                       BUG_ON(ret); /* -ENOMEM */
+                       if (ret) {
+                               bio->bi_error = ret;
+                               bio_endio(bio);
+                       }
 
                        bio_put(bio);
 
@@ -434,7 +437,10 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
        }
 
        ret = btrfs_map_bio(root, bio, 0, 1);
-       BUG_ON(ret); /* -ENOMEM */
+       if (ret) {
+               bio->bi_error = ret;
+               bio_endio(bio);
+       }
 
        bio_put(bio);
        return 0;
index a85cf7d2330981d606352cc8218167570db5507a..d1c56c94dd5abe2c4d007d55936699629009b604 100644 (file)
@@ -1153,14 +1153,14 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
 
        ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
 
        if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
                ret = btrfs_reloc_cow_block(trans, root, buf, cow);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        return ret;
                }
        }
@@ -1198,7 +1198,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
                if (last_ref) {
                        ret = tree_mod_log_free_eb(root->fs_info, buf);
                        if (ret) {
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                return ret;
                        }
                }
@@ -1505,7 +1505,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root,
                                   struct extent_buffer *buf)
 {
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(root->fs_info))
                return 0;
 
        /* ensure we can see the force_cow */
@@ -1771,6 +1771,14 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
        unsigned long map_len = 0;
        int err;
 
+       if (low > high) {
+               btrfs_err(eb->fs_info,
+                "%s: low (%d) > high (%d) eb %llu owner %llu level %d",
+                         __func__, low, high, eb->start,
+                         btrfs_header_owner(eb), btrfs_header_level(eb));
+               return -EINVAL;
+       }
+
        while (low < high) {
                mid = (low + high) / 2;
                offset = p + mid * item_size;
@@ -1858,7 +1866,6 @@ static void root_sub_used(struct btrfs_root *root, u32 size)
 
 /* given a node and slot number, this reads the blocks it points to.  The
  * extent buffer is returned with a reference taken (but unlocked).
- * NULL is returned on error.
  */
 static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root,
                                   struct extent_buffer *parent, int slot)
@@ -1866,19 +1873,16 @@ static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root,
        int level = btrfs_header_level(parent);
        struct extent_buffer *eb;
 
-       if (slot < 0)
-               return NULL;
-       if (slot >= btrfs_header_nritems(parent))
-               return NULL;
+       if (slot < 0 || slot >= btrfs_header_nritems(parent))
+               return ERR_PTR(-ENOENT);
 
        BUG_ON(level == 0);
 
        eb = read_tree_block(root, btrfs_node_blockptr(parent, slot),
                             btrfs_node_ptr_generation(parent, slot));
-       if (IS_ERR(eb) || !extent_buffer_uptodate(eb)) {
-               if (!IS_ERR(eb))
-                       free_extent_buffer(eb);
-               eb = NULL;
+       if (!IS_ERR(eb) && !extent_buffer_uptodate(eb)) {
+               free_extent_buffer(eb);
+               eb = ERR_PTR(-EIO);
        }
 
        return eb;
@@ -1931,8 +1935,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
                /* promote the child to a root */
                child = read_node_slot(root, mid, 0);
-               if (!child) {
-                       ret = -EROFS;
+               if (IS_ERR(child)) {
+                       ret = PTR_ERR(child);
                        btrfs_handle_fs_error(root->fs_info, ret, NULL);
                        goto enospc;
                }
@@ -1970,6 +1974,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                return 0;
 
        left = read_node_slot(root, parent, pslot - 1);
+       if (IS_ERR(left))
+               left = NULL;
+
        if (left) {
                btrfs_tree_lock(left);
                btrfs_set_lock_blocking(left);
@@ -1980,7 +1987,11 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                        goto enospc;
                }
        }
+
        right = read_node_slot(root, parent, pslot + 1);
+       if (IS_ERR(right))
+               right = NULL;
+
        if (right) {
                btrfs_tree_lock(right);
                btrfs_set_lock_blocking(right);
@@ -2135,6 +2146,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
                return 1;
 
        left = read_node_slot(root, parent, pslot - 1);
+       if (IS_ERR(left))
+               left = NULL;
 
        /* first, try to make some room in the middle buffer */
        if (left) {
@@ -2185,6 +2198,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
                free_extent_buffer(left);
        }
        right = read_node_slot(root, parent, pslot + 1);
+       if (IS_ERR(right))
+               right = NULL;
 
        /*
         * then try to empty the right most buffer into the middle
@@ -3240,7 +3255,7 @@ static int push_node_left(struct btrfs_trans_handle *trans,
        ret = tree_mod_log_eb_copy(root->fs_info, dst, src, dst_nritems, 0,
                                   push_items);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
        copy_extent_buffer(dst, src,
@@ -3315,7 +3330,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
        ret = tree_mod_log_eb_copy(root->fs_info, dst, src, 0,
                                   src_nritems - push_items, push_items);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
        copy_extent_buffer(dst, src,
@@ -3519,7 +3534,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
        ret = tree_mod_log_eb_copy(root->fs_info, split, c, 0,
                                   mid, c_nritems - mid);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
        copy_extent_buffer(split, c,
@@ -3773,7 +3788,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
        btrfs_assert_tree_locked(path->nodes[1]);
 
        right = read_node_slot(root, upper, slot + 1);
-       if (right == NULL)
+       /*
+        * slot + 1 is not valid or we fail to read the right node,
+        * no big deal, just return.
+        */
+       if (IS_ERR(right))
                return 1;
 
        btrfs_tree_lock(right);
@@ -4003,7 +4022,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
        btrfs_assert_tree_locked(path->nodes[1]);
 
        left = read_node_slot(root, path->nodes[1], slot - 1);
-       if (left == NULL)
+       /*
+        * slot - 1 is not valid or we fail to read the left node,
+        * no big deal, just return.
+        */
+       if (IS_ERR(left))
                return 1;
 
        btrfs_tree_lock(left);
@@ -5210,7 +5233,10 @@ find_next_key:
                }
                btrfs_set_path_blocking(path);
                cur = read_node_slot(root, cur, slot);
-               BUG_ON(!cur); /* -ENOMEM */
+               if (IS_ERR(cur)) {
+                       ret = PTR_ERR(cur);
+                       goto out;
+               }
 
                btrfs_tree_read_lock(cur);
 
@@ -5229,15 +5255,21 @@ out:
        return ret;
 }
 
-static void tree_move_down(struct btrfs_root *root,
+static int tree_move_down(struct btrfs_root *root,
                           struct btrfs_path *path,
                           int *level, int root_level)
 {
+       struct extent_buffer *eb;
+
        BUG_ON(*level == 0);
-       path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
-                                       path->slots[*level]);
+       eb = read_node_slot(root, path->nodes[*level], path->slots[*level]);
+       if (IS_ERR(eb))
+               return PTR_ERR(eb);
+
+       path->nodes[*level - 1] = eb;
        path->slots[*level - 1] = 0;
        (*level)--;
+       return 0;
 }
 
 static int tree_move_next_or_upnext(struct btrfs_root *root,
@@ -5282,8 +5314,7 @@ static int tree_advance(struct btrfs_root *root,
        if (*level == 0 || !allow_down) {
                ret = tree_move_next_or_upnext(root, path, level, root_level);
        } else {
-               tree_move_down(root, path, level, root_level);
-               ret = 0;
+               ret = tree_move_down(root, path, level, root_level);
        }
        if (ret >= 0) {
                if (*level == 0)
@@ -5457,8 +5488,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
                                        left_root_level,
                                        advance_left != ADVANCE_ONLY_NEXT,
                                        &left_key);
-                       if (ret < 0)
+                       if (ret == -1)
                                left_end_reached = ADVANCE;
+                       else if (ret < 0)
+                               goto out;
                        advance_left = 0;
                }
                if (advance_right && !right_end_reached) {
@@ -5466,8 +5499,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
                                        right_root_level,
                                        advance_right != ADVANCE_ONLY_NEXT,
                                        &right_key);
-                       if (ret < 0)
+                       if (ret == -1)
                                right_end_reached = ADVANCE;
+                       else if (ret < 0)
+                               goto out;
                        advance_right = 0;
                }
 
index 443fcc4021141f0ea5f5f9bbe5a1cdca0fb6f4ee..2fe8f89091a3097aa8e55bcee4a20c7b43ab1ca2 100644 (file)
@@ -117,6 +117,7 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
 #define BTRFS_FS_STATE_REMOUNTING      1
 #define BTRFS_FS_STATE_TRANS_ABORTED   2
 #define BTRFS_FS_STATE_DEV_REPLACING   3
+#define BTRFS_FS_STATE_DUMMY_FS_INFO   4
 
 #define BTRFS_BACKREF_REV_MAX          256
 #define BTRFS_BACKREF_REV_SHIFT                56
@@ -144,21 +145,6 @@ struct btrfs_header {
        u8 level;
 } __attribute__ ((__packed__));
 
-#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \
-                                     sizeof(struct btrfs_header)) / \
-                                    sizeof(struct btrfs_key_ptr))
-#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))
-#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->nodesize))
-#define BTRFS_FILE_EXTENT_INLINE_DATA_START            \
-               (offsetof(struct btrfs_file_extent_item, disk_bytenr))
-#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \
-                                       sizeof(struct btrfs_item) - \
-                                       BTRFS_FILE_EXTENT_INLINE_DATA_START)
-#define BTRFS_MAX_XATTR_SIZE(r)        (BTRFS_LEAF_DATA_SIZE(r) - \
-                                sizeof(struct btrfs_item) -\
-                                sizeof(struct btrfs_dir_item))
-
-
 /*
  * this is a very generous portion of the super block, giving us
  * room to translate 14 chunks with 3 stripes each.
@@ -1114,12 +1100,11 @@ struct btrfs_subvolume_writers {
 #define BTRFS_ROOT_REF_COWS            1
 #define BTRFS_ROOT_TRACK_DIRTY         2
 #define BTRFS_ROOT_IN_RADIX            3
-#define BTRFS_ROOT_DUMMY_ROOT          4
-#define BTRFS_ROOT_ORPHAN_ITEM_INSERTED        5
-#define BTRFS_ROOT_DEFRAG_RUNNING      6
-#define BTRFS_ROOT_FORCE_COW           7
-#define BTRFS_ROOT_MULTI_LOG_TASKS     8
-#define BTRFS_ROOT_DIRTY               9
+#define BTRFS_ROOT_ORPHAN_ITEM_INSERTED        4
+#define BTRFS_ROOT_DEFRAG_RUNNING      5
+#define BTRFS_ROOT_FORCE_COW           6
+#define BTRFS_ROOT_MULTI_LOG_TASKS     7
+#define BTRFS_ROOT_DIRTY               8
 
 /*
  * in ram representation of the tree.  extent_root is used for all allocations
@@ -1181,8 +1166,10 @@ struct btrfs_root {
 
        u64 highest_objectid;
 
+#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
        /* only used with CONFIG_BTRFS_FS_RUN_SANITY_TESTS is enabled */
        u64 alloc_bytenr;
+#endif
 
        u64 defrag_trans_start;
        struct btrfs_key defrag_progress;
@@ -1259,6 +1246,39 @@ struct btrfs_root {
        atomic_t qgroup_meta_rsv;
 };
 
+static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 blocksize)
+{
+       return blocksize - sizeof(struct btrfs_header);
+}
+
+static inline u32 BTRFS_LEAF_DATA_SIZE(const struct btrfs_root *root)
+{
+       return __BTRFS_LEAF_DATA_SIZE(root->nodesize);
+}
+
+static inline u32 BTRFS_MAX_ITEM_SIZE(const struct btrfs_root *root)
+{
+       return BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item);
+}
+
+static inline u32 BTRFS_NODEPTRS_PER_BLOCK(const struct btrfs_root *root)
+{
+       return BTRFS_LEAF_DATA_SIZE(root) / sizeof(struct btrfs_key_ptr);
+}
+
+#define BTRFS_FILE_EXTENT_INLINE_DATA_START            \
+               (offsetof(struct btrfs_file_extent_item, disk_bytenr))
+static inline u32 BTRFS_MAX_INLINE_DATA_SIZE(const struct btrfs_root *root)
+{
+       return BTRFS_MAX_ITEM_SIZE(root) -
+              BTRFS_FILE_EXTENT_INLINE_DATA_START;
+}
+
+static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_root *root)
+{
+       return BTRFS_MAX_ITEM_SIZE(root) - sizeof(struct btrfs_dir_item);
+}
+
 /*
  * Flags for mount options.
  *
@@ -1299,21 +1319,21 @@ struct btrfs_root {
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
 #define btrfs_raw_test_opt(o, opt)     ((o) & BTRFS_MOUNT_##opt)
-#define btrfs_test_opt(root, opt)      ((root)->fs_info->mount_opt & \
+#define btrfs_test_opt(fs_info, opt)   ((fs_info)->mount_opt & \
                                         BTRFS_MOUNT_##opt)
 
-#define btrfs_set_and_info(root, opt, fmt, args...)                    \
+#define btrfs_set_and_info(fs_info, opt, fmt, args...)                 \
 {                                                                      \
-       if (!btrfs_test_opt(root, opt))                                 \
-               btrfs_info(root->fs_info, fmt, ##args);                 \
-       btrfs_set_opt(root->fs_info->mount_opt, opt);                   \
+       if (!btrfs_test_opt(fs_info, opt))                              \
+               btrfs_info(fs_info, fmt, ##args);                       \
+       btrfs_set_opt(fs_info->mount_opt, opt);                         \
 }
 
-#define btrfs_clear_and_info(root, opt, fmt, args...)                  \
+#define btrfs_clear_and_info(fs_info, opt, fmt, args...)               \
 {                                                                      \
-       if (btrfs_test_opt(root, opt))                                  \
-               btrfs_info(root->fs_info, fmt, ##args);                 \
-       btrfs_clear_opt(root->fs_info->mount_opt, opt);                 \
+       if (btrfs_test_opt(fs_info, opt))                               \
+               btrfs_info(fs_info, fmt, ##args);                       \
+       btrfs_clear_opt(fs_info->mount_opt, opt);                       \
 }
 
 #ifdef CONFIG_BTRFS_DEBUG
@@ -1321,9 +1341,9 @@ static inline int
 btrfs_should_fragment_free_space(struct btrfs_root *root,
                                 struct btrfs_block_group_cache *block_group)
 {
-       return (btrfs_test_opt(root, FRAGMENT_METADATA) &&
+       return (btrfs_test_opt(root->fs_info, FRAGMENT_METADATA) &&
                block_group->flags & BTRFS_BLOCK_GROUP_METADATA) ||
-              (btrfs_test_opt(root, FRAGMENT_DATA) &&
+              (btrfs_test_opt(root->fs_info, FRAGMENT_DATA) &&
                block_group->flags &  BTRFS_BLOCK_GROUP_DATA);
 }
 #endif
@@ -2886,9 +2906,6 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
 int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq);
 
 /* root-item.c */
-int btrfs_find_root_ref(struct btrfs_root *tree_root,
-                       struct btrfs_path *path,
-                       u64 root_id, u64 ref_id);
 int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
                       struct btrfs_root *tree_root,
                       u64 root_id, u64 ref_id, u64 dirid, u64 sequence,
@@ -3362,23 +3379,23 @@ const char *btrfs_decode_error(int errno);
 
 __cold
 void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
-                              struct btrfs_root *root, const char *function,
+                              const char *function,
                               unsigned int line, int errno);
 
 /*
  * Call btrfs_abort_transaction as early as possible when an error condition is
  * detected, that way the exact line number is reported.
  */
-#define btrfs_abort_transaction(trans, root, errno)            \
+#define btrfs_abort_transaction(trans, errno)          \
 do {                                                           \
        /* Report first abort since mount */                    \
        if (!test_and_set_bit(BTRFS_FS_STATE_TRANS_ABORTED,     \
-                       &((root)->fs_info->fs_state))) {        \
+                       &((trans)->fs_info->fs_state))) {       \
                WARN(1, KERN_DEBUG                              \
                "BTRFS: Transaction aborted (error %d)\n",      \
                (errno));                                       \
        }                                                       \
-       __btrfs_abort_transaction((trans), (root), __func__,    \
+       __btrfs_abort_transaction((trans), __func__,            \
                                  __LINE__, (errno));           \
 } while (0)
 
@@ -3610,13 +3627,13 @@ static inline int btrfs_defrag_cancelled(struct btrfs_fs_info *fs_info)
 void btrfs_test_destroy_inode(struct inode *inode);
 #endif
 
-static inline int btrfs_test_is_dummy_root(struct btrfs_root *root)
+static inline int btrfs_is_testing(struct btrfs_fs_info *fs_info)
 {
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
-       if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state)))
+       if (unlikely(test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO,
+                             &fs_info->fs_state)))
                return 1;
 #endif
        return 0;
 }
-
 #endif
diff --git a/fs/btrfs/dedupe.h b/fs/btrfs/dedupe.h
new file mode 100644 (file)
index 0000000..83ebfe2
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef __BTRFS_DEDUPE__
+#define __BTRFS_DEDUPE__
+
+/* later in-band dedupe will expand this struct */
+struct btrfs_dedupe_hash;
+#endif
index dd3c040139a2ffb38957177b383790d2a6782e51..3eeb9cd8cfa57edc81bdeba91b1d37a3011d7bf9 100644 (file)
@@ -34,7 +34,7 @@ int __init btrfs_delayed_inode_init(void)
        delayed_node_cache = kmem_cache_create("btrfs_delayed_node",
                                        sizeof(struct btrfs_delayed_node),
                                        0,
-                                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+                                       SLAB_MEM_SPREAD,
                                        NULL);
        if (!delayed_node_cache)
                return -ENOMEM;
@@ -1170,7 +1170,7 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
                if (ret) {
                        btrfs_release_delayed_node(curr_node);
                        curr_node = NULL;
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        break;
                }
 
index 430b3689b112b745d531109f64f1dc3ac10bca78..b6d210e7a993fd67634b3523aa3e61a1121d31bd 100644 (file)
@@ -606,7 +606,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
                qrecord->num_bytes = num_bytes;
                qrecord->old_roots = NULL;
 
-               qexisting = btrfs_qgroup_insert_dirty_extent(delayed_refs,
+               qexisting = btrfs_qgroup_insert_dirty_extent(fs_info,
+                                                            delayed_refs,
                                                             qrecord);
                if (qexisting)
                        kfree(qrecord);
@@ -615,7 +616,7 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
        spin_lock_init(&head_ref->lock);
        mutex_init(&head_ref->mutex);
 
-       trace_add_delayed_ref_head(ref, head_ref, action);
+       trace_add_delayed_ref_head(fs_info, ref, head_ref, action);
 
        existing = htree_insert(&delayed_refs->href_root,
                                &head_ref->href_node);
@@ -682,7 +683,7 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
                ref->type = BTRFS_TREE_BLOCK_REF_KEY;
        full_ref->level = level;
 
-       trace_add_delayed_tree_ref(ref, full_ref, action);
+       trace_add_delayed_tree_ref(fs_info, ref, full_ref, action);
 
        ret = add_delayed_ref_tail_merge(trans, delayed_refs, head_ref, ref);
 
@@ -739,7 +740,7 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
        full_ref->objectid = owner;
        full_ref->offset = offset;
 
-       trace_add_delayed_data_ref(ref, full_ref, action);
+       trace_add_delayed_data_ref(fs_info, ref, full_ref, action);
 
        ret = add_delayed_ref_tail_merge(trans, delayed_refs, head_ref, ref);
 
@@ -940,28 +941,28 @@ int btrfs_delayed_ref_init(void)
        btrfs_delayed_ref_head_cachep = kmem_cache_create(
                                "btrfs_delayed_ref_head",
                                sizeof(struct btrfs_delayed_ref_head), 0,
-                               SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                               SLAB_MEM_SPREAD, NULL);
        if (!btrfs_delayed_ref_head_cachep)
                goto fail;
 
        btrfs_delayed_tree_ref_cachep = kmem_cache_create(
                                "btrfs_delayed_tree_ref",
                                sizeof(struct btrfs_delayed_tree_ref), 0,
-                               SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                               SLAB_MEM_SPREAD, NULL);
        if (!btrfs_delayed_tree_ref_cachep)
                goto fail;
 
        btrfs_delayed_data_ref_cachep = kmem_cache_create(
                                "btrfs_delayed_data_ref",
                                sizeof(struct btrfs_delayed_data_ref), 0,
-                               SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                               SLAB_MEM_SPREAD, NULL);
        if (!btrfs_delayed_data_ref_cachep)
                goto fail;
 
        btrfs_delayed_extent_op_cachep = kmem_cache_create(
                                "btrfs_delayed_extent_op",
                                sizeof(struct btrfs_delayed_extent_op), 0,
-                               SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                               SLAB_MEM_SPREAD, NULL);
        if (!btrfs_delayed_extent_op_cachep)
                goto fail;
 
index 63ef9cdf0144dd00f226d1a98069f58b916f2dc4..e9bbff3c0029c57814207014c5d29c4b725a73b3 100644 (file)
@@ -142,7 +142,7 @@ no_valid_dev_replace_entry_found:
                 * missing
                 */
                if (!dev_replace->srcdev &&
-                   !btrfs_test_opt(dev_root, DEGRADED)) {
+                   !btrfs_test_opt(dev_root->fs_info, DEGRADED)) {
                        ret = -EIO;
                        btrfs_warn(fs_info,
                           "cannot mount because device replace operation is ongoing and");
@@ -151,7 +151,7 @@ no_valid_dev_replace_entry_found:
                           src_devid);
                }
                if (!dev_replace->tgtdev &&
-                   !btrfs_test_opt(dev_root, DEGRADED)) {
+                   !btrfs_test_opt(dev_root->fs_info, DEGRADED)) {
                        ret = -EIO;
                        btrfs_warn(fs_info,
                           "cannot mount because device replace operation is ongoing and");
index 9a726ded2c6d150e73bd2719a09cb95a8634ab57..87dad552e39ae13ea2533c4a5718a5af635bcbee 100644 (file)
@@ -101,7 +101,7 @@ int __init btrfs_end_io_wq_init(void)
        btrfs_end_io_wq_cache = kmem_cache_create("btrfs_end_io_wq",
                                        sizeof(struct btrfs_end_io_wq),
                                        0,
-                                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+                                       SLAB_MEM_SPREAD,
                                        NULL);
        if (!btrfs_end_io_wq_cache)
                return -ENOMEM;
@@ -1140,7 +1140,7 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info,
 struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
                                                 u64 bytenr)
 {
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(root->fs_info))
                return alloc_test_extent_buffer(root->fs_info, bytenr,
                                root->nodesize);
        return alloc_extent_buffer(root->fs_info, bytenr);
@@ -1227,6 +1227,7 @@ static void __setup_root(u32 nodesize, u32 sectorsize, u32 stripesize,
                         struct btrfs_root *root, struct btrfs_fs_info *fs_info,
                         u64 objectid)
 {
+       bool dummy = test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
        root->node = NULL;
        root->commit_root = NULL;
        root->sectorsize = sectorsize;
@@ -1281,14 +1282,14 @@ static void __setup_root(u32 nodesize, u32 sectorsize, u32 stripesize,
        root->log_transid = 0;
        root->log_transid_committed = -1;
        root->last_log_commit = 0;
-       if (fs_info)
+       if (!dummy)
                extent_io_tree_init(&root->dirty_log_pages,
                                     fs_info->btree_inode->i_mapping);
 
        memset(&root->root_key, 0, sizeof(root->root_key));
        memset(&root->root_item, 0, sizeof(root->root_item));
        memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
-       if (fs_info)
+       if (!dummy)
                root->defrag_trans_start = fs_info->generation;
        else
                root->defrag_trans_start = 0;
@@ -1309,17 +1310,20 @@ static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info,
 
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
 /* Should only be used by the testing infrastructure */
-struct btrfs_root *btrfs_alloc_dummy_root(u32 sectorsize, u32 nodesize)
+struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info,
+                                         u32 sectorsize, u32 nodesize)
 {
        struct btrfs_root *root;
 
-       root = btrfs_alloc_root(NULL, GFP_KERNEL);
+       if (!fs_info)
+               return ERR_PTR(-EINVAL);
+
+       root = btrfs_alloc_root(fs_info, GFP_KERNEL);
        if (!root)
                return ERR_PTR(-ENOMEM);
        /* We don't use the stripesize in selftest, set it as sectorsize */
-       __setup_root(nodesize, sectorsize, sectorsize, root, NULL,
+       __setup_root(nodesize, sectorsize, sectorsize, root, fs_info,
                        BTRFS_ROOT_TREE_OBJECTID);
-       set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state);
        root->alloc_bytenr = 0;
 
        return root;
@@ -1594,14 +1598,14 @@ int btrfs_init_fs_root(struct btrfs_root *root)
 
        ret = get_anon_bdev(&root->anon_dev);
        if (ret)
-               goto free_writers;
+               goto fail;
 
        mutex_lock(&root->objectid_mutex);
        ret = btrfs_find_highest_objectid(root,
                                        &root->highest_objectid);
        if (ret) {
                mutex_unlock(&root->objectid_mutex);
-               goto free_root_dev;
+               goto fail;
        }
 
        ASSERT(root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
@@ -1609,14 +1613,8 @@ int btrfs_init_fs_root(struct btrfs_root *root)
        mutex_unlock(&root->objectid_mutex);
 
        return 0;
-
-free_root_dev:
-       free_anon_bdev(root->anon_dev);
-free_writers:
-       btrfs_free_subvolume_writers(root->subv_writers);
 fail:
-       kfree(root->free_ino_ctl);
-       kfree(root->free_ino_pinned);
+       /* the caller is responsible to call free_fs_root */
        return ret;
 }
 
@@ -2310,17 +2308,19 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
        unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND;
 
        fs_info->workers =
-               btrfs_alloc_workqueue("worker", flags | WQ_HIGHPRI,
-                                     max_active, 16);
+               btrfs_alloc_workqueue(fs_info, "worker",
+                                     flags | WQ_HIGHPRI, max_active, 16);
 
        fs_info->delalloc_workers =
-               btrfs_alloc_workqueue("delalloc", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "delalloc",
+                                     flags, max_active, 2);
 
        fs_info->flush_workers =
-               btrfs_alloc_workqueue("flush_delalloc", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "flush_delalloc",
+                                     flags, max_active, 0);
 
        fs_info->caching_workers =
-               btrfs_alloc_workqueue("cache", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0);
 
        /*
         * a higher idle thresh on the submit workers makes it much more
@@ -2328,41 +2328,48 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
         * devices
         */
        fs_info->submit_workers =
-               btrfs_alloc_workqueue("submit", flags,
+               btrfs_alloc_workqueue(fs_info, "submit", flags,
                                      min_t(u64, fs_devices->num_devices,
                                            max_active), 64);
 
        fs_info->fixup_workers =
-               btrfs_alloc_workqueue("fixup", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0);
 
        /*
         * endios are largely parallel and should have a very
         * low idle thresh
         */
        fs_info->endio_workers =
-               btrfs_alloc_workqueue("endio", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio", flags, max_active, 4);
        fs_info->endio_meta_workers =
-               btrfs_alloc_workqueue("endio-meta", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio-meta", flags,
+                                     max_active, 4);
        fs_info->endio_meta_write_workers =
-               btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "endio-meta-write", flags,
+                                     max_active, 2);
        fs_info->endio_raid56_workers =
-               btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio-raid56", flags,
+                                     max_active, 4);
        fs_info->endio_repair_workers =
-               btrfs_alloc_workqueue("endio-repair", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "endio-repair", flags, 1, 0);
        fs_info->rmw_workers =
-               btrfs_alloc_workqueue("rmw", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "rmw", flags, max_active, 2);
        fs_info->endio_write_workers =
-               btrfs_alloc_workqueue("endio-write", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "endio-write", flags,
+                                     max_active, 2);
        fs_info->endio_freespace_worker =
-               btrfs_alloc_workqueue("freespace-write", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "freespace-write", flags,
+                                     max_active, 0);
        fs_info->delayed_workers =
-               btrfs_alloc_workqueue("delayed-meta", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "delayed-meta", flags,
+                                     max_active, 0);
        fs_info->readahead_workers =
-               btrfs_alloc_workqueue("readahead", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "readahead", flags,
+                                     max_active, 2);
        fs_info->qgroup_rescan_workers =
-               btrfs_alloc_workqueue("qgroup-rescan", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0);
        fs_info->extent_workers =
-               btrfs_alloc_workqueue("extent-refs", flags,
+               btrfs_alloc_workqueue(fs_info, "extent-refs", flags,
                                      min_t(u64, fs_devices->num_devices,
                                            max_active), 8);
 
@@ -3010,8 +3017,8 @@ retry_root_backup:
        if (IS_ERR(fs_info->transaction_kthread))
                goto fail_cleaner;
 
-       if (!btrfs_test_opt(tree_root, SSD) &&
-           !btrfs_test_opt(tree_root, NOSSD) &&
+       if (!btrfs_test_opt(tree_root->fs_info, SSD) &&
+           !btrfs_test_opt(tree_root->fs_info, NOSSD) &&
            !fs_info->fs_devices->rotating) {
                btrfs_info(fs_info, "detected SSD devices, enabling SSD mode");
                btrfs_set_opt(fs_info->mount_opt, SSD);
@@ -3024,9 +3031,9 @@ retry_root_backup:
        btrfs_apply_pending_changes(fs_info);
 
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
-       if (btrfs_test_opt(tree_root, CHECK_INTEGRITY)) {
+       if (btrfs_test_opt(tree_root->fs_info, CHECK_INTEGRITY)) {
                ret = btrfsic_mount(tree_root, fs_devices,
-                                   btrfs_test_opt(tree_root,
+                                   btrfs_test_opt(tree_root->fs_info,
                                        CHECK_INTEGRITY_INCLUDING_EXTENT_DATA) ?
                                    1 : 0,
                                    fs_info->check_integrity_print_mask);
@@ -3042,7 +3049,7 @@ retry_root_backup:
 
        /* do not make disk changes in broken FS or nologreplay is given */
        if (btrfs_super_log_root(disk_super) != 0 &&
-           !btrfs_test_opt(tree_root, NOLOGREPLAY)) {
+           !btrfs_test_opt(tree_root->fs_info, NOLOGREPLAY)) {
                ret = btrfs_replay_log(fs_info, fs_devices);
                if (ret) {
                        err = ret;
@@ -3083,7 +3090,7 @@ retry_root_backup:
        if (sb->s_flags & MS_RDONLY)
                return 0;
 
-       if (btrfs_test_opt(tree_root, FREE_SPACE_TREE) &&
+       if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) &&
            !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
                btrfs_info(fs_info, "creating free space tree");
                ret = btrfs_create_free_space_tree(fs_info);
@@ -3120,7 +3127,7 @@ retry_root_backup:
 
        btrfs_qgroup_rescan_resume(fs_info);
 
-       if (btrfs_test_opt(tree_root, CLEAR_CACHE) &&
+       if (btrfs_test_opt(tree_root->fs_info, CLEAR_CACHE) &&
            btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
                btrfs_info(fs_info, "clearing free space tree");
                ret = btrfs_clear_free_space_tree(fs_info);
@@ -3141,7 +3148,7 @@ retry_root_backup:
                        close_ctree(tree_root);
                        return ret;
                }
-       } else if (btrfs_test_opt(tree_root, RESCAN_UUID_TREE) ||
+       } else if (btrfs_test_opt(tree_root->fs_info, RESCAN_UUID_TREE) ||
                   fs_info->generation !=
                                btrfs_super_uuid_tree_generation(disk_super)) {
                btrfs_info(fs_info, "checking UUID tree");
@@ -3218,7 +3225,7 @@ fail:
        return err;
 
 recovery_tree_root:
-       if (!btrfs_test_opt(tree_root, USEBACKUPROOT))
+       if (!btrfs_test_opt(tree_root->fs_info, USEBACKUPROOT))
                goto fail_tree_roots;
 
        free_root_pointers(fs_info, 0);
@@ -3634,7 +3641,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
        int total_errors = 0;
        u64 flags;
 
-       do_barriers = !btrfs_test_opt(root, NOBARRIER);
+       do_barriers = !btrfs_test_opt(root->fs_info, NOBARRIER);
        backup_super_roots(root->fs_info);
 
        sb = root->fs_info->super_for_commit;
@@ -3918,7 +3925,7 @@ void close_ctree(struct btrfs_root *root)
        iput(fs_info->btree_inode);
 
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
-       if (btrfs_test_opt(root, CHECK_INTEGRITY))
+       if (btrfs_test_opt(root->fs_info, CHECK_INTEGRITY))
                btrfsic_unmount(root, fs_info->fs_devices);
 #endif
 
index dbf3e1aab69e904a75a6828bbcb6f955166c8b25..b3207a0e09f7966703e1d130e250f05f610b2a3f 100644 (file)
@@ -90,7 +90,8 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 void btrfs_free_fs_root(struct btrfs_root *root);
 
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
-struct btrfs_root *btrfs_alloc_dummy_root(u32 sectorsize, u32 nodesize);
+struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info,
+                                         u32 sectorsize, u32 nodesize);
 #endif
 
 /*
index e9376b1657e25ff18f72d8f41bc37e1d520d3f01..61b494e8e604e9e80f1c46c581ede724f56ea050 100644 (file)
@@ -2180,7 +2180,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                                    path, bytenr, parent, root_objectid,
                                    owner, offset, refs_to_add);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 out:
        btrfs_free_path(path);
        return ret;
@@ -2204,7 +2204,7 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
        ins.type = BTRFS_EXTENT_ITEM_KEY;
 
        ref = btrfs_delayed_node_to_data_ref(node);
-       trace_run_delayed_data_ref(node, ref, node->action);
+       trace_run_delayed_data_ref(root->fs_info, node, ref, node->action);
 
        if (node->type == BTRFS_SHARED_DATA_REF_KEY)
                parent = ref->parent;
@@ -2359,7 +2359,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
                                                 SKINNY_METADATA);
 
        ref = btrfs_delayed_node_to_tree_ref(node);
-       trace_run_delayed_tree_ref(node, ref, node->action);
+       trace_run_delayed_tree_ref(root->fs_info, node, ref, node->action);
 
        if (node->type == BTRFS_SHARED_BLOCK_REF_KEY)
                parent = ref->parent;
@@ -2423,7 +2423,8 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
                 */
                BUG_ON(extent_op);
                head = btrfs_delayed_node_to_head(node);
-               trace_run_delayed_ref_head(node, head, node->action);
+               trace_run_delayed_ref_head(root->fs_info, node, head,
+                                          node->action);
 
                if (insert_reserved) {
                        btrfs_pin_extent(root, node->bytenr,
@@ -2778,7 +2779,7 @@ u64 btrfs_csum_bytes_to_leaves(struct btrfs_root *root, u64 csum_bytes)
        u64 num_csums_per_leaf;
        u64 num_csums;
 
-       csum_size = BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item);
+       csum_size = BTRFS_MAX_ITEM_SIZE(root);
        num_csums_per_leaf = div64_u64(csum_size,
                        (u64)btrfs_super_csum_size(root->fs_info->super_copy));
        num_csums = div64_u64(csum_bytes, root->sectorsize);
@@ -2970,7 +2971,7 @@ again:
        trans->can_flush_pending_bgs = false;
        ret = __btrfs_run_delayed_refs(trans, root, count);
        if (ret < 0) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
 
@@ -3234,7 +3235,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
                            u64, u64, u64, u64, u64, u64);
 
 
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(root->fs_info))
                return 0;
 
        ref_root = btrfs_header_owner(buf);
@@ -3429,7 +3430,7 @@ again:
                 * transaction, this only happens in really bad situations
                 * anyway.
                 */
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_put;
        }
        WARN_ON(ret);
@@ -3447,7 +3448,7 @@ again:
 
        spin_lock(&block_group->lock);
        if (block_group->cached != BTRFS_CACHE_FINISHED ||
-           !btrfs_test_opt(root, SPACE_CACHE)) {
+           !btrfs_test_opt(root->fs_info, SPACE_CACHE)) {
                /*
                 * don't bother trying to write stuff out _if_
                 * a) we're not cached,
@@ -3524,7 +3525,7 @@ int btrfs_setup_space_cache(struct btrfs_trans_handle *trans,
        struct btrfs_path *path;
 
        if (list_empty(&cur_trans->dirty_bgs) ||
-           !btrfs_test_opt(root, SPACE_CACHE))
+           !btrfs_test_opt(root->fs_info, SPACE_CACHE))
                return 0;
 
        path = btrfs_alloc_path();
@@ -3669,7 +3670,7 @@ again:
                                }
                                spin_unlock(&cur_trans->dirty_bgs_lock);
                        } else if (ret) {
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                        }
                }
 
@@ -3815,7 +3816,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                                            cache);
                        }
                        if (ret)
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                }
 
                /* if its not on the io list, we need to put the block group */
@@ -4443,7 +4444,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans,
        thresh = btrfs_calc_trunc_metadata_size(root, num_devs) +
                btrfs_calc_trans_metadata_size(root, 1);
 
-       if (left < thresh && btrfs_test_opt(root, ENOSPC_DEBUG)) {
+       if (left < thresh && btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
                btrfs_info(root->fs_info, "left=%llu, need=%llu, flags=%llu",
                        left, thresh, type);
                dump_space_info(info, 0, 0);
@@ -4588,7 +4589,7 @@ out:
         */
        if (trans->can_flush_pending_bgs &&
            trans->chunk_bytes_reserved >= (u64)SZ_2M) {
-               btrfs_create_pending_block_groups(trans, trans->root);
+               btrfs_create_pending_block_groups(trans, extent_root);
                btrfs_trans_release_chunk_metadata(trans);
        }
        return ret;
@@ -5729,7 +5730,7 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
  */
 void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
 {
-       struct btrfs_fs_info *fs_info = trans->root->fs_info;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
 
        if (!trans->chunk_bytes_reserved)
                return;
@@ -6100,7 +6101,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
        if (dropped > 0)
                to_free += btrfs_calc_trans_metadata_size(root, dropped);
 
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(root->fs_info))
                return;
 
        trace_btrfs_space_reservation(root->fs_info, "delalloc",
@@ -6215,7 +6216,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                spin_lock(&cache->space_info->lock);
                spin_lock(&cache->lock);
 
-               if (btrfs_test_opt(root, SPACE_CACHE) &&
+               if (btrfs_test_opt(root->fs_info, SPACE_CACHE) &&
                    cache->disk_cache_state < BTRFS_DC_CLEAR)
                        cache->disk_cache_state = BTRFS_DC_CLEAR;
 
@@ -6597,7 +6598,7 @@ fetch_cluster_info(struct btrfs_root *root, struct btrfs_space_info *space_info,
                   u64 *empty_cluster)
 {
        struct btrfs_free_cluster *ret = NULL;
-       bool ssd = btrfs_test_opt(root, SSD);
+       bool ssd = btrfs_test_opt(root->fs_info, SSD);
 
        *empty_cluster = 0;
        if (btrfs_mixed_space_info(space_info))
@@ -6742,7 +6743,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
                        break;
                }
 
-               if (btrfs_test_opt(root, DISCARD))
+               if (btrfs_test_opt(root->fs_info, DISCARD))
                        ret = btrfs_discard_extent(root, start,
                                                   end + 1 - start, NULL);
 
@@ -6880,7 +6881,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                                    NULL, refs_to_drop,
                                                    is_data, &last_ref);
                        if (ret) {
-                               btrfs_abort_transaction(trans, extent_root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                        btrfs_release_path(path);
@@ -6929,7 +6930,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                                         path->nodes[0]);
                        }
                        if (ret < 0) {
-                               btrfs_abort_transaction(trans, extent_root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                        extent_slot = path->slots[0];
@@ -6940,10 +6941,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                        "unable to find ref byte nr %llu parent %llu root %llu  owner %llu offset %llu",
                        bytenr, parent, root_objectid, owner_objectid,
                        owner_offset);
-               btrfs_abort_transaction(trans, extent_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        } else {
-               btrfs_abort_transaction(trans, extent_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -6955,7 +6956,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                ret = convert_extent_item_v0(trans, extent_root, path,
                                             owner_objectid, 0);
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -6974,7 +6975,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                        btrfs_print_leaf(extent_root, path->nodes[0]);
                }
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -6999,7 +7000,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                btrfs_err(info, "trying to drop %d refs but we only have %Lu "
                          "for bytenr %Lu", refs_to_drop, refs, bytenr);
                ret = -EINVAL;
-               btrfs_abort_transaction(trans, extent_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
        refs -= refs_to_drop;
@@ -7022,7 +7023,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                                    iref, refs_to_drop,
                                                    is_data, &last_ref);
                        if (ret) {
-                               btrfs_abort_transaction(trans, extent_root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                }
@@ -7045,7 +7046,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
                                      num_to_del);
                if (ret) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
                btrfs_release_path(path);
@@ -7053,7 +7054,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                if (is_data) {
                        ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
                        if (ret) {
-                               btrfs_abort_transaction(trans, extent_root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                }
@@ -7061,13 +7062,13 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                ret = add_to_free_space_tree(trans, root->fs_info, bytenr,
                                             num_bytes);
                if (ret) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
                ret = update_block_group(trans, root, bytenr, num_bytes, 0);
                if (ret) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
        }
@@ -7216,7 +7217,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        int ret;
        struct btrfs_fs_info *fs_info = root->fs_info;
 
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(fs_info))
                return 0;
 
        add_pinned_bytes(root->fs_info, num_bytes, owner, root_objectid);
@@ -7851,8 +7852,7 @@ loop:
                         * can do more things.
                         */
                        if (ret < 0 && ret != -ENOSPC)
-                               btrfs_abort_transaction(trans,
-                                                       root, ret);
+                               btrfs_abort_transaction(trans, ret);
                        else
                                ret = 0;
                        if (!exist)
@@ -7906,8 +7906,8 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
        printk(KERN_INFO "BTRFS: space_info %llu has %llu free, is %sfull\n",
               info->flags,
               info->total_bytes - info->bytes_used - info->bytes_pinned -
-              info->bytes_reserved - info->bytes_readonly,
-              (info->full) ? "" : "not ");
+              info->bytes_reserved - info->bytes_readonly -
+              info->bytes_may_use, (info->full) ? "" : "not ");
        printk(KERN_INFO "BTRFS: space_info total=%llu, used=%llu, pinned=%llu, "
               "reserved=%llu, may_use=%llu, readonly=%llu\n",
               info->total_bytes, info->bytes_used, info->bytes_pinned,
@@ -7961,7 +7961,7 @@ again:
                        if (num_bytes == min_alloc_size)
                                final_tried = true;
                        goto again;
-               } else if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
+               } else if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
                        struct btrfs_space_info *sinfo;
 
                        sinfo = __find_space_info(root->fs_info, flags);
@@ -7992,7 +7992,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
        if (pin)
                pin_down_extent(root, cache, start, len, 1);
        else {
-               if (btrfs_test_opt(root, DISCARD))
+               if (btrfs_test_opt(root->fs_info, DISCARD))
                        ret = btrfs_discard_extent(root, start, len, NULL);
                btrfs_add_free_space(cache, start, len);
                btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc);
@@ -8300,7 +8300,7 @@ again:
                goto again;
        }
 
-       if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
+       if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
                static DEFINE_RATELIMIT_STATE(_rs,
                                DEFAULT_RATELIMIT_INTERVAL * 10,
                                /*DEFAULT_RATELIMIT_BURST*/ 1);
@@ -8354,13 +8354,15 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
        bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
                                                 SKINNY_METADATA);
 
-       if (btrfs_test_is_dummy_root(root)) {
+#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+       if (btrfs_is_testing(root->fs_info)) {
                buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr,
                                            level);
                if (!IS_ERR(buf))
                        root->alloc_bytenr += blocksize;
                return buf;
        }
+#endif
 
        block_rsv = use_block_rsv(trans, root, blocksize);
        if (IS_ERR(block_rsv))
@@ -8540,7 +8542,8 @@ static int record_one_subtree_extent(struct btrfs_trans_handle *trans,
 
        delayed_refs = &trans->transaction->delayed_refs;
        spin_lock(&delayed_refs->lock);
-       if (btrfs_qgroup_insert_dirty_extent(delayed_refs, qrecord))
+       if (btrfs_qgroup_insert_dirty_extent(trans->fs_info,
+                                            delayed_refs, qrecord))
                kfree(qrecord);
        spin_unlock(&delayed_refs->lock);
 
@@ -9325,7 +9328,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
                                                &root->root_key,
                                                root_item);
                        if (ret) {
-                               btrfs_abort_transaction(trans, tree_root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                err = ret;
                                goto out_end_trans;
                        }
@@ -9352,7 +9355,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
 
        ret = btrfs_del_root(trans, tree_root, &root->root_key);
        if (ret) {
-               btrfs_abort_transaction(trans, tree_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_end_trans;
        }
 
@@ -9360,7 +9363,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
                ret = btrfs_find_root(tree_root, &root->root_key, path,
                                      NULL, NULL);
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, tree_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        err = ret;
                        goto out_end_trans;
                } else if (ret > 0) {
@@ -9731,7 +9734,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
        int full = 0;
        int ret = 0;
 
-       debug = btrfs_test_opt(root, ENOSPC_DEBUG);
+       debug = btrfs_test_opt(root->fs_info, ENOSPC_DEBUG);
 
        block_group = btrfs_lookup_block_group(root->fs_info, bytenr);
 
@@ -9887,7 +9890,22 @@ static int find_first_block_group(struct btrfs_root *root,
 
                if (found_key.objectid >= key->objectid &&
                    found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
-                       ret = 0;
+                       struct extent_map_tree *em_tree;
+                       struct extent_map *em;
+
+                       em_tree = &root->fs_info->mapping_tree.map_tree;
+                       read_lock(&em_tree->lock);
+                       em = lookup_extent_mapping(em_tree, found_key.objectid,
+                                                  found_key.offset);
+                       read_unlock(&em_tree->lock);
+                       if (!em) {
+                               btrfs_err(root->fs_info,
+                       "logical %llu len %llu found bg but no related chunk",
+                                         found_key.objectid, found_key.offset);
+                               ret = -ENOENT;
+                       } else {
+                               ret = 0;
+                       }
                        goto out;
                }
                path->slots[0]++;
@@ -10129,10 +10147,10 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        path->reada = READA_FORWARD;
 
        cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
-       if (btrfs_test_opt(root, SPACE_CACHE) &&
+       if (btrfs_test_opt(root->fs_info, SPACE_CACHE) &&
            btrfs_super_generation(root->fs_info->super_copy) != cache_gen)
                need_clear = 1;
-       if (btrfs_test_opt(root, CLEAR_CACHE))
+       if (btrfs_test_opt(root->fs_info, CLEAR_CACHE))
                need_clear = 1;
 
        while (1) {
@@ -10163,7 +10181,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                         * b) Setting 'dirty flag' makes sure that we flush
                         *    the new space cache info onto disk.
                         */
-                       if (btrfs_test_opt(root, SPACE_CACHE))
+                       if (btrfs_test_opt(root->fs_info, SPACE_CACHE))
                                cache->disk_cache_state = BTRFS_DC_CLEAR;
                }
 
@@ -10305,11 +10323,11 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
                ret = btrfs_insert_item(trans, extent_root, &key, &item,
                                        sizeof(item));
                if (ret)
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                ret = btrfs_finish_chunk_alloc(trans, extent_root,
                                               key.objectid, key.offset);
                if (ret)
-                       btrfs_abort_transaction(trans, extent_root, ret);
+                       btrfs_abort_transaction(trans, ret);
                add_block_group_free_space(trans, root->fs_info, block_group);
                /* already aborted the transaction if it failed. */
 next:
@@ -10622,7 +10640,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        spin_lock(&block_group->space_info->lock);
        list_del_init(&block_group->ro_list);
 
-       if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
+       if (btrfs_test_opt(root->fs_info, ENOSPC_DEBUG)) {
                WARN_ON(block_group->space_info->total_bytes
                        < block_group->key.offset);
                WARN_ON(block_group->space_info->bytes_readonly
@@ -10890,7 +10908,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                spin_unlock(&space_info->lock);
 
                /* DISCARD can flip during remount */
-               trimming = btrfs_test_opt(root, DISCARD);
+               trimming = btrfs_test_opt(root->fs_info, DISCARD);
 
                /* Implicit trim during transaction commit. */
                if (trimming)
index cee4cb99b8ce7b436c60f394b518e22256ecbf97..80d92839d119548f1c02bcb22e6b45263c85ce80 100644 (file)
@@ -163,13 +163,13 @@ int __init extent_io_init(void)
 {
        extent_state_cache = kmem_cache_create("btrfs_extent_state",
                        sizeof(struct extent_state), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_MEM_SPREAD, NULL);
        if (!extent_state_cache)
                return -ENOMEM;
 
        extent_buffer_cache = kmem_cache_create("btrfs_extent_buffer",
                        sizeof(struct extent_buffer), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_MEM_SPREAD, NULL);
        if (!extent_buffer_cache)
                goto free_state_cache;
 
@@ -2756,7 +2756,6 @@ static int merge_bio(struct extent_io_tree *tree, struct page *page,
        if (tree->ops && tree->ops->merge_bio_hook)
                ret = tree->ops->merge_bio_hook(page, offset, size, bio,
                                                bio_flags);
-       BUG_ON(ret < 0);
        return ret;
 
 }
@@ -2879,6 +2878,7 @@ __get_extent_map(struct inode *inode, struct page *page, size_t pg_offset,
  * into the tree that are removed when the IO is done (by the end_io
  * handlers)
  * XXX JDM: This needs looking at to ensure proper page locking
+ * return 0 on success, otherwise return error
  */
 static int __do_readpage(struct extent_io_tree *tree,
                         struct page *page,
@@ -2900,7 +2900,7 @@ static int __do_readpage(struct extent_io_tree *tree,
        sector_t sector;
        struct extent_map *em;
        struct block_device *bdev;
-       int ret;
+       int ret = 0;
        int nr = 0;
        size_t pg_offset = 0;
        size_t iosize;
@@ -3081,6 +3081,7 @@ static int __do_readpage(struct extent_io_tree *tree,
                } else {
                        SetPageError(page);
                        unlock_extent(tree, cur, cur + iosize - 1);
+                       goto out;
                }
                cur = cur + iosize;
                pg_offset += iosize;
@@ -3091,7 +3092,7 @@ out:
                        SetPageUptodate(page);
                unlock_page(page);
        }
-       return 0;
+       return ret;
 }
 
 static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
@@ -5230,14 +5231,31 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
        atomic_set(&eb->io_pages, num_reads);
        for (i = start_i; i < num_pages; i++) {
                page = eb->pages[i];
+
                if (!PageUptodate(page)) {
+                       if (ret) {
+                               atomic_dec(&eb->io_pages);
+                               unlock_page(page);
+                               continue;
+                       }
+
                        ClearPageError(page);
                        err = __extent_read_full_page(tree, page,
                                                      get_extent, &bio,
                                                      mirror_num, &bio_flags,
                                                      REQ_META);
-                       if (err)
+                       if (err) {
                                ret = err;
+                               /*
+                                * We use &bio in above __extent_read_full_page,
+                                * so we ensure that if it returns error, the
+                                * current page fails to add itself to bio and
+                                * it's been unlocked.
+                                *
+                                * We must dec io_pages by ourselves.
+                                */
+                               atomic_dec(&eb->io_pages);
+                       }
                } else {
                        unlock_page(page);
                }
index e0715fcfb11ee9ee3582510d037fa32a887616ea..26f9ac719d20b4bff1a6b0a456ca45dd1752b4c7 100644 (file)
@@ -13,7 +13,7 @@ int __init extent_map_init(void)
 {
        extent_map_cache = kmem_cache_create("btrfs_extent_map",
                        sizeof(struct extent_map), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_MEM_SPREAD, NULL);
        if (!extent_map_cache)
                return -ENOMEM;
        return 0;
index 62a81ee13a5f649f3d17139f8069395dbd512527..d0d571c47d33b8e876aa1906097678350a2ef74b 100644 (file)
@@ -250,7 +250,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
                                                offset + root->sectorsize - 1,
                                                EXTENT_NODATASUM);
                                } else {
-                                       btrfs_info(BTRFS_I(inode)->root->fs_info,
+                                       btrfs_info_rl(BTRFS_I(inode)->root->fs_info,
                                                   "no csum found for inode %llu start %llu",
                                               btrfs_ino(inode), offset);
                                }
@@ -699,7 +699,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
                         */
                        ret = btrfs_split_item(trans, root, path, &key, offset);
                        if (ret && ret != -EAGAIN) {
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
 
index bcfb4a27ddd4f82bda72bb789ba1fbdf5804f3a3..9404121fd5f7b44f165c6f76c856548cf5722aff 100644 (file)
@@ -132,7 +132,7 @@ static int __btrfs_add_inode_defrag(struct inode *inode,
 
 static inline int __need_auto_defrag(struct btrfs_root *root)
 {
-       if (!btrfs_test_opt(root, AUTO_DEFRAG))
+       if (!btrfs_test_opt(root->fs_info, AUTO_DEFRAG))
                return 0;
 
        if (btrfs_fs_closing(root->fs_info))
@@ -950,7 +950,7 @@ delete_extent_item:
                        ret = btrfs_del_items(trans, root, path, del_slot,
                                              del_nr);
                        if (ret) {
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                break;
                        }
 
@@ -974,7 +974,7 @@ delete_extent_item:
                path->slots[0] = del_slot;
                ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
                if (ret)
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
        }
 
        leaf = path->nodes[0];
@@ -1190,7 +1190,7 @@ again:
                        goto again;
                }
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -1278,7 +1278,7 @@ again:
 
                ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
        }
@@ -2975,7 +2975,7 @@ int btrfs_auto_defrag_init(void)
 {
        btrfs_inode_defrag_cachep = kmem_cache_create("btrfs_inode_defrag",
                                        sizeof(struct inode_defrag), 0,
-                                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+                                       SLAB_MEM_SPREAD,
                                        NULL);
        if (!btrfs_inode_defrag_cachep)
                return -ENOMEM;
index 69d270f6602c2de22a734af3f848ad03bf767906..d571bd2b697bf56ccb3f838a55002526ab9a8122 100644 (file)
@@ -280,7 +280,7 @@ fail:
        if (locked)
                mutex_unlock(&trans->transaction->cache_write_mutex);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 
        return ret;
 }
@@ -3026,7 +3026,7 @@ int btrfs_find_space_cluster(struct btrfs_root *root,
         * For metadata, allow allocates with smaller extents.  For
         * data, keep it dense.
         */
-       if (btrfs_test_opt(root, SSD_SPREAD)) {
+       if (btrfs_test_opt(root->fs_info, SSD_SPREAD)) {
                cont1_bytes = min_bytes = bytes + empty_size;
        } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
                cont1_bytes = bytes;
@@ -3470,7 +3470,7 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
        int ret = 0;
        u64 root_gen = btrfs_root_generation(&root->root_item);
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return 0;
 
        /*
@@ -3514,7 +3514,7 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
        struct btrfs_io_ctl io_ctl;
        bool release_metadata = true;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return 0;
 
        memset(&io_ctl, 0, sizeof(io_ctl));
index 53dbeaf6ce941cc7a6a8bf06c6a81df354e9e364..87e7e3d3e6760ebb2b07ef73162ff1d83942d641 100644 (file)
@@ -305,7 +305,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
 out:
        kvfree(bitmap);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
@@ -454,7 +454,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
 out:
        kvfree(bitmap);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
@@ -851,7 +851,7 @@ int remove_from_free_space_tree(struct btrfs_trans_handle *trans,
 out:
        btrfs_free_path(path);
        if (ret)
-               btrfs_abort_transaction(trans, fs_info->free_space_root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
@@ -1047,7 +1047,7 @@ int add_to_free_space_tree(struct btrfs_trans_handle *trans,
 out:
        btrfs_free_path(path);
        if (ret)
-               btrfs_abort_transaction(trans, fs_info->free_space_root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
@@ -1193,7 +1193,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
 
 abort:
        fs_info->creating_free_space_tree = 0;
-       btrfs_abort_transaction(trans, tree_root, ret);
+       btrfs_abort_transaction(trans, ret);
        btrfs_end_transaction(trans, tree_root);
        return ret;
 }
@@ -1280,7 +1280,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
        return 0;
 
 abort:
-       btrfs_abort_transaction(trans, tree_root, ret);
+       btrfs_abort_transaction(trans, ret);
        btrfs_end_transaction(trans, tree_root);
        return ret;
 }
@@ -1333,7 +1333,7 @@ out:
        btrfs_free_path(path);
        mutex_unlock(&block_group->free_space_lock);
        if (ret)
-               btrfs_abort_transaction(trans, fs_info->free_space_root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
@@ -1410,7 +1410,7 @@ int remove_block_group_free_space(struct btrfs_trans_handle *trans,
 out:
        btrfs_free_path(path);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 }
 
index 70107f7c930730c8054d45c153dec71cf9227270..aa6fabaee72ed488844fc042e98536a77e9148cf 100644 (file)
@@ -38,7 +38,7 @@ static int caching_kthread(void *data)
        int slot;
        int ret;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return 0;
 
        path = btrfs_alloc_path();
@@ -141,7 +141,7 @@ static void start_caching(struct btrfs_root *root)
        int ret;
        u64 objectid;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return;
 
        spin_lock(&root->ino_cache_lock);
@@ -185,7 +185,7 @@ static void start_caching(struct btrfs_root *root)
 
 int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
 {
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return btrfs_find_free_objectid(root, objectid);
 
 again:
@@ -211,7 +211,7 @@ void btrfs_return_ino(struct btrfs_root *root, u64 objectid)
 {
        struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return;
 again:
        if (root->ino_cache_state == BTRFS_CACHE_FINISHED) {
@@ -251,7 +251,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root)
        struct rb_node *n;
        u64 count;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return;
 
        while (1) {
@@ -412,7 +412,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
        if (btrfs_root_refs(&root->root_item) == 0)
                return 0;
 
-       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE))
                return 0;
 
        path = btrfs_alloc_path();
@@ -458,7 +458,7 @@ again:
        BTRFS_I(inode)->generation = 0;
        ret = btrfs_update_inode(trans, root, inode);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_put;
        }
 
@@ -466,7 +466,7 @@ again:
                ret = btrfs_truncate_free_space_cache(root, trans, NULL, inode);
                if (ret) {
                        if (ret != -ENOSPC)
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                        goto out_put;
                }
        }
index 8078077d109084aaa24a32f1a8914e36850f180d..b0f421f332ae911b731f4c4eb8705053705504ce 100644 (file)
@@ -60,6 +60,7 @@
 #include "hash.h"
 #include "props.h"
 #include "qgroup.h"
+#include "dedupe.h"
 
 struct btrfs_iget_args {
        struct btrfs_key *location;
@@ -105,8 +106,9 @@ static int btrfs_truncate(struct inode *inode);
 static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent);
 static noinline int cow_file_range(struct inode *inode,
                                   struct page *locked_page,
-                                  u64 start, u64 end, int *page_started,
-                                  unsigned long *nr_written, int unlock);
+                                  u64 start, u64 end, u64 delalloc_end,
+                                  int *page_started, unsigned long *nr_written,
+                                  int unlock, struct btrfs_dedupe_hash *hash);
 static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
                                           u64 len, u64 orig_start,
                                           u64 block_start, u64 block_len,
@@ -294,7 +296,7 @@ static noinline int cow_file_range_inline(struct btrfs_root *root,
                                   start, aligned_end, NULL,
                                   1, 1, extent_item_size, &extent_inserted);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -305,7 +307,7 @@ static noinline int cow_file_range_inline(struct btrfs_root *root,
                                   inline_len, compressed_size,
                                   compress_type, compressed_pages);
        if (ret && ret != -ENOSPC) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        } else if (ret == -ENOSPC) {
                ret = 1;
@@ -374,12 +376,12 @@ static inline int inode_need_compress(struct inode *inode)
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
        /* force compress */
-       if (btrfs_test_opt(root, FORCE_COMPRESS))
+       if (btrfs_test_opt(root->fs_info, FORCE_COMPRESS))
                return 1;
        /* bad compression ratios */
        if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS)
                return 0;
-       if (btrfs_test_opt(root, COMPRESS) ||
+       if (btrfs_test_opt(root->fs_info, COMPRESS) ||
            BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS ||
            BTRFS_I(inode)->force_compress)
                return 1;
@@ -585,9 +587,27 @@ cont:
                        will_compress = 0;
                } else {
                        num_bytes = total_in;
+                       *num_added += 1;
+
+                       /*
+                        * The async work queues will take care of doing actual
+                        * allocation on disk for these compressed pages, and
+                        * will submit them to the elevator.
+                        */
+                       add_async_extent(async_cow, start, num_bytes,
+                                       total_compressed, pages, nr_pages_ret,
+                                       compress_type);
+
+                       if (start + num_bytes < end) {
+                               start += num_bytes;
+                               pages = NULL;
+                               cond_resched();
+                               goto again;
+                       }
+                       return;
                }
        }
-       if (!will_compress && pages) {
+       if (pages) {
                /*
                 * the compression code ran but failed to make things smaller,
                 * free any pages it allocated and our page pointer array
@@ -602,48 +622,28 @@ cont:
                nr_pages_ret = 0;
 
                /* flag the file so we don't compress in the future */
-               if (!btrfs_test_opt(root, FORCE_COMPRESS) &&
+               if (!btrfs_test_opt(root->fs_info, FORCE_COMPRESS) &&
                    !(BTRFS_I(inode)->force_compress)) {
                        BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
                }
        }
-       if (will_compress) {
-               *num_added += 1;
-
-               /* the async work queues will take care of doing actual
-                * allocation on disk for these compressed pages,
-                * and will submit them to the elevator.
-                */
-               add_async_extent(async_cow, start, num_bytes,
-                                total_compressed, pages, nr_pages_ret,
-                                compress_type);
-
-               if (start + num_bytes < end) {
-                       start += num_bytes;
-                       pages = NULL;
-                       cond_resched();
-                       goto again;
-               }
-       } else {
 cleanup_and_bail_uncompressed:
-               /*
-                * No compression, but we still need to write the pages in
-                * the file we've been given so far.  redirty the locked
-                * page if it corresponds to our extent and set things up
-                * for the async work queue to run cow_file_range to do
-                * the normal delalloc dance
-                */
-               if (page_offset(locked_page) >= start &&
-                   page_offset(locked_page) <= end) {
-                       __set_page_dirty_nobuffers(locked_page);
-                       /* unlocked later on in the async handlers */
-               }
-               if (redirty)
-                       extent_range_redirty_for_io(inode, start, end);
-               add_async_extent(async_cow, start, end - start + 1,
-                                0, NULL, 0, BTRFS_COMPRESS_NONE);
-               *num_added += 1;
-       }
+       /*
+        * No compression, but we still need to write the pages in the file
+        * we've been given so far.  redirty the locked page if it corresponds
+        * to our extent and set things up for the async work queue to run
+        * cow_file_range to do the normal delalloc dance.
+        */
+       if (page_offset(locked_page) >= start &&
+           page_offset(locked_page) <= end)
+               __set_page_dirty_nobuffers(locked_page);
+               /* unlocked later on in the async handlers */
+
+       if (redirty)
+               extent_range_redirty_for_io(inode, start, end);
+       add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0,
+                        BTRFS_COMPRESS_NONE);
+       *num_added += 1;
 
        return;
 
@@ -712,7 +712,10 @@ retry:
                                             async_extent->start,
                                             async_extent->start +
                                             async_extent->ram_size - 1,
-                                            &page_started, &nr_written, 0);
+                                            async_extent->start +
+                                            async_extent->ram_size - 1,
+                                            &page_started, &nr_written, 0,
+                                            NULL);
 
                        /* JDM XXX */
 
@@ -925,9 +928,9 @@ static u64 get_extent_allocation_hint(struct inode *inode, u64 start,
  */
 static noinline int cow_file_range(struct inode *inode,
                                   struct page *locked_page,
-                                  u64 start, u64 end, int *page_started,
-                                  unsigned long *nr_written,
-                                  int unlock)
+                                  u64 start, u64 end, u64 delalloc_end,
+                                  int *page_started, unsigned long *nr_written,
+                                  int unlock, struct btrfs_dedupe_hash *hash)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 alloc_hint = 0;
@@ -1156,7 +1159,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
                async_cow->start = start;
 
                if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS &&
-                   !btrfs_test_opt(root, FORCE_COMPRESS))
+                   !btrfs_test_opt(root->fs_info, FORCE_COMPRESS))
                        cur_end = end;
                else
                        cur_end = min(end, start + SZ_512K - 1);
@@ -1418,7 +1421,8 @@ out_check:
                if (cow_start != (u64)-1) {
                        ret = cow_file_range(inode, locked_page,
                                             cow_start, found_key.offset - 1,
-                                            page_started, nr_written, 1);
+                                            end, page_started, nr_written, 1,
+                                            NULL);
                        if (ret) {
                                if (!nolock && nocow)
                                        btrfs_end_write_no_snapshoting(root);
@@ -1501,8 +1505,8 @@ out_check:
        }
 
        if (cow_start != (u64)-1) {
-               ret = cow_file_range(inode, locked_page, cow_start, end,
-                                    page_started, nr_written, 1);
+               ret = cow_file_range(inode, locked_page, cow_start, end, end,
+                                    page_started, nr_written, 1, NULL);
                if (ret)
                        goto error;
        }
@@ -1561,8 +1565,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
                ret = run_delalloc_nocow(inode, locked_page, start, end,
                                         page_started, 0, nr_written);
        } else if (!inode_need_compress(inode)) {
-               ret = cow_file_range(inode, locked_page, start, end,
-                                     page_started, nr_written, 1);
+               ret = cow_file_range(inode, locked_page, start, end, end,
+                                     page_started, nr_written, 1, NULL);
        } else {
                set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
                        &BTRFS_I(inode)->runtime_flags);
@@ -1740,7 +1744,7 @@ static void btrfs_set_bit_hook(struct inode *inode,
                }
 
                /* For sanity tests */
-               if (btrfs_test_is_dummy_root(root))
+               if (btrfs_is_testing(root->fs_info))
                        return;
 
                __percpu_counter_add(&root->fs_info->delalloc_bytes, len,
@@ -1799,7 +1803,7 @@ static void btrfs_clear_bit_hook(struct inode *inode,
                        btrfs_delalloc_release_metadata(inode, len);
 
                /* For sanity tests. */
-               if (btrfs_test_is_dummy_root(root))
+               if (btrfs_is_testing(root->fs_info))
                        return;
 
                if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID
@@ -1822,6 +1826,10 @@ static void btrfs_clear_bit_hook(struct inode *inode,
 /*
  * extent_io.c merge_bio_hook, this must check the chunk tree to make sure
  * we don't create bios that span stripes or chunks
+ *
+ * return 1 if page cannot be merged to bio
+ * return 0 if page can be merged to bio
+ * return error otherwise
  */
 int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
                         size_t size, struct bio *bio,
@@ -1840,8 +1848,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
        map_length = length;
        ret = btrfs_map_block(root->fs_info, bio_op(bio), logical,
                              &map_length, NULL, 0);
-       /* Will always return 0 with map_multi == NULL */
-       BUG_ON(ret < 0);
+       if (ret < 0)
+               return ret;
        if (map_length < length + size)
                return 1;
        return 0;
@@ -2594,7 +2602,7 @@ again:
        ret = btrfs_insert_empty_item(trans, root, path, &key,
                                        sizeof(*extent));
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
        }
 
@@ -2621,7 +2629,7 @@ again:
                        backref->root_id, backref->inum,
                        new->file_pos); /* start - extent_offset */
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
        }
 
@@ -2890,7 +2898,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                ret = btrfs_update_inode_fallback(trans, root, inode);
                if (ret) /* -ENOMEM or corruption */
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -2950,7 +2958,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                           ordered_extent->file_offset, ordered_extent->len,
                           trans->transid);
        if (ret < 0) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_unlock;
        }
 
@@ -2960,7 +2968,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
        btrfs_ordered_update_i_size(inode, 0, ordered_extent);
        ret = btrfs_update_inode_fallback(trans, root, inode);
        if (ret) { /* -ENOMEM or corruption */
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_unlock;
        }
        ret = 0;
@@ -3204,7 +3212,7 @@ void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans,
                ret = btrfs_del_orphan_item(trans, root->fs_info->tree_root,
                                            root->root_key.objectid);
                if (ret)
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                else
                        clear_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
                                  &root->state);
@@ -3295,7 +3303,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
                        if (ret != -EEXIST) {
                                clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
                                          &BTRFS_I(inode)->runtime_flags);
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                return ret;
                        }
                }
@@ -3307,7 +3315,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
                ret = btrfs_insert_orphan_item(trans, root->fs_info->tree_root,
                                               root->root_key.objectid);
                if (ret && ret != -EEXIST) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        return ret;
                }
        }
@@ -4006,20 +4014,20 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
                btrfs_info(root->fs_info,
                        "failed to delete reference to %.*s, inode %llu parent %llu",
                        name_len, name, ino, dir_ino);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto err;
        }
 skip_backref:
        ret = btrfs_delete_delayed_dir_index(trans, root, dir, index);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto err;
        }
 
        ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len,
                                         inode, dir_ino);
        if (ret != 0 && ret != -ENOENT) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto err;
        }
 
@@ -4028,7 +4036,7 @@ skip_backref:
        if (ret == -ENOENT)
                ret = 0;
        else if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 err:
        btrfs_free_path(path);
        if (ret)
@@ -4142,7 +4150,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
        WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid);
        ret = btrfs_delete_one_dir_name(trans, root, path, di);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
        btrfs_release_path(path);
@@ -4152,7 +4160,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
                                 dir_ino, &index, name, name_len);
        if (ret < 0) {
                if (ret != -ENOENT) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
                di = btrfs_search_dir_index_item(root, path, dir_ino,
@@ -4162,7 +4170,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
                                ret = -ENOENT;
                        else
                                ret = PTR_ERR(di);
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -4175,7 +4183,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
 
        ret = btrfs_delete_delayed_dir_index(trans, root, dir, index);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -4184,7 +4192,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
        dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
        ret = btrfs_update_inode_fallback(trans, root, dir);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 out:
        btrfs_free_path(path);
        return ret;
@@ -4505,7 +4513,6 @@ search_again:
                                                              pending_del_nr);
                                        if (err) {
                                                btrfs_abort_transaction(trans,
-                                                                       root,
                                                                        err);
                                                goto error;
                                        }
@@ -4517,8 +4524,7 @@ search_again:
                                                             item_end,
                                                             new_size);
                                if (err) {
-                                       btrfs_abort_transaction(trans,
-                                                               root, err);
+                                       btrfs_abort_transaction(trans, err);
                                        goto error;
                                }
                        } else if (test_bit(BTRFS_ROOT_REF_COWS,
@@ -4582,8 +4588,7 @@ delete:
                                                pending_del_slot,
                                                pending_del_nr);
                                if (ret) {
-                                       btrfs_abort_transaction(trans,
-                                                               root, ret);
+                                       btrfs_abort_transaction(trans, ret);
                                        goto error;
                                }
                                pending_del_nr = 0;
@@ -4616,7 +4621,7 @@ out:
                ret = btrfs_del_items(trans, root, path, pending_del_slot,
                                      pending_del_nr);
                if (ret)
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
        }
 error:
        if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
@@ -4785,7 +4790,7 @@ static int maybe_insert_hole(struct btrfs_root *root, struct inode *inode,
 
        ret = btrfs_drop_extents(trans, root, inode, offset, offset + len, 1);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_end_transaction(trans, root);
                return ret;
        }
@@ -4793,7 +4798,7 @@ static int maybe_insert_hole(struct btrfs_root *root, struct inode *inode,
        ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset,
                                       0, 0, len, 0, len, 0, 0, 0);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        else
                btrfs_update_inode(trans, root, inode);
        btrfs_end_transaction(trans, root);
@@ -5020,7 +5025,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
                        i_size_write(inode, BTRFS_I(inode)->disk_i_size);
                        err = btrfs_orphan_del(trans, inode);
                        if (err)
-                               btrfs_abort_transaction(trans, root, err);
+                               btrfs_abort_transaction(trans, err);
                        btrfs_end_transaction(trans, root);
                }
        }
@@ -5158,11 +5163,18 @@ void btrfs_evict_inode(struct inode *inode)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_block_rsv *rsv, *global_rsv;
        int steal_from_global = 0;
-       u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
+       u64 min_size;
        int ret;
 
        trace_btrfs_inode_evict(inode);
 
+       if (!root) {
+               kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+               return;
+       }
+
+       min_size = btrfs_calc_trunc_metadata_size(root, 1);
+
        evict_inode_truncate_pages(inode);
 
        if (inode->i_nlink &&
@@ -6239,9 +6251,9 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        btrfs_inherit_iflags(inode, dir);
 
        if (S_ISREG(mode)) {
-               if (btrfs_test_opt(root, NODATASUM))
+               if (btrfs_test_opt(root->fs_info, NODATASUM))
                        BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM;
-               if (btrfs_test_opt(root, NODATACOW))
+               if (btrfs_test_opt(root->fs_info, NODATACOW))
                        BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW |
                                BTRFS_INODE_NODATASUM;
        }
@@ -6319,7 +6331,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
        if (ret == -EEXIST || ret == -EOVERFLOW)
                goto fail_dir_item;
        else if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                return ret;
        }
 
@@ -6330,7 +6342,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
                current_fs_time(parent_inode->i_sb);
        ret = btrfs_update_inode(trans, root, parent_inode);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        return ret;
 
 fail_dir_item:
@@ -9385,25 +9397,25 @@ int btrfs_init_cachep(void)
 
        btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle",
                        sizeof(struct btrfs_trans_handle), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL);
        if (!btrfs_trans_handle_cachep)
                goto fail;
 
        btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction",
                        sizeof(struct btrfs_transaction), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL);
        if (!btrfs_transaction_cachep)
                goto fail;
 
        btrfs_path_cachep = kmem_cache_create("btrfs_path",
                        sizeof(struct btrfs_path), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_MEM_SPREAD, NULL);
        if (!btrfs_path_cachep)
                goto fail;
 
        btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space",
                        sizeof(struct btrfs_free_space), 0,
-                       SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+                       SLAB_MEM_SPREAD, NULL);
        if (!btrfs_free_space_cachep)
                goto fail;
 
@@ -9553,7 +9565,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                        ret = btrfs_update_inode(trans, root, old_inode);
        }
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9573,7 +9585,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                        ret = btrfs_update_inode(trans, dest, new_inode);
        }
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9581,7 +9593,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                             new_dentry->d_name.name,
                             new_dentry->d_name.len, 0, old_idx);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9589,7 +9601,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                             old_dentry->d_name.name,
                             old_dentry->d_name.len, 0, new_idx);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9828,7 +9840,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        ret = btrfs_update_inode(trans, root, old_inode);
        }
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9852,7 +9864,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (!ret && new_inode->i_nlink == 0)
                        ret = btrfs_orphan_add(trans, d_inode(new_dentry));
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out_fail;
                }
        }
@@ -9861,7 +9873,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                             new_dentry->d_name.name,
                             new_dentry->d_name.len, 0, index);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_fail;
        }
 
@@ -9881,7 +9893,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                                                old_dentry);
 
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out_fail;
                }
        }
@@ -10307,7 +10319,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                if (ret) {
                        btrfs_free_reserved_extent(root, ins.objectid,
                                                   ins.offset, 0);
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        if (own_trans)
                                btrfs_end_transaction(trans, root);
                        break;
@@ -10367,7 +10379,7 @@ next:
                ret = btrfs_update_inode(trans, root, inode);
 
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        if (own_trans)
                                btrfs_end_transaction(trans, root);
                        break;
index 05173563e4a6b9068b6c02f62b4dfd400b325ca5..14ed1e9e6bc83df20da4863798d0052b376e5636 100644 (file)
@@ -561,7 +561,7 @@ static noinline int create_subvol(struct inode *dir,
        new_root = btrfs_read_fs_root_no_name(root->fs_info, &key);
        if (IS_ERR(new_root)) {
                ret = PTR_ERR(new_root);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -570,7 +570,7 @@ static noinline int create_subvol(struct inode *dir,
        ret = btrfs_create_subvol_root(trans, new_root, root, new_dirid);
        if (ret) {
                /* We potentially lose an unused inode item here */
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -583,7 +583,7 @@ static noinline int create_subvol(struct inode *dir,
         */
        ret = btrfs_set_inode_index(dir, &index);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -591,7 +591,7 @@ static noinline int create_subvol(struct inode *dir,
                                    name, namelen, dir, &key,
                                    BTRFS_FT_DIR, index);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -608,7 +608,7 @@ static noinline int create_subvol(struct inode *dir,
                                  root_item->uuid, BTRFS_UUID_KEY_SUBVOL,
                                  objectid);
        if (ret)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 
 fail:
        kfree(root_item);
@@ -1948,8 +1948,7 @@ static noinline int key_in_sk(struct btrfs_key *key,
        return 1;
 }
 
-static noinline int copy_to_sk(struct btrfs_root *root,
-                              struct btrfs_path *path,
+static noinline int copy_to_sk(struct btrfs_path *path,
                               struct btrfs_key *key,
                               struct btrfs_ioctl_search_key *sk,
                               size_t *buf_size,
@@ -2120,7 +2119,7 @@ static noinline int search_ioctl(struct inode *inode,
                                ret = 0;
                        goto err;
                }
-               ret = copy_to_sk(root, path, &key, sk, buf_size, ubuf,
+               ret = copy_to_sk(path, &key, sk, buf_size, ubuf,
                                 &sk_offset, &num_found);
                btrfs_release_path(path);
                if (ret)
@@ -2406,7 +2405,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                 * rmdir(2).
                 */
                err = -EPERM;
-               if (!btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
+               if (!btrfs_test_opt(root->fs_info, USER_SUBVOL_RM_ALLOWED))
                        goto out_dput;
 
                /*
@@ -2489,7 +2488,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                                dentry->d_name.len);
        if (ret) {
                err = ret;
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_end_trans;
        }
 
@@ -2505,7 +2504,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                                        root->fs_info->tree_root,
                                        dest->root_key.objectid);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        err = ret;
                        goto out_end_trans;
                }
@@ -2515,7 +2514,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                                  dest->root_item.uuid, BTRFS_UUID_KEY_SUBVOL,
                                  dest->root_key.objectid);
        if (ret && ret != -ENOENT) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                err = ret;
                goto out_end_trans;
        }
@@ -2525,7 +2524,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                                          BTRFS_UUID_KEY_RECEIVED_SUBVOL,
                                          dest->root_key.objectid);
                if (ret && ret != -ENOENT) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        err = ret;
                        goto out_end_trans;
                }
@@ -3292,7 +3291,7 @@ static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
 
        ret = btrfs_update_inode(trans, root, inode);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_end_transaction(trans, root);
                goto out;
        }
@@ -3694,7 +3693,7 @@ process_slot:
                                if (ret) {
                                        if (ret != -EOPNOTSUPP)
                                                btrfs_abort_transaction(trans,
-                                                               root, ret);
+                                                                       ret);
                                        btrfs_end_transaction(trans, root);
                                        goto out;
                                }
@@ -3702,8 +3701,7 @@ process_slot:
                                ret = btrfs_insert_empty_item(trans, root, path,
                                                              &new_key, size);
                                if (ret) {
-                                       btrfs_abort_transaction(trans, root,
-                                                               ret);
+                                       btrfs_abort_transaction(trans, ret);
                                        btrfs_end_transaction(trans, root);
                                        goto out;
                                }
@@ -3735,7 +3733,6 @@ process_slot:
                                                        new_key.offset - datao);
                                        if (ret) {
                                                btrfs_abort_transaction(trans,
-                                                                       root,
                                                                        ret);
                                                btrfs_end_transaction(trans,
                                                                      root);
@@ -3772,7 +3769,6 @@ process_slot:
                                if (ret) {
                                        if (ret != -EOPNOTSUPP)
                                                btrfs_abort_transaction(trans,
-                                                                       root,
                                                                        ret);
                                        btrfs_end_transaction(trans, root);
                                        goto out;
@@ -3828,7 +3824,7 @@ process_slot:
                                         last_dest_end, destoff + len, 1);
                if (ret) {
                        if (ret != -EOPNOTSUPP)
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                        btrfs_end_transaction(trans, root);
                        goto out;
                }
@@ -5164,13 +5160,13 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
                                          BTRFS_UUID_KEY_RECEIVED_SUBVOL,
                                          root->root_key.objectid);
                if (ret < 0 && ret != -EEXIST) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
        }
        ret = btrfs_commit_transaction(trans, root);
        if (ret < 0) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
index aca8264f4a49d029c52ca9363cf4b64dcef1aef2..3b78d38173b3fa7eb0ddd5c07597c49e454bc954 100644 (file)
@@ -1122,7 +1122,7 @@ int __init ordered_data_init(void)
 {
        btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent",
                                     sizeof(struct btrfs_ordered_extent), 0,
-                                    SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+                                    SLAB_MEM_SPREAD,
                                     NULL);
        if (!btrfs_ordered_extent_cache)
                return -ENOMEM;
index 36992128c7466cab65b1d8a9b71e670f32df9ac5..cf0b444ac4f306068c2da63349b3a151066118a1 100644 (file)
@@ -350,6 +350,7 @@ int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root,
                               struct btrfs_root *parent_root)
 {
+       struct super_block *sb = root->fs_info->sb;
        struct btrfs_key key;
        struct inode *parent_inode, *child_inode;
        int ret;
@@ -358,12 +359,11 @@ int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans,
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
 
-       parent_inode = btrfs_iget(parent_root->fs_info->sb, &key,
-                                 parent_root, NULL);
+       parent_inode = btrfs_iget(sb, &key, parent_root, NULL);
        if (IS_ERR(parent_inode))
                return PTR_ERR(parent_inode);
 
-       child_inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
+       child_inode = btrfs_iget(sb, &key, root, NULL);
        if (IS_ERR(child_inode)) {
                iput(parent_inode);
                return PTR_ERR(child_inode);
index 9d4c05b14f6e742c5dc6d4d990ef8de269496865..93ee1c18ef9d4c2e1677fc3ad437b3044c84f68e 100644 (file)
@@ -571,7 +571,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
        struct extent_buffer *leaf;
        struct btrfs_key key;
 
-       if (btrfs_test_is_dummy_root(quota_root))
+       if (btrfs_is_testing(quota_root->fs_info))
                return 0;
 
        path = btrfs_alloc_path();
@@ -728,7 +728,7 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
        int ret;
        int slot;
 
-       if (btrfs_test_is_dummy_root(root))
+       if (btrfs_is_testing(root->fs_info))
                return 0;
 
        key.objectid = 0;
@@ -1453,9 +1453,10 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-struct btrfs_qgroup_extent_record
-*btrfs_qgroup_insert_dirty_extent(struct btrfs_delayed_ref_root *delayed_refs,
-                                 struct btrfs_qgroup_extent_record *record)
+struct btrfs_qgroup_extent_record *
+btrfs_qgroup_insert_dirty_extent(struct btrfs_fs_info *fs_info,
+                                struct btrfs_delayed_ref_root *delayed_refs,
+                                struct btrfs_qgroup_extent_record *record)
 {
        struct rb_node **p = &delayed_refs->dirty_extent_root.rb_node;
        struct rb_node *parent_node = NULL;
@@ -1463,7 +1464,7 @@ struct btrfs_qgroup_extent_record
        u64 bytenr = record->bytenr;
 
        assert_spin_locked(&delayed_refs->lock);
-       trace_btrfs_qgroup_insert_dirty_extent(record);
+       trace_btrfs_qgroup_insert_dirty_extent(fs_info, record);
 
        while (*p) {
                parent_node = *p;
@@ -1595,8 +1596,8 @@ static int qgroup_update_counters(struct btrfs_fs_info *fs_info,
                cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq);
                cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq);
 
-               trace_qgroup_update_counters(qg->qgroupid, cur_old_count,
-                                            cur_new_count);
+               trace_qgroup_update_counters(fs_info, qg->qgroupid,
+                                            cur_old_count, cur_new_count);
 
                /* Rfer update part */
                if (cur_old_count == 0 && cur_new_count > 0) {
@@ -1687,8 +1688,8 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans,
                goto out_free;
        BUG_ON(!fs_info->quota_root);
 
-       trace_btrfs_qgroup_account_extent(bytenr, num_bytes, nr_old_roots,
-                                         nr_new_roots);
+       trace_btrfs_qgroup_account_extent(fs_info, bytenr, num_bytes,
+                                         nr_old_roots, nr_new_roots);
 
        qgroups = ulist_alloc(GFP_NOFS);
        if (!qgroups) {
@@ -1759,7 +1760,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans,
                record = rb_entry(node, struct btrfs_qgroup_extent_record,
                                  node);
 
-               trace_btrfs_qgroup_account_extents(record);
+               trace_btrfs_qgroup_account_extents(fs_info, record);
 
                if (!ret) {
                        /*
@@ -2195,7 +2196,7 @@ void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
 {
        if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq)
                return;
-       btrfs_err(trans->root->fs_info,
+       btrfs_err(trans->fs_info,
                "qgroups not uptodate in trans handle %p:  list is%s empty, "
                "seq is %#x.%x",
                trans, list_empty(&trans->qgroup_ref_list) ? "" : " not",
index ecb2c143ef756bd0356e3968b3f9f13fe5ac21cd..710887c06aaf4c6171a74b2b954653dfa61478e1 100644 (file)
@@ -63,9 +63,10 @@ void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info);
 struct btrfs_delayed_extent_op;
 int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans,
                                         struct btrfs_fs_info *fs_info);
-struct btrfs_qgroup_extent_record
-*btrfs_qgroup_insert_dirty_extent(struct btrfs_delayed_ref_root *delayed_refs,
-                                 struct btrfs_qgroup_extent_record *record);
+struct btrfs_qgroup_extent_record *
+btrfs_qgroup_insert_dirty_extent(struct btrfs_fs_info *fs_info,
+                                struct btrfs_delayed_ref_root *delayed_refs,
+                                struct btrfs_qgroup_extent_record *record);
 int
 btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans,
                            struct btrfs_fs_info *fs_info,
@@ -88,7 +89,7 @@ static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info,
                                                 u64 ref_root, u64 num_bytes)
 {
        btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes);
-       trace_btrfs_qgroup_free_delayed_ref(ref_root, num_bytes);
+       trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes);
 }
 void assert_qgroups_uptodate(struct btrfs_trans_handle *trans);
 
index fc067b07e31fac354c45a0f0ad1b693886b80a47..b26a5aea41b4a67be495fb419080e3dd9d235136 100644 (file)
@@ -235,12 +235,12 @@ static void backref_cache_cleanup(struct backref_cache *cache)
        cache->last_trans = 0;
 
        for (i = 0; i < BTRFS_MAX_LEVEL; i++)
-               BUG_ON(!list_empty(&cache->pending[i]));
-       BUG_ON(!list_empty(&cache->changed));
-       BUG_ON(!list_empty(&cache->detached));
-       BUG_ON(!RB_EMPTY_ROOT(&cache->rb_root));
-       BUG_ON(cache->nr_nodes);
-       BUG_ON(cache->nr_edges);
+               ASSERT(list_empty(&cache->pending[i]));
+       ASSERT(list_empty(&cache->changed));
+       ASSERT(list_empty(&cache->detached));
+       ASSERT(RB_EMPTY_ROOT(&cache->rb_root));
+       ASSERT(!cache->nr_nodes);
+       ASSERT(!cache->nr_edges);
 }
 
 static struct backref_node *alloc_backref_node(struct backref_cache *cache)
@@ -1171,8 +1171,12 @@ out:
                        lower = list_entry(useless.next,
                                           struct backref_node, list);
                        list_del_init(&lower->list);
+                       if (lower == node)
+                               node = NULL;
                        free_backref_node(cache, lower);
                }
+
+               free_backref_node(cache, node);
                return ERR_PTR(err);
        }
        ASSERT(!node || !node->detached);
@@ -1719,7 +1723,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
                                           btrfs_header_owner(leaf),
                                           key.objectid, key.offset);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        break;
                }
 
@@ -1727,7 +1731,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
                                        parent, btrfs_header_owner(leaf),
                                        key.objectid, key.offset);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        break;
                }
        }
index f1c30861d062713e8feaaf5886c7bbca2596aa88..7fd7e1830cfe676e74000b54de026a5a1070cc1a 100644 (file)
@@ -150,7 +150,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
 
        ret = btrfs_search_slot(trans, root, key, path, 0, 1);
        if (ret < 0) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -176,20 +176,20 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
                ret = btrfs_search_slot(trans, root, key, path,
                                -1, 1);
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
                ret = btrfs_del_item(trans, root, path);
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
                btrfs_release_path(path);
                ret = btrfs_insert_empty_item(trans, root, path,
                                key, sizeof(*item));
                if (ret < 0) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
                l = path->nodes[0];
@@ -448,7 +448,7 @@ again:
        ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
                                      sizeof(*ref) + name_len);
        if (ret) {
-               btrfs_abort_transaction(trans, tree_root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_free_path(path);
                return ret;
        }
index e08b6bc676e3faa4d93c211b11a59a90c1a62891..1d195d2b32c6ee62d497539172c15e011c26e467 100644 (file)
@@ -3785,27 +3785,27 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
        if (fs_info->scrub_workers_refcnt == 0) {
                if (is_dev_replace)
                        fs_info->scrub_workers =
-                               btrfs_alloc_workqueue("scrub", flags,
+                               btrfs_alloc_workqueue(fs_info, "scrub", flags,
                                                      1, 4);
                else
                        fs_info->scrub_workers =
-                               btrfs_alloc_workqueue("scrub", flags,
+                               btrfs_alloc_workqueue(fs_info, "scrub", flags,
                                                      max_active, 4);
                if (!fs_info->scrub_workers)
                        goto fail_scrub_workers;
 
                fs_info->scrub_wr_completion_workers =
-                       btrfs_alloc_workqueue("scrubwrc", flags,
+                       btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
                                              max_active, 2);
                if (!fs_info->scrub_wr_completion_workers)
                        goto fail_scrub_wr_completion_workers;
 
                fs_info->scrub_nocow_workers =
-                       btrfs_alloc_workqueue("scrubnc", flags, 1, 0);
+                       btrfs_alloc_workqueue(fs_info, "scrubnc", flags, 1, 0);
                if (!fs_info->scrub_nocow_workers)
                        goto fail_scrub_nocow_workers;
                fs_info->scrub_parity_workers =
-                       btrfs_alloc_workqueue("scrubparity", flags,
+                       btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
                                              max_active, 2);
                if (!fs_info->scrub_parity_workers)
                        goto fail_scrub_parity_workers;
@@ -3860,7 +3860,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
 
        if (fs_info->chunk_root->sectorsize != PAGE_SIZE) {
                /* not supported for data w/o checksums */
-               btrfs_err(fs_info,
+               btrfs_err_rl(fs_info,
                           "scrub: size assumption sectorsize != PAGE_SIZE "
                           "(%d != %lu) fails",
                       fs_info->chunk_root->sectorsize, PAGE_SIZE);
index 60e7179ed4b77ff8dcd9de1d8eb1c0cebce9f95d..864ce334f696c31badf2919b07d503416545ded6 100644 (file)
@@ -184,6 +184,22 @@ static const char * const logtypes[] = {
        "debug",
 };
 
+
+/*
+ * Use one ratelimit state per log level so that a flood of less important
+ * messages doesn't cause more important ones to be dropped.
+ */
+static struct ratelimit_state printk_limits[] = {
+       RATELIMIT_STATE_INIT(printk_limits[0], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[1], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[2], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[3], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[4], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[5], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[6], DEFAULT_RATELIMIT_INTERVAL, 100),
+       RATELIMIT_STATE_INIT(printk_limits[7], DEFAULT_RATELIMIT_INTERVAL, 100),
+};
+
 void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
 {
        struct super_block *sb = fs_info->sb;
@@ -192,6 +208,7 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
        va_list args;
        const char *type = logtypes[4];
        int kern_level;
+       struct ratelimit_state *ratelimit;
 
        va_start(args, fmt);
 
@@ -202,13 +219,18 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
                lvl[size] = '\0';
                fmt += size;
                type = logtypes[kern_level - '0'];
-       } else
+               ratelimit = &printk_limits[kern_level - '0'];
+       } else {
                *lvl = '\0';
+               /* Default to debug output */
+               ratelimit = &printk_limits[7];
+       }
 
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       printk("%sBTRFS %s (device %s): %pV\n", lvl, type, sb->s_id, &vaf);
+       if (__ratelimit(ratelimit))
+               printk("%sBTRFS %s (device %s): %pV\n", lvl, type, sb->s_id, &vaf);
 
        va_end(args);
 }
@@ -229,9 +251,11 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
  */
 __cold
 void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
-                              struct btrfs_root *root, const char *function,
+                              const char *function,
                               unsigned int line, int errno)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
+
        trans->aborted = errno;
        /* Nothing used. The other threads that have joined this
         * transaction may be able to continue. */
@@ -239,16 +263,16 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
                const char *errstr;
 
                errstr = btrfs_decode_error(errno);
-               btrfs_warn(root->fs_info,
+               btrfs_warn(fs_info,
                           "%s:%d: Aborting unused transaction(%s).",
                           function, line, errstr);
                return;
        }
        ACCESS_ONCE(trans->transaction->aborted) = errno;
        /* Wake up anybody who may be waiting on this transaction */
-       wake_up(&root->fs_info->transaction_wait);
-       wake_up(&root->fs_info->transaction_blocked_wait);
-       __btrfs_handle_fs_error(root->fs_info, function, line, errno, NULL);
+       wake_up(&fs_info->transaction_wait);
+       wake_up(&fs_info->transaction_blocked_wait);
+       __btrfs_handle_fs_error(fs_info, function, line, errno, NULL);
 }
 /*
  * __btrfs_panic decodes unexpected, fatal errors from the caller,
@@ -432,12 +456,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                         */
                        break;
                case Opt_nodatasum:
-                       btrfs_set_and_info(root, NODATASUM,
+                       btrfs_set_and_info(info, NODATASUM,
                                           "setting nodatasum");
                        break;
                case Opt_datasum:
-                       if (btrfs_test_opt(root, NODATASUM)) {
-                               if (btrfs_test_opt(root, NODATACOW))
+                       if (btrfs_test_opt(info, NODATASUM)) {
+                               if (btrfs_test_opt(info, NODATACOW))
                                        btrfs_info(root->fs_info, "setting datasum, datacow enabled");
                                else
                                        btrfs_info(root->fs_info, "setting datasum");
@@ -446,9 +470,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        btrfs_clear_opt(info->mount_opt, NODATASUM);
                        break;
                case Opt_nodatacow:
-                       if (!btrfs_test_opt(root, NODATACOW)) {
-                               if (!btrfs_test_opt(root, COMPRESS) ||
-                                   !btrfs_test_opt(root, FORCE_COMPRESS)) {
+                       if (!btrfs_test_opt(info, NODATACOW)) {
+                               if (!btrfs_test_opt(info, COMPRESS) ||
+                                   !btrfs_test_opt(info, FORCE_COMPRESS)) {
                                        btrfs_info(root->fs_info,
                                                   "setting nodatacow, compression disabled");
                                } else {
@@ -461,7 +485,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        btrfs_set_opt(info->mount_opt, NODATASUM);
                        break;
                case Opt_datacow:
-                       btrfs_clear_and_info(root, NODATACOW,
+                       btrfs_clear_and_info(info, NODATACOW,
                                             "setting datacow");
                        break;
                case Opt_compress_force:
@@ -470,10 +494,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        /* Fallthrough */
                case Opt_compress:
                case Opt_compress_type:
-                       saved_compress_type = btrfs_test_opt(root, COMPRESS) ?
+                       saved_compress_type = btrfs_test_opt(info,
+                                                            COMPRESS) ?
                                info->compress_type : BTRFS_COMPRESS_NONE;
                        saved_compress_force =
-                               btrfs_test_opt(root, FORCE_COMPRESS);
+                               btrfs_test_opt(info, FORCE_COMPRESS);
                        if (token == Opt_compress ||
                            token == Opt_compress_force ||
                            strcmp(args[0].from, "zlib") == 0) {
@@ -513,10 +538,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                                 */
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                        }
-                       if ((btrfs_test_opt(root, COMPRESS) &&
+                       if ((btrfs_test_opt(info, COMPRESS) &&
                             (info->compress_type != saved_compress_type ||
                              compress_force != saved_compress_force)) ||
-                           (!btrfs_test_opt(root, COMPRESS) &&
+                           (!btrfs_test_opt(info, COMPRESS) &&
                             no_compress == 1)) {
                                btrfs_info(root->fs_info,
                                           "%s %s compression",
@@ -526,25 +551,25 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        compress_force = false;
                        break;
                case Opt_ssd:
-                       btrfs_set_and_info(root, SSD,
+                       btrfs_set_and_info(info, SSD,
                                           "use ssd allocation scheme");
                        break;
                case Opt_ssd_spread:
-                       btrfs_set_and_info(root, SSD_SPREAD,
+                       btrfs_set_and_info(info, SSD_SPREAD,
                                           "use spread ssd allocation scheme");
                        btrfs_set_opt(info->mount_opt, SSD);
                        break;
                case Opt_nossd:
-                       btrfs_set_and_info(root, NOSSD,
+                       btrfs_set_and_info(info, NOSSD,
                                             "not using ssd allocation scheme");
                        btrfs_clear_opt(info->mount_opt, SSD);
                        break;
                case Opt_barrier:
-                       btrfs_clear_and_info(root, NOBARRIER,
+                       btrfs_clear_and_info(info, NOBARRIER,
                                             "turning on barriers");
                        break;
                case Opt_nobarrier:
-                       btrfs_set_and_info(root, NOBARRIER,
+                       btrfs_set_and_info(info, NOBARRIER,
                                           "turning off barriers");
                        break;
                case Opt_thread_pool:
@@ -604,24 +629,24 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        root->fs_info->sb->s_flags &= ~MS_POSIXACL;
                        break;
                case Opt_notreelog:
-                       btrfs_set_and_info(root, NOTREELOG,
+                       btrfs_set_and_info(info, NOTREELOG,
                                           "disabling tree log");
                        break;
                case Opt_treelog:
-                       btrfs_clear_and_info(root, NOTREELOG,
+                       btrfs_clear_and_info(info, NOTREELOG,
                                             "enabling tree log");
                        break;
                case Opt_norecovery:
                case Opt_nologreplay:
-                       btrfs_set_and_info(root, NOLOGREPLAY,
+                       btrfs_set_and_info(info, NOLOGREPLAY,
                                           "disabling log replay at mount time");
                        break;
                case Opt_flushoncommit:
-                       btrfs_set_and_info(root, FLUSHONCOMMIT,
+                       btrfs_set_and_info(info, FLUSHONCOMMIT,
                                           "turning on flush-on-commit");
                        break;
                case Opt_noflushoncommit:
-                       btrfs_clear_and_info(root, FLUSHONCOMMIT,
+                       btrfs_clear_and_info(info, FLUSHONCOMMIT,
                                             "turning off flush-on-commit");
                        break;
                case Opt_ratio:
@@ -638,11 +663,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        }
                        break;
                case Opt_discard:
-                       btrfs_set_and_info(root, DISCARD,
+                       btrfs_set_and_info(info, DISCARD,
                                           "turning on discard");
                        break;
                case Opt_nodiscard:
-                       btrfs_clear_and_info(root, DISCARD,
+                       btrfs_clear_and_info(info, DISCARD,
                                             "turning off discard");
                        break;
                case Opt_space_cache:
@@ -651,12 +676,13 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                            strcmp(args[0].from, "v1") == 0) {
                                btrfs_clear_opt(root->fs_info->mount_opt,
                                                FREE_SPACE_TREE);
-                               btrfs_set_and_info(root, SPACE_CACHE,
+                               btrfs_set_and_info(info, SPACE_CACHE,
                                                   "enabling disk space caching");
                        } else if (strcmp(args[0].from, "v2") == 0) {
                                btrfs_clear_opt(root->fs_info->mount_opt,
                                                SPACE_CACHE);
-                               btrfs_set_and_info(root, FREE_SPACE_TREE,
+                               btrfs_set_and_info(info,
+                                                  FREE_SPACE_TREE,
                                                   "enabling free space tree");
                        } else {
                                ret = -EINVAL;
@@ -667,12 +693,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE);
                        break;
                case Opt_no_space_cache:
-                       if (btrfs_test_opt(root, SPACE_CACHE)) {
-                               btrfs_clear_and_info(root, SPACE_CACHE,
+                       if (btrfs_test_opt(info, SPACE_CACHE)) {
+                               btrfs_clear_and_info(info,
+                                                    SPACE_CACHE,
                                                     "disabling disk space caching");
                        }
-                       if (btrfs_test_opt(root, FREE_SPACE_TREE)) {
-                               btrfs_clear_and_info(root, FREE_SPACE_TREE,
+                       if (btrfs_test_opt(info, FREE_SPACE_TREE)) {
+                               btrfs_clear_and_info(info,
+                                                    FREE_SPACE_TREE,
                                                     "disabling free space tree");
                        }
                        break;
@@ -685,7 +713,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                                             "disabling inode map caching");
                        break;
                case Opt_clear_cache:
-                       btrfs_set_and_info(root, CLEAR_CACHE,
+                       btrfs_set_and_info(info, CLEAR_CACHE,
                                           "force clearing of disk cache");
                        break;
                case Opt_user_subvol_rm_allowed:
@@ -698,11 +726,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options,
                        btrfs_clear_opt(info->mount_opt, ENOSPC_DEBUG);
                        break;
                case Opt_defrag:
-                       btrfs_set_and_info(root, AUTO_DEFRAG,
+                       btrfs_set_and_info(info, AUTO_DEFRAG,
                                           "enabling auto defrag");
                        break;
                case Opt_nodefrag:
-                       btrfs_clear_and_info(root, AUTO_DEFRAG,
+                       btrfs_clear_and_info(info, AUTO_DEFRAG,
                                             "disabling auto defrag");
                        break;
                case Opt_recovery:
@@ -810,22 +838,22 @@ check:
        /*
         * Extra check for current option against current flag
         */
-       if (btrfs_test_opt(root, NOLOGREPLAY) && !(new_flags & MS_RDONLY)) {
+       if (btrfs_test_opt(info, NOLOGREPLAY) && !(new_flags & MS_RDONLY)) {
                btrfs_err(root->fs_info,
                          "nologreplay must be used with ro mount option");
                ret = -EINVAL;
        }
 out:
        if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
-           !btrfs_test_opt(root, FREE_SPACE_TREE) &&
-           !btrfs_test_opt(root, CLEAR_CACHE)) {
+           !btrfs_test_opt(info, FREE_SPACE_TREE) &&
+           !btrfs_test_opt(info, CLEAR_CACHE)) {
                btrfs_err(root->fs_info, "cannot disable free space tree");
                ret = -EINVAL;
 
        }
-       if (!ret && btrfs_test_opt(root, SPACE_CACHE))
+       if (!ret && btrfs_test_opt(info, SPACE_CACHE))
                btrfs_info(root->fs_info, "disk space caching is enabled");
-       if (!ret && btrfs_test_opt(root, FREE_SPACE_TREE))
+       if (!ret && btrfs_test_opt(info, FREE_SPACE_TREE))
                btrfs_info(root->fs_info, "using free space tree");
        kfree(orig);
        return ret;
@@ -1149,7 +1177,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
        struct btrfs_fs_info *fs_info = btrfs_sb(sb);
        struct btrfs_root *root = fs_info->tree_root;
 
-       trace_btrfs_sync_fs(wait);
+       trace_btrfs_sync_fs(fs_info, wait);
 
        if (!wait) {
                filemap_flush(fs_info->btree_inode->i_mapping);
@@ -1192,13 +1220,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
        struct btrfs_root *root = info->tree_root;
        char *compress_type;
 
-       if (btrfs_test_opt(root, DEGRADED))
+       if (btrfs_test_opt(info, DEGRADED))
                seq_puts(seq, ",degraded");
-       if (btrfs_test_opt(root, NODATASUM))
+       if (btrfs_test_opt(info, NODATASUM))
                seq_puts(seq, ",nodatasum");
-       if (btrfs_test_opt(root, NODATACOW))
+       if (btrfs_test_opt(info, NODATACOW))
                seq_puts(seq, ",nodatacow");
-       if (btrfs_test_opt(root, NOBARRIER))
+       if (btrfs_test_opt(info, NOBARRIER))
                seq_puts(seq, ",nobarrier");
        if (info->max_inline != BTRFS_DEFAULT_MAX_INLINE)
                seq_printf(seq, ",max_inline=%llu", info->max_inline);
@@ -1207,56 +1235,56 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
        if (info->thread_pool_size !=  min_t(unsigned long,
                                             num_online_cpus() + 2, 8))
                seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
-       if (btrfs_test_opt(root, COMPRESS)) {
+       if (btrfs_test_opt(info, COMPRESS)) {
                if (info->compress_type == BTRFS_COMPRESS_ZLIB)
                        compress_type = "zlib";
                else
                        compress_type = "lzo";
-               if (btrfs_test_opt(root, FORCE_COMPRESS))
+               if (btrfs_test_opt(info, FORCE_COMPRESS))
                        seq_printf(seq, ",compress-force=%s", compress_type);
                else
                        seq_printf(seq, ",compress=%s", compress_type);
        }
-       if (btrfs_test_opt(root, NOSSD))
+       if (btrfs_test_opt(info, NOSSD))
                seq_puts(seq, ",nossd");
-       if (btrfs_test_opt(root, SSD_SPREAD))
+       if (btrfs_test_opt(info, SSD_SPREAD))
                seq_puts(seq, ",ssd_spread");
-       else if (btrfs_test_opt(root, SSD))
+       else if (btrfs_test_opt(info, SSD))
                seq_puts(seq, ",ssd");
-       if (btrfs_test_opt(root, NOTREELOG))
+       if (btrfs_test_opt(info, NOTREELOG))
                seq_puts(seq, ",notreelog");
-       if (btrfs_test_opt(root, NOLOGREPLAY))
+       if (btrfs_test_opt(info, NOLOGREPLAY))
                seq_puts(seq, ",nologreplay");
-       if (btrfs_test_opt(root, FLUSHONCOMMIT))
+       if (btrfs_test_opt(info, FLUSHONCOMMIT))
                seq_puts(seq, ",flushoncommit");
-       if (btrfs_test_opt(root, DISCARD))
+       if (btrfs_test_opt(info, DISCARD))
                seq_puts(seq, ",discard");
        if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
                seq_puts(seq, ",noacl");
-       if (btrfs_test_opt(root, SPACE_CACHE))
+       if (btrfs_test_opt(info, SPACE_CACHE))
                seq_puts(seq, ",space_cache");
-       else if (btrfs_test_opt(root, FREE_SPACE_TREE))
+       else if (btrfs_test_opt(info, FREE_SPACE_TREE))
                seq_puts(seq, ",space_cache=v2");
        else
                seq_puts(seq, ",nospace_cache");
-       if (btrfs_test_opt(root, RESCAN_UUID_TREE))
+       if (btrfs_test_opt(info, RESCAN_UUID_TREE))
                seq_puts(seq, ",rescan_uuid_tree");
-       if (btrfs_test_opt(root, CLEAR_CACHE))
+       if (btrfs_test_opt(info, CLEAR_CACHE))
                seq_puts(seq, ",clear_cache");
-       if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
+       if (btrfs_test_opt(info, USER_SUBVOL_RM_ALLOWED))
                seq_puts(seq, ",user_subvol_rm_allowed");
-       if (btrfs_test_opt(root, ENOSPC_DEBUG))
+       if (btrfs_test_opt(info, ENOSPC_DEBUG))
                seq_puts(seq, ",enospc_debug");
-       if (btrfs_test_opt(root, AUTO_DEFRAG))
+       if (btrfs_test_opt(info, AUTO_DEFRAG))
                seq_puts(seq, ",autodefrag");
-       if (btrfs_test_opt(root, INODE_MAP_CACHE))
+       if (btrfs_test_opt(info, INODE_MAP_CACHE))
                seq_puts(seq, ",inode_cache");
-       if (btrfs_test_opt(root, SKIP_BALANCE))
+       if (btrfs_test_opt(info, SKIP_BALANCE))
                seq_puts(seq, ",skip_balance");
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
-       if (btrfs_test_opt(root, CHECK_INTEGRITY_INCLUDING_EXTENT_DATA))
+       if (btrfs_test_opt(info, CHECK_INTEGRITY_INCLUDING_EXTENT_DATA))
                seq_puts(seq, ",check_int_data");
-       else if (btrfs_test_opt(root, CHECK_INTEGRITY))
+       else if (btrfs_test_opt(info, CHECK_INTEGRITY))
                seq_puts(seq, ",check_int");
        if (info->check_integrity_print_mask)
                seq_printf(seq, ",check_int_print_mask=%d",
@@ -1265,14 +1293,14 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
        if (info->metadata_ratio)
                seq_printf(seq, ",metadata_ratio=%d",
                                info->metadata_ratio);
-       if (btrfs_test_opt(root, PANIC_ON_FATAL_ERROR))
+       if (btrfs_test_opt(info, PANIC_ON_FATAL_ERROR))
                seq_puts(seq, ",fatal_errors=panic");
        if (info->commit_interval != BTRFS_DEFAULT_COMMIT_INTERVAL)
                seq_printf(seq, ",commit=%d", info->commit_interval);
 #ifdef CONFIG_BTRFS_DEBUG
-       if (btrfs_test_opt(root, FRAGMENT_DATA))
+       if (btrfs_test_opt(info, FRAGMENT_DATA))
                seq_puts(seq, ",fragment=data");
-       if (btrfs_test_opt(root, FRAGMENT_METADATA))
+       if (btrfs_test_opt(info, FRAGMENT_METADATA))
                seq_puts(seq, ",fragment=metadata");
 #endif
        seq_printf(seq, ",subvolid=%llu",
@@ -2030,9 +2058,6 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
  * chunk).
  *
  * If metadata is exhausted, f_bavail will be 0.
- *
- * FIXME: not accurate for mixed block groups, total and free/used are ok,
- * available appears slightly larger.
  */
 static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
@@ -2319,49 +2344,6 @@ static void btrfs_print_mod_info(void)
                        btrfs_crc32c_impl());
 }
 
-static int btrfs_run_sanity_tests(void)
-{
-       int ret, i;
-       u32 sectorsize, nodesize;
-       u32 test_sectorsize[] = {
-               PAGE_SIZE,
-       };
-       ret = btrfs_init_test_fs();
-       if (ret)
-               return ret;
-       for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
-               sectorsize = test_sectorsize[i];
-               for (nodesize = sectorsize;
-                    nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
-                    nodesize <<= 1) {
-                       pr_info("BTRFS: selftest: sectorsize: %u  nodesize: %u\n",
-                               sectorsize, nodesize);
-                       ret = btrfs_test_free_space_cache(sectorsize, nodesize);
-                       if (ret)
-                               goto out;
-                       ret = btrfs_test_extent_buffer_operations(sectorsize,
-                               nodesize);
-                       if (ret)
-                               goto out;
-                       ret = btrfs_test_extent_io(sectorsize, nodesize);
-                       if (ret)
-                               goto out;
-                       ret = btrfs_test_inodes(sectorsize, nodesize);
-                       if (ret)
-                               goto out;
-                       ret = btrfs_test_qgroups(sectorsize, nodesize);
-                       if (ret)
-                               goto out;
-                       ret = btrfs_test_free_space_tree(sectorsize, nodesize);
-                       if (ret)
-                               goto out;
-               }
-       }
-out:
-       btrfs_destroy_test_fs();
-       return ret;
-}
-
 static int __init init_btrfs_fs(void)
 {
        int err;
index 4879656bda3cdebefbcd6390bf6ab6597e616ac0..c6569905d3d1cc5058b7a7a67785a49d6e5d1104 100644 (file)
@@ -326,6 +326,7 @@ SPACE_INFO_ATTR(bytes_used);
 SPACE_INFO_ATTR(bytes_pinned);
 SPACE_INFO_ATTR(bytes_reserved);
 SPACE_INFO_ATTR(bytes_may_use);
+SPACE_INFO_ATTR(bytes_readonly);
 SPACE_INFO_ATTR(disk_used);
 SPACE_INFO_ATTR(disk_total);
 BTRFS_ATTR(total_bytes_pinned, btrfs_space_info_show_total_bytes_pinned);
@@ -337,6 +338,7 @@ static struct attribute *space_info_attrs[] = {
        BTRFS_ATTR_PTR(bytes_pinned),
        BTRFS_ATTR_PTR(bytes_reserved),
        BTRFS_ATTR_PTR(bytes_may_use),
+       BTRFS_ATTR_PTR(bytes_readonly),
        BTRFS_ATTR_PTR(disk_used),
        BTRFS_ATTR_PTR(disk_total),
        BTRFS_ATTR_PTR(total_bytes_pinned),
index 02223f3f78f4b54bc1fca294d71ac75b0e61b2ce..bf62ad919a95db4725483000b6110b6e20890214 100644 (file)
@@ -54,7 +54,7 @@ struct inode *btrfs_new_test_inode(void)
        return new_inode(test_mnt->mnt_sb);
 }
 
-int btrfs_init_test_fs(void)
+static int btrfs_init_test_fs(void)
 {
        int ret;
 
@@ -73,7 +73,7 @@ int btrfs_init_test_fs(void)
        return 0;
 }
 
-void btrfs_destroy_test_fs(void)
+static void btrfs_destroy_test_fs(void)
 {
        kern_unmount(test_mnt);
        unregister_filesystem(&test_type);
@@ -128,14 +128,27 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void)
        extent_io_tree_init(&fs_info->freed_extents[0], NULL);
        extent_io_tree_init(&fs_info->freed_extents[1], NULL);
        fs_info->pinned_extents = &fs_info->freed_extents[0];
+       set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
+
+       test_mnt->mnt_sb->s_fs_info = fs_info;
+
        return fs_info;
 }
 
-static void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
+void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
 {
        struct radix_tree_iter iter;
        void **slot;
 
+       if (!fs_info)
+               return;
+
+       if (WARN_ON(!test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO,
+                             &fs_info->fs_state)))
+               return;
+
+       test_mnt->mnt_sb->s_fs_info = NULL;
+
        spin_lock(&fs_info->buffer_lock);
        radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter, 0) {
                struct extent_buffer *eb;
@@ -167,10 +180,11 @@ void btrfs_free_dummy_root(struct btrfs_root *root)
 {
        if (!root)
                return;
+       /* Will be freed by btrfs_free_fs_roots */
+       if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))
+               return;
        if (root->node)
                free_extent_buffer(root->node);
-       if (root->fs_info)
-               btrfs_free_dummy_fs_info(root->fs_info);
        kfree(root);
 }
 
@@ -220,3 +234,46 @@ void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans)
        INIT_LIST_HEAD(&trans->qgroup_ref_list);
        trans->type = __TRANS_DUMMY;
 }
+
+int btrfs_run_sanity_tests(void)
+{
+       int ret, i;
+       u32 sectorsize, nodesize;
+       u32 test_sectorsize[] = {
+               PAGE_SIZE,
+       };
+       ret = btrfs_init_test_fs();
+       if (ret)
+               return ret;
+       for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
+               sectorsize = test_sectorsize[i];
+               for (nodesize = sectorsize;
+                    nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
+                    nodesize <<= 1) {
+                       pr_info("BTRFS: selftest: sectorsize: %u  nodesize: %u\n",
+                               sectorsize, nodesize);
+                       ret = btrfs_test_free_space_cache(sectorsize, nodesize);
+                       if (ret)
+                               goto out;
+                       ret = btrfs_test_extent_buffer_operations(sectorsize,
+                               nodesize);
+                       if (ret)
+                               goto out;
+                       ret = btrfs_test_extent_io(sectorsize, nodesize);
+                       if (ret)
+                               goto out;
+                       ret = btrfs_test_inodes(sectorsize, nodesize);
+                       if (ret)
+                               goto out;
+                       ret = btrfs_test_qgroups(sectorsize, nodesize);
+                       if (ret)
+                               goto out;
+                       ret = btrfs_test_free_space_tree(sectorsize, nodesize);
+                       if (ret)
+                               goto out;
+               }
+       }
+out:
+       btrfs_destroy_test_fs();
+       return ret;
+}
index 66fb6b701eb72975fa203fd4018ae847cffd46ab..b17ffbe8f9f33651a319dd5574a40320ee476fed 100644 (file)
 #define __BTRFS_TESTS
 
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+int btrfs_run_sanity_tests(void);
 
 #define test_msg(fmt, ...) pr_info("BTRFS: selftest: " fmt, ##__VA_ARGS__)
 
 struct btrfs_root;
 struct btrfs_trans_handle;
 
-int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize);
 int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize);
+int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize);
 int btrfs_test_extent_io(u32 sectorsize, u32 nodesize);
 int btrfs_test_inodes(u32 sectorsize, u32 nodesize);
 int btrfs_test_qgroups(u32 sectorsize, u32 nodesize);
 int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize);
-int btrfs_init_test_fs(void);
-void btrfs_destroy_test_fs(void);
 struct inode *btrfs_new_test_inode(void);
 struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void);
+void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info);
 void btrfs_free_dummy_root(struct btrfs_root *root);
 struct btrfs_block_group_cache *
 btrfs_alloc_dummy_block_group(unsigned long length, u32 sectorsize);
 void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache);
 void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans);
 #else
-static inline int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
-{
-       return 0;
-}
-static inline int btrfs_test_extent_buffer_operations(u32 sectorsize,
-       u32 nodesize)
-{
-       return 0;
-}
-static inline int btrfs_init_test_fs(void)
-{
-       return 0;
-}
-static inline void btrfs_destroy_test_fs(void)
-{
-}
-static inline int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
-{
-       return 0;
-}
-static inline int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
-{
-       return 0;
-}
-static inline int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
-{
-       return 0;
-}
-static inline int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
+static inline int btrfs_run_sanity_tests(void)
 {
        return 0;
 }
index 4f8cbd1ec5ee340d862a8f8c415ce828ebd1a9c8..199569174637481fe2138dc20ea696388f2093f6 100644 (file)
@@ -24,8 +24,9 @@
 
 static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
 {
-       struct btrfs_path *path;
-       struct btrfs_root *root;
+       struct btrfs_fs_info *fs_info;
+       struct btrfs_path *path = NULL;
+       struct btrfs_root *root = NULL;
        struct extent_buffer *eb;
        struct btrfs_item *item;
        char *value = "mary had a little lamb";
@@ -40,17 +41,24 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
 
        test_msg("Running btrfs_split_item tests\n");
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Could not allocate fs_info\n");
+               return -ENOMEM;
+       }
+
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
        if (IS_ERR(root)) {
                test_msg("Could not allocate root\n");
-               return PTR_ERR(root);
+               ret = PTR_ERR(root);
+               goto out;
        }
 
        path = btrfs_alloc_path();
        if (!path) {
                test_msg("Could not allocate path\n");
-               kfree(root);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out;
        }
 
        path->nodes[0] = eb = alloc_dummy_extent_buffer(NULL, nodesize,
@@ -219,7 +227,8 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
        }
 out:
        btrfs_free_path(path);
-       kfree(root);
+       btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
 
index 3956bb2ff84cab59bf25fc9869cebc83d8606621..3221c8dee272f2bebe8afb705c725e7a8ed9b25f 100644 (file)
@@ -837,6 +837,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache,
 
 int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info;
        struct btrfs_block_group_cache *cache;
        struct btrfs_root *root = NULL;
        int ret = -ENOMEM;
@@ -855,15 +856,17 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
                return 0;
        }
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               ret = PTR_ERR(root);
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               ret = -ENOMEM;
                goto out;
        }
 
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info)
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               ret = PTR_ERR(root);
                goto out;
+       }
 
        root->fs_info->extent_root = root;
        cache->fs_info = root->fs_info;
@@ -882,6 +885,7 @@ int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
 out:
        btrfs_free_dummy_block_group(cache);
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        test_msg("Free space cache tests finished\n");
        return ret;
 }
index aac507085ab0958f89a1ce81f0dc69d3824c2a6c..7508d3b427804c0cb634b565e0b625e99a2c0dfc 100644 (file)
@@ -443,23 +443,24 @@ typedef int (*test_func_t)(struct btrfs_trans_handle *,
 static int run_test(test_func_t test_func, int bitmaps,
                u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info;
        struct btrfs_root *root = NULL;
        struct btrfs_block_group_cache *cache = NULL;
        struct btrfs_trans_handle trans;
        struct btrfs_path *path = NULL;
        int ret;
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               test_msg("Couldn't allocate dummy root\n");
-               ret = PTR_ERR(root);
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Couldn't allocate dummy fs info\n");
+               ret = -ENOMEM;
                goto out;
        }
 
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info) {
-               test_msg("Couldn't allocate dummy fs info\n");
-               ret = -ENOMEM;
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               test_msg("Couldn't allocate dummy root\n");
+               ret = PTR_ERR(root);
                goto out;
        }
 
@@ -534,6 +535,7 @@ out:
        btrfs_free_path(path);
        btrfs_free_dummy_block_group(cache);
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
 
index 29648c0a39f1bc380eaffb08f0d574098dc9d343..9f72aeda922041f9bec7de131be16817f38abc19 100644 (file)
@@ -230,6 +230,7 @@ static unsigned long vacancy_only = 0;
 
 static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info = NULL;
        struct inode *inode = NULL;
        struct btrfs_root *root = NULL;
        struct extent_map *em = NULL;
@@ -248,19 +249,15 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
        BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
        BTRFS_I(inode)->location.offset = 0;
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               test_msg("Couldn't allocate root\n");
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Couldn't allocate dummy fs info\n");
                goto out;
        }
 
-       /*
-        * We do this since btrfs_get_extent wants to assign em->bdev to
-        * root->fs_info->fs_devices->latest_bdev.
-        */
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info) {
-               test_msg("Couldn't allocate dummy fs info\n");
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               test_msg("Couldn't allocate root\n");
                goto out;
        }
 
@@ -835,11 +832,13 @@ out:
                free_extent_map(em);
        iput(inode);
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
 
 static int test_hole_first(u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info = NULL;
        struct inode *inode = NULL;
        struct btrfs_root *root = NULL;
        struct extent_map *em = NULL;
@@ -855,15 +854,15 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
        BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
        BTRFS_I(inode)->location.offset = 0;
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               test_msg("Couldn't allocate root\n");
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Couldn't allocate dummy fs info\n");
                goto out;
        }
 
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info) {
-               test_msg("Couldn't allocate dummy fs info\n");
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               test_msg("Couldn't allocate root\n");
                goto out;
        }
 
@@ -934,11 +933,13 @@ out:
                free_extent_map(em);
        iput(inode);
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
 
 static int test_extent_accounting(u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info = NULL;
        struct inode *inode = NULL;
        struct btrfs_root *root = NULL;
        int ret = -ENOMEM;
@@ -949,15 +950,15 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
                return ret;
        }
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               test_msg("Couldn't allocate root\n");
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Couldn't allocate dummy fs info\n");
                goto out;
        }
 
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info) {
-               test_msg("Couldn't allocate dummy fs info\n");
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               test_msg("Couldn't allocate root\n");
                goto out;
        }
 
@@ -1132,6 +1133,7 @@ out:
                                 NULL, GFP_KERNEL);
        iput(inode);
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
 
index 57a12c0d680ba300461ff5ee9714833b541f2810..4407fef7c16c1911cef2c6eec107018b6546d513 100644 (file)
@@ -453,22 +453,24 @@ static int test_multiple_refs(struct btrfs_root *root,
 
 int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
 {
+       struct btrfs_fs_info *fs_info = NULL;
        struct btrfs_root *root;
        struct btrfs_root *tmp_root;
        int ret = 0;
 
-       root = btrfs_alloc_dummy_root(sectorsize, nodesize);
-       if (IS_ERR(root)) {
-               test_msg("Couldn't allocate root\n");
-               return PTR_ERR(root);
+       fs_info = btrfs_alloc_dummy_fs_info();
+       if (!fs_info) {
+               test_msg("Couldn't allocate dummy fs info\n");
+               return -ENOMEM;
        }
 
-       root->fs_info = btrfs_alloc_dummy_fs_info();
-       if (!root->fs_info) {
-               test_msg("Couldn't allocate dummy fs info\n");
-               ret = -ENOMEM;
+       root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
+       if (IS_ERR(root)) {
+               test_msg("Couldn't allocate root\n");
+               ret = PTR_ERR(root);
                goto out;
        }
+
        /* We are using this root as our extent root */
        root->fs_info->extent_root = root;
 
@@ -495,7 +497,7 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
        btrfs_set_header_nritems(root->node, 0);
        root->alloc_bytenr += 2 * nodesize;
 
-       tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize);
+       tmp_root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
        if (IS_ERR(tmp_root)) {
                test_msg("Couldn't allocate a fs root\n");
                ret = PTR_ERR(tmp_root);
@@ -510,7 +512,7 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
                goto out;
        }
 
-       tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize);
+       tmp_root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
        if (IS_ERR(tmp_root)) {
                test_msg("Couldn't allocate a fs root\n");
                ret = PTR_ERR(tmp_root);
@@ -531,5 +533,6 @@ int btrfs_test_qgroups(u32 sectorsize, u32 nodesize)
        ret = test_multiple_refs(root, sectorsize, nodesize);
 out:
        btrfs_free_dummy_root(root);
+       btrfs_free_dummy_fs_info(fs_info);
        return ret;
 }
index 948aa186b353caf55748fd983e975c127b654f0f..9cca0a72196180986b440865221a8aafa5659315 100644 (file)
@@ -561,6 +561,7 @@ again:
        h->transaction = cur_trans;
        h->root = root;
        h->use_count = 1;
+       h->fs_info = root->fs_info;
 
        h->type = type;
        h->can_flush_pending_bgs = true;
@@ -1491,7 +1492,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                goto dir_item_existed;
        } else if (IS_ERR(dir_item)) {
                ret = PTR_ERR(dir_item);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
        btrfs_release_path(path);
@@ -1504,7 +1505,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
         */
        ret = btrfs_run_delayed_items(trans, root);
        if (ret) {      /* Transaction aborted */
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1543,7 +1544,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        if (ret) {
                btrfs_tree_unlock(old);
                free_extent_buffer(old);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1554,7 +1555,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        btrfs_tree_unlock(old);
        free_extent_buffer(old);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
        /* see comments in should_cow_block() */
@@ -1568,7 +1569,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        btrfs_tree_unlock(tmp);
        free_extent_buffer(tmp);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1580,7 +1581,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                 btrfs_ino(parent_inode), index,
                                 dentry->d_name.name, dentry->d_name.len);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1588,19 +1589,19 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
        if (IS_ERR(pending->snap)) {
                ret = PTR_ERR(pending->snap);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
        ret = btrfs_reloc_post_snapshot(trans, pending);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
        ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1622,7 +1623,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        /* We have check then name at the beginning, so it is impossible. */
        BUG_ON(ret == -EEXIST || ret == -EOVERFLOW);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1632,13 +1633,13 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                current_fs_time(parent_inode->i_sb);
        ret = btrfs_update_inode_fallback(trans, parent_root, parent_inode);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
        ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, new_uuid.b,
                                  BTRFS_UUID_KEY_SUBVOL, objectid);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
        if (!btrfs_is_empty_uuid(new_root_item->received_uuid)) {
@@ -1647,14 +1648,14 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                          BTRFS_UUID_KEY_RECEIVED_SUBVOL,
                                          objectid);
                if (ret && ret != -EEXIST) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto fail;
                }
        }
 
        ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto fail;
        }
 
@@ -1709,7 +1710,7 @@ static void update_super_roots(struct btrfs_root *root)
        super->root = root_item->bytenr;
        super->generation = root_item->generation;
        super->root_level = root_item->level;
-       if (btrfs_test_opt(root, SPACE_CACHE))
+       if (btrfs_test_opt(root->fs_info, SPACE_CACHE))
                super->cache_generation = root_item->generation;
        if (root->fs_info->update_uuid_tree_gen)
                super->uuid_tree_generation = root_item->generation;
@@ -1850,7 +1851,7 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
 
        WARN_ON(trans->use_count > 1);
 
-       btrfs_abort_transaction(trans, root, err);
+       btrfs_abort_transaction(trans, err);
 
        spin_lock(&root->fs_info->trans_lock);
 
@@ -1895,14 +1896,14 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
 
 static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
 {
-       if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT))
+       if (btrfs_test_opt(fs_info, FLUSHONCOMMIT))
                return btrfs_start_delalloc_roots(fs_info, 1, -1);
        return 0;
 }
 
 static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info)
 {
-       if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT))
+       if (btrfs_test_opt(fs_info, FLUSHONCOMMIT))
                btrfs_wait_ordered_roots(fs_info, -1, 0, (u64)-1);
 }
 
index c5abee4f01add54f811c78fac76170f8b5c02bb3..efb1226433800b12c83af38fad763eddbbab5cbb 100644 (file)
@@ -128,6 +128,7 @@ struct btrfs_trans_handle {
         * Subvolume quota depends on this
         */
        struct btrfs_root *root;
+       struct btrfs_fs_info *fs_info;
        struct seq_list delayed_ref_elem;
        struct list_head qgroup_ref_list;
        struct list_head new_bgs;
index c05f69a8ec42dad19269620e0ec7e8b38f91ca25..d31a0c4f56bed436e0eb933cceb592fdc498eb53 100644 (file)
@@ -2757,7 +2757,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        while (1) {
                int batch = atomic_read(&root->log_batch);
                /* when we're on an ssd, just kick the log commit out */
-               if (!btrfs_test_opt(root, SSD) &&
+               if (!btrfs_test_opt(root->fs_info, SSD) &&
                    test_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state)) {
                        mutex_unlock(&root->log_mutex);
                        schedule_timeout_uninterruptible(1);
@@ -2788,7 +2788,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark);
        if (ret) {
                blk_finish_plug(&plug);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_free_logged_extents(log, log_transid);
                btrfs_set_log_full_commit(root->fs_info, trans);
                mutex_unlock(&root->log_mutex);
@@ -2838,7 +2838,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                btrfs_set_log_full_commit(root->fs_info, trans);
 
                if (ret != -ENOSPC) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        mutex_unlock(&log_root_tree->log_mutex);
                        goto out;
                }
@@ -2898,7 +2898,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        blk_finish_plug(&plug);
        if (ret) {
                btrfs_set_log_full_commit(root->fs_info, trans);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
                goto out_wake_log_root;
@@ -2934,7 +2934,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
        if (ret) {
                btrfs_set_log_full_commit(root->fs_info, trans);
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out_wake_log_root;
        }
 
@@ -2991,7 +2991,7 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
        ret = walk_log_tree(trans, log, &wc);
        /* I don't think this can happen but just in case */
        if (ret)
-               btrfs_abort_transaction(trans, log, ret);
+               btrfs_abort_transaction(trans, ret);
 
        while (1) {
                ret = find_first_extent_bit(&log->dirty_log_pages,
@@ -3160,7 +3160,7 @@ out_unlock:
                btrfs_set_log_full_commit(root->fs_info, trans);
                ret = 0;
        } else if (ret < 0)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
 
        btrfs_end_log_trans(root);
 
@@ -3193,7 +3193,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
                btrfs_set_log_full_commit(root->fs_info, trans);
                ret = 0;
        } else if (ret < 0 && ret != -ENOENT)
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
        btrfs_end_log_trans(root);
 
        return ret;
@@ -4703,6 +4703,10 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
                ins_nr = 0;
                ret = btrfs_search_forward(root, &min_key,
                                           path, trans->transid);
+               if (ret < 0) {
+                       err = ret;
+                       goto out_unlock;
+               }
                if (ret != 0)
                        break;
 again:
@@ -5301,7 +5305,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
 
        sb = inode->i_sb;
 
-       if (btrfs_test_opt(root, NOTREELOG)) {
+       if (btrfs_test_opt(root->fs_info, NOTREELOG)) {
                ret = 1;
                goto end_no_trans;
        }
index 0fb4a959012e0db9cff59828d6734d0cdfc761f5..bb0addce755865dbb3fb3726998e2792c90205ed 100644 (file)
@@ -140,7 +140,6 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root);
 static void __btrfs_reset_dev_stats(struct btrfs_device *dev);
 static void btrfs_dev_stat_print_on_error(struct btrfs_device *dev);
 static void btrfs_dev_stat_print_on_load(struct btrfs_device *device);
-static void btrfs_close_one_device(struct btrfs_device *device);
 
 DEFINE_MUTEX(uuid_mutex);
 static LIST_HEAD(fs_uuids);
@@ -853,6 +852,46 @@ static void free_device(struct rcu_head *head)
        schedule_work(&device->rcu_work);
 }
 
+static void btrfs_close_one_device(struct btrfs_device *device)
+{
+       struct btrfs_fs_devices *fs_devices = device->fs_devices;
+       struct btrfs_device *new_device;
+       struct rcu_string *name;
+
+       if (device->bdev)
+               fs_devices->open_devices--;
+
+       if (device->writeable &&
+           device->devid != BTRFS_DEV_REPLACE_DEVID) {
+               list_del_init(&device->dev_alloc_list);
+               fs_devices->rw_devices--;
+       }
+
+       if (device->missing)
+               fs_devices->missing_devices--;
+
+       if (device->bdev && device->writeable) {
+               sync_blockdev(device->bdev);
+               invalidate_bdev(device->bdev);
+       }
+
+       new_device = btrfs_alloc_device(NULL, &device->devid,
+                                       device->uuid);
+       BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
+
+       /* Safe because we are under uuid_mutex */
+       if (device->name) {
+               name = rcu_string_strdup(device->name->str, GFP_NOFS);
+               BUG_ON(!name); /* -ENOMEM */
+               rcu_assign_pointer(new_device->name, name);
+       }
+
+       list_replace_rcu(&device->dev_list, &new_device->dev_list);
+       new_device->fs_devices = device->fs_devices;
+
+       call_rcu(&device->rcu, free_device);
+}
+
 static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
        struct btrfs_device *device, *tmp;
@@ -2399,14 +2438,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
                ret = init_first_rw_device(trans, root, device);
                unlock_chunks(root);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto error_trans;
                }
        }
 
        ret = btrfs_add_device(trans, root, device);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto error_trans;
        }
 
@@ -2415,7 +2454,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 
                ret = btrfs_finish_sprout(trans, root);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto error_trans;
                }
 
@@ -2801,7 +2840,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                                            &dev_extent_len);
                if (ret) {
                        mutex_unlock(&fs_devices->device_list_mutex);
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
 
@@ -2820,7 +2859,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                        ret = btrfs_update_device(trans, map->stripes[i].dev);
                        if (ret) {
                                mutex_unlock(&fs_devices->device_list_mutex);
-                               btrfs_abort_transaction(trans, root, ret);
+                               btrfs_abort_transaction(trans, ret);
                                goto out;
                        }
                }
@@ -2829,7 +2868,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
 
        ret = btrfs_free_chunk(trans, root, chunk_objectid, chunk_offset);
        if (ret) {
-               btrfs_abort_transaction(trans, root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -2838,14 +2877,14 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
        if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
                ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       btrfs_abort_transaction(trans, ret);
                        goto out;
                }
        }
 
        ret = btrfs_remove_block_group(trans, extent_root, chunk_offset, em);
        if (ret) {
-               btrfs_abort_transaction(trans, extent_root, ret);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -2902,7 +2941,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
         * chunk tree entries
         */
        ret = btrfs_remove_chunk(trans, root, chunk_offset);
-       btrfs_end_transaction(trans, root);
+       btrfs_end_transaction(trans, extent_root);
        return ret;
 }
 
@@ -3421,7 +3460,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
        u64 size_to_free;
        u64 chunk_type;
        struct btrfs_chunk *chunk;
-       struct btrfs_path *path;
+       struct btrfs_path *path = NULL;
        struct btrfs_key key;
        struct btrfs_key found_key;
        struct btrfs_trans_handle *trans;
@@ -3455,13 +3494,33 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
                ret = btrfs_shrink_device(device, old_size - size_to_free);
                if (ret == -ENOSPC)
                        break;
-               BUG_ON(ret);
+               if (ret) {
+                       /* btrfs_shrink_device never returns ret > 0 */
+                       WARN_ON(ret > 0);
+                       goto error;
+               }
 
                trans = btrfs_start_transaction(dev_root, 0);
-               BUG_ON(IS_ERR(trans));
+               if (IS_ERR(trans)) {
+                       ret = PTR_ERR(trans);
+                       btrfs_info_in_rcu(fs_info,
+                "resize: unable to start transaction after shrinking device %s (error %d), old size %llu, new size %llu",
+                                         rcu_str_deref(device->name), ret,
+                                         old_size, old_size - size_to_free);
+                       goto error;
+               }
 
                ret = btrfs_grow_device(trans, device, old_size);
-               BUG_ON(ret);
+               if (ret) {
+                       btrfs_end_transaction(trans, dev_root);
+                       /* btrfs_grow_device never returns ret > 0 */
+                       WARN_ON(ret > 0);
+                       btrfs_info_in_rcu(fs_info,
+                "resize: unable to grow device after shrinking device %s (error %d), old size %llu, new size %llu",
+                                         rcu_str_deref(device->name), ret,
+                                         old_size, old_size - size_to_free);
+                       goto error;
+               }
 
                btrfs_end_transaction(trans, dev_root);
        }
@@ -3885,7 +3944,7 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
        }
        spin_unlock(&fs_info->balance_lock);
 
-       if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
+       if (btrfs_test_opt(fs_info, SKIP_BALANCE)) {
                btrfs_info(fs_info, "force skipping balance");
                return 0;
        }
@@ -4240,7 +4299,7 @@ int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info)
                                      BTRFS_UUID_TREE_OBJECTID);
        if (IS_ERR(uuid_root)) {
                ret = PTR_ERR(uuid_root);
-               btrfs_abort_transaction(trans, tree_root, ret);
+               btrfs_abort_transaction(trans, ret);
                btrfs_end_transaction(trans, tree_root);
                return ret;
        }
@@ -4514,8 +4573,7 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
        btrfs_set_fs_incompat(info, RAID56);
 }
 
-#define BTRFS_MAX_DEVS(r) ((BTRFS_LEAF_DATA_SIZE(r)            \
-                       - sizeof(struct btrfs_item)             \
+#define BTRFS_MAX_DEVS(r) ((BTRFS_MAX_ITEM_SIZE(r)             \
                        - sizeof(struct btrfs_chunk))           \
                        / sizeof(struct btrfs_stripe) + 1)
 
@@ -6401,7 +6459,8 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
                                   BTRFS_UUID_SIZE);
                map->stripes[i].dev = btrfs_find_device(root->fs_info, devid,
                                                        uuid, NULL);
-               if (!map->stripes[i].dev && !btrfs_test_opt(root, DEGRADED)) {
+               if (!map->stripes[i].dev &&
+                   !btrfs_test_opt(root->fs_info, DEGRADED)) {
                        free_extent_map(em);
                        return -EIO;
                }
@@ -6469,7 +6528,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_root *root,
 
        fs_devices = find_fsid(fsid);
        if (!fs_devices) {
-               if (!btrfs_test_opt(root, DEGRADED))
+               if (!btrfs_test_opt(root->fs_info, DEGRADED))
                        return ERR_PTR(-ENOENT);
 
                fs_devices = alloc_fs_devices(fsid);
@@ -6531,7 +6590,7 @@ static int read_one_dev(struct btrfs_root *root,
 
        device = btrfs_find_device(root->fs_info, devid, dev_uuid, fs_uuid);
        if (!device) {
-               if (!btrfs_test_opt(root, DEGRADED))
+               if (!btrfs_test_opt(root->fs_info, DEGRADED))
                        return -EIO;
 
                device = add_missing_dev(root, fs_devices, devid, dev_uuid);
@@ -6540,7 +6599,7 @@ static int read_one_dev(struct btrfs_root *root,
                btrfs_warn(root->fs_info, "devid %llu uuid %pU missing",
                                devid, dev_uuid);
        } else {
-               if (!device->bdev && !btrfs_test_opt(root, DEGRADED))
+               if (!device->bdev && !btrfs_test_opt(root->fs_info, DEGRADED))
                        return -EIO;
 
                if(!device->bdev && !device->missing) {
@@ -7143,38 +7202,3 @@ void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info)
                fs_devices = fs_devices->seed;
        }
 }
-
-static void btrfs_close_one_device(struct btrfs_device *device)
-{
-       struct btrfs_fs_devices *fs_devices = device->fs_devices;
-       struct btrfs_device *new_device;
-       struct rcu_string *name;
-
-       if (device->bdev)
-               fs_devices->open_devices--;
-
-       if (device->writeable &&
-           device->devid != BTRFS_DEV_REPLACE_DEVID) {
-               list_del_init(&device->dev_alloc_list);
-               fs_devices->rw_devices--;
-       }
-
-       if (device->missing)
-               fs_devices->missing_devices--;
-
-       new_device = btrfs_alloc_device(NULL, &device->devid,
-                                       device->uuid);
-       BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
-
-       /* Safe because we are under uuid_mutex */
-       if (device->name) {
-               name = rcu_string_strdup(device->name->str, GFP_NOFS);
-               BUG_ON(!name); /* -ENOMEM */
-               rcu_assign_pointer(new_device->name, name);
-       }
-
-       list_replace_rcu(&device->dev_list, &new_device->dev_list);
-       new_device->fs_devices = device->fs_devices;
-
-       call_rcu(&device->rcu, free_device);
-}
index 5b81ef304388ed537033e7c4b67850e1385f5e0e..e030d6f6c19acb090348298e664739a8cb06c111 100644 (file)
@@ -66,6 +66,21 @@ struct btrfs_qgroup_extent_record;
        { BTRFS_BLOCK_GROUP_RAID6,      "RAID6"}
 
 #define BTRFS_UUID_SIZE 16
+#define TP_STRUCT__entry_fsid __array(u8, fsid, BTRFS_UUID_SIZE)
+
+#define TP_fast_assign_fsid(fs_info)                                   \
+       memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE)
+
+#define TP_STRUCT__entry_btrfs(args...)                                        \
+       TP_STRUCT__entry(                                               \
+               TP_STRUCT__entry_fsid                                   \
+               args)
+#define TP_fast_assign_btrfs(fs_info, args...)                         \
+       TP_fast_assign(                                                 \
+               TP_fast_assign_fsid(fs_info);                           \
+               args)
+#define TP_printk_btrfs(fmt, args...) \
+       TP_printk("%pU: " fmt, __entry->fsid, args)
 
 TRACE_EVENT(btrfs_transaction_commit,
 
@@ -73,17 +88,17 @@ TRACE_EVENT(btrfs_transaction_commit,
 
        TP_ARGS(root),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  generation                )
                __field(        u64,  root_objectid             )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->generation     = root->fs_info->generation;
                __entry->root_objectid  = root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), gen = %llu",
+       TP_printk_btrfs("root = %llu(%s), gen = %llu",
                  show_root_type(__entry->root_objectid),
                  (unsigned long long)__entry->generation)
 );
@@ -94,7 +109,7 @@ DECLARE_EVENT_CLASS(btrfs__inode,
 
        TP_ARGS(inode),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        ino_t,  ino                     )
                __field(        blkcnt_t,  blocks               )
                __field(        u64,  disk_i_size               )
@@ -104,7 +119,7 @@ DECLARE_EVENT_CLASS(btrfs__inode,
                __field(        u64,  root_objectid             )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_sb(inode->i_sb),
                __entry->ino    = inode->i_ino;
                __entry->blocks = inode->i_blocks;
                __entry->disk_i_size  = BTRFS_I(inode)->disk_i_size;
@@ -115,7 +130,7 @@ DECLARE_EVENT_CLASS(btrfs__inode,
                                BTRFS_I(inode)->root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), gen = %llu, ino = %lu, blocks = %llu, "
+       TP_printk_btrfs("root = %llu(%s), gen = %llu, ino = %lu, blocks = %llu, "
                  "disk_i_size = %llu, last_trans = %llu, logged_trans = %llu",
                  show_root_type(__entry->root_objectid),
                  (unsigned long long)__entry->generation,
@@ -175,7 +190,7 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
 
        TP_CONDITION(map),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  root_objectid     )
                __field(        u64,  start             )
                __field(        u64,  len               )
@@ -187,7 +202,7 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
                __field(        unsigned int,  compress_type    )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->root_objectid  = root->root_key.objectid;
                __entry->start          = map->start;
                __entry->len            = map->len;
@@ -199,7 +214,7 @@ TRACE_EVENT_CONDITION(btrfs_get_extent,
                __entry->compress_type  = map->compress_type;
        ),
 
-       TP_printk("root = %llu(%s), start = %llu, len = %llu, "
+       TP_printk_btrfs("root = %llu(%s), start = %llu, len = %llu, "
                  "orig_start = %llu, block_start = %llu(%s), "
                  "block_len = %llu, flags = %s, refs = %u, "
                  "compress_type = %u",
@@ -233,7 +248,7 @@ DECLARE_EVENT_CLASS(btrfs__ordered_extent,
 
        TP_ARGS(inode, ordered),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        ino_t,  ino             )
                __field(        u64,  file_offset       )
                __field(        u64,  start             )
@@ -246,7 +261,7 @@ DECLARE_EVENT_CLASS(btrfs__ordered_extent,
                __field(        u64,  root_objectid     )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_sb(inode->i_sb),
                __entry->ino            = inode->i_ino;
                __entry->file_offset    = ordered->file_offset;
                __entry->start          = ordered->start;
@@ -260,7 +275,7 @@ DECLARE_EVENT_CLASS(btrfs__ordered_extent,
                                BTRFS_I(inode)->root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), ino = %llu, file_offset = %llu, "
+       TP_printk_btrfs("root = %llu(%s), ino = %llu, file_offset = %llu, "
                  "start = %llu, len = %llu, disk_len = %llu, "
                  "bytes_left = %llu, flags = %s, compress_type = %d, "
                  "refs = %d",
@@ -310,7 +325,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage,
 
        TP_ARGS(page, inode, wbc),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        ino_t,  ino                     )
                __field(        pgoff_t,  index                 )
                __field(        long,   nr_to_write             )
@@ -324,7 +339,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage,
                __field(        u64,    root_objectid           )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_sb(inode->i_sb),
                __entry->ino            = inode->i_ino;
                __entry->index          = page->index;
                __entry->nr_to_write    = wbc->nr_to_write;
@@ -339,7 +354,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage,
                                 BTRFS_I(inode)->root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, "
+       TP_printk_btrfs("root = %llu(%s), ino = %lu, page_index = %lu, "
                  "nr_to_write = %ld, pages_skipped = %ld, range_start = %llu, "
                  "range_end = %llu, for_kupdate = %d, "
                  "for_reclaim = %d, range_cyclic = %d, writeback_index = %lu",
@@ -366,7 +381,7 @@ TRACE_EVENT(btrfs_writepage_end_io_hook,
 
        TP_ARGS(page, start, end, uptodate),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        ino_t,   ino            )
                __field(        pgoff_t, index          )
                __field(        u64,     start          )
@@ -375,7 +390,7 @@ TRACE_EVENT(btrfs_writepage_end_io_hook,
                __field(        u64,    root_objectid   )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_sb(page->mapping->host->i_sb),
                __entry->ino    = page->mapping->host->i_ino;
                __entry->index  = page->index;
                __entry->start  = start;
@@ -385,7 +400,7 @@ TRACE_EVENT(btrfs_writepage_end_io_hook,
                         BTRFS_I(page->mapping->host)->root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, start = %llu, "
+       TP_printk_btrfs("root = %llu(%s), ino = %lu, page_index = %lu, start = %llu, "
                  "end = %llu, uptodate = %d",
                  show_root_type(__entry->root_objectid),
                  (unsigned long)__entry->ino, (unsigned long)__entry->index,
@@ -399,7 +414,7 @@ TRACE_EVENT(btrfs_sync_file,
 
        TP_ARGS(file, datasync),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        ino_t,  ino             )
                __field(        ino_t,  parent          )
                __field(        int,    datasync        )
@@ -410,6 +425,7 @@ TRACE_EVENT(btrfs_sync_file,
                struct dentry *dentry = file->f_path.dentry;
                struct inode *inode = d_inode(dentry);
 
+               TP_fast_assign_fsid(btrfs_sb(file->f_path.dentry->d_sb));
                __entry->ino            = inode->i_ino;
                __entry->parent         = d_inode(dentry->d_parent)->i_ino;
                __entry->datasync       = datasync;
@@ -417,7 +433,7 @@ TRACE_EVENT(btrfs_sync_file,
                                 BTRFS_I(inode)->root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), ino = %ld, parent = %ld, datasync = %d",
+       TP_printk_btrfs("root = %llu(%s), ino = %ld, parent = %ld, datasync = %d",
                  show_root_type(__entry->root_objectid),
                  (unsigned long)__entry->ino, (unsigned long)__entry->parent,
                  __entry->datasync)
@@ -425,19 +441,19 @@ TRACE_EVENT(btrfs_sync_file,
 
 TRACE_EVENT(btrfs_sync_fs,
 
-       TP_PROTO(int wait),
+       TP_PROTO(struct btrfs_fs_info *fs_info, int wait),
 
-       TP_ARGS(wait),
+       TP_ARGS(fs_info, wait),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        int,  wait              )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(fs_info,
                __entry->wait   = wait;
        ),
 
-       TP_printk("wait = %d", __entry->wait)
+       TP_printk_btrfs("wait = %d", __entry->wait)
 );
 
 TRACE_EVENT(btrfs_add_block_group,
@@ -490,13 +506,14 @@ TRACE_EVENT(btrfs_add_block_group,
 
 DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_tree_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action),
+       TP_ARGS(fs_info, ref, full_ref, action),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  bytenr            )
                __field(        u64,  num_bytes         )
                __field(        int,  action            ) 
@@ -507,7 +524,7 @@ DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref,
                __field(        u64,  seq               )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(fs_info,
                __entry->bytenr         = ref->bytenr;
                __entry->num_bytes      = ref->num_bytes;
                __entry->action         = action;
@@ -518,7 +535,7 @@ DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref,
                __entry->seq            = ref->seq;
        ),
 
-       TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
+       TP_printk_btrfs("bytenr = %llu, num_bytes = %llu, action = %s, "
                  "parent = %llu(%s), ref_root = %llu(%s), level = %d, "
                  "type = %s, seq = %llu",
                  (unsigned long long)__entry->bytenr,
@@ -532,31 +549,34 @@ DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref,
 
 DEFINE_EVENT(btrfs_delayed_tree_ref,  add_delayed_tree_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_tree_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action)
+       TP_ARGS(fs_info, ref, full_ref, action)
 );
 
 DEFINE_EVENT(btrfs_delayed_tree_ref,  run_delayed_tree_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_tree_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action)
+       TP_ARGS(fs_info, ref, full_ref, action)
 );
 
 DECLARE_EVENT_CLASS(btrfs_delayed_data_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_data_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action),
+       TP_ARGS(fs_info, ref, full_ref, action),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  bytenr            )
                __field(        u64,  num_bytes         )
                __field(        int,  action            ) 
@@ -568,7 +588,7 @@ DECLARE_EVENT_CLASS(btrfs_delayed_data_ref,
                __field(        u64,  seq               )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(fs_info,
                __entry->bytenr         = ref->bytenr;
                __entry->num_bytes      = ref->num_bytes;
                __entry->action         = action;
@@ -580,7 +600,7 @@ DECLARE_EVENT_CLASS(btrfs_delayed_data_ref,
                __entry->seq            = ref->seq;
        ),
 
-       TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
+       TP_printk_btrfs("bytenr = %llu, num_bytes = %llu, action = %s, "
                  "parent = %llu(%s), ref_root = %llu(%s), owner = %llu, "
                  "offset = %llu, type = %s, seq = %llu",
                  (unsigned long long)__entry->bytenr,
@@ -596,45 +616,48 @@ DECLARE_EVENT_CLASS(btrfs_delayed_data_ref,
 
 DEFINE_EVENT(btrfs_delayed_data_ref,  add_delayed_data_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_data_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action)
+       TP_ARGS(fs_info, ref, full_ref, action)
 );
 
 DEFINE_EVENT(btrfs_delayed_data_ref,  run_delayed_data_ref,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_data_ref *full_ref,
                 int action),
 
-       TP_ARGS(ref, full_ref, action)
+       TP_ARGS(fs_info, ref, full_ref, action)
 );
 
 DECLARE_EVENT_CLASS(btrfs_delayed_ref_head,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_ref_head *head_ref,
                 int action),
 
-       TP_ARGS(ref, head_ref, action),
+       TP_ARGS(fs_info, ref, head_ref, action),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  bytenr            )
                __field(        u64,  num_bytes         )
                __field(        int,  action            ) 
                __field(        int,  is_data           )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(fs_info,
                __entry->bytenr         = ref->bytenr;
                __entry->num_bytes      = ref->num_bytes;
                __entry->action         = action;
                __entry->is_data        = head_ref->is_data;
        ),
 
-       TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, is_data = %d",
+       TP_printk_btrfs("bytenr = %llu, num_bytes = %llu, action = %s, is_data = %d",
                  (unsigned long long)__entry->bytenr,
                  (unsigned long long)__entry->num_bytes,
                  show_ref_action(__entry->action),
@@ -643,20 +666,22 @@ DECLARE_EVENT_CLASS(btrfs_delayed_ref_head,
 
 DEFINE_EVENT(btrfs_delayed_ref_head,  add_delayed_ref_head,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_ref_head *head_ref,
                 int action),
 
-       TP_ARGS(ref, head_ref, action)
+       TP_ARGS(fs_info, ref, head_ref, action)
 );
 
 DEFINE_EVENT(btrfs_delayed_ref_head,  run_delayed_ref_head,
 
-       TP_PROTO(struct btrfs_delayed_ref_node *ref,
+       TP_PROTO(struct btrfs_fs_info *fs_info,
+                struct btrfs_delayed_ref_node *ref,
                 struct btrfs_delayed_ref_head *head_ref,
                 int action),
 
-       TP_ARGS(ref, head_ref, action)
+       TP_ARGS(fs_info, ref, head_ref, action)
 );
 
 #define show_chunk_type(type)                                  \
@@ -678,7 +703,7 @@ DECLARE_EVENT_CLASS(btrfs__chunk,
 
        TP_ARGS(root, map, offset, size),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        int,  num_stripes               )
                __field(        u64,  type                      )
                __field(        int,  sub_stripes               )
@@ -687,7 +712,7 @@ DECLARE_EVENT_CLASS(btrfs__chunk,
                __field(        u64,  root_objectid             )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->num_stripes    = map->num_stripes;
                __entry->type           = map->type;
                __entry->sub_stripes    = map->sub_stripes;
@@ -696,7 +721,7 @@ DECLARE_EVENT_CLASS(btrfs__chunk,
                __entry->root_objectid  = root->root_key.objectid;
        ),
 
-       TP_printk("root = %llu(%s), offset = %llu, size = %llu, "
+       TP_printk_btrfs("root = %llu(%s), offset = %llu, size = %llu, "
                  "num_stripes = %d, sub_stripes = %d, type = %s",
                  show_root_type(__entry->root_objectid),
                  (unsigned long long)__entry->offset,
@@ -728,7 +753,7 @@ TRACE_EVENT(btrfs_cow_block,
 
        TP_ARGS(root, buf, cow),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,  root_objectid             )
                __field(        u64,  buf_start                 )
                __field(        int,  refs                      )
@@ -737,7 +762,7 @@ TRACE_EVENT(btrfs_cow_block,
                __field(        int,  cow_level                 )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->root_objectid  = root->root_key.objectid;
                __entry->buf_start      = buf->start;
                __entry->refs           = atomic_read(&buf->refs);
@@ -746,7 +771,7 @@ TRACE_EVENT(btrfs_cow_block,
                __entry->cow_level      = btrfs_header_level(cow);
        ),
 
-       TP_printk("root = %llu(%s), refs = %d, orig_buf = %llu "
+       TP_printk_btrfs("root = %llu(%s), refs = %d, orig_buf = %llu "
                  "(orig_level = %d), cow_buf = %llu (cow_level = %d)",
                  show_root_type(__entry->root_objectid),
                  __entry->refs,
@@ -763,25 +788,23 @@ TRACE_EVENT(btrfs_space_reservation,
 
        TP_ARGS(fs_info, type, val, bytes, reserve),
 
-       TP_STRUCT__entry(
-               __array(        u8,     fsid,   BTRFS_UUID_SIZE )
+       TP_STRUCT__entry_btrfs(
                __string(       type,   type                    )
                __field(        u64,    val                     )
                __field(        u64,    bytes                   )
                __field(        int,    reserve                 )
        ),
 
-       TP_fast_assign(
-               memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE);
+       TP_fast_assign_btrfs(fs_info,
                __assign_str(type, type);
                __entry->val            = val;
                __entry->bytes          = bytes;
                __entry->reserve        = reserve;
        ),
 
-       TP_printk("%pU: %s: %Lu %s %Lu", __entry->fsid, __get_str(type),
-                 __entry->val, __entry->reserve ? "reserve" : "release",
-                 __entry->bytes)
+       TP_printk_btrfs("%s: %Lu %s %Lu", __get_str(type), __entry->val,
+                       __entry->reserve ? "reserve" : "release",
+                       __entry->bytes)
 );
 
 #define show_flush_action(action)                                              \
@@ -872,22 +895,19 @@ DECLARE_EVENT_CLASS(btrfs__reserved_extent,
 
        TP_ARGS(root, start, len),
 
-       TP_STRUCT__entry(
-               __array(        u8,     fsid,   BTRFS_UUID_SIZE )
-               __field(        u64,    root_objectid           )
-               __field(        u64,    start                   )
-               __field(        u64,    len                     )
+       TP_STRUCT__entry_btrfs(
+               __field(        u64,  root_objectid             )
+               __field(        u64,  start                     )
+               __field(        u64,  len                       )
        ),
 
-       TP_fast_assign(
-               memcpy(__entry->fsid, root->fs_info->fsid, BTRFS_UUID_SIZE);
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->root_objectid  = root->root_key.objectid;
                __entry->start          = start;
                __entry->len            = len;
        ),
 
-       TP_printk("%pU: root = %llu(%s), start = %llu, len = %llu",
-                 __entry->fsid,
+       TP_printk_btrfs("root = %llu(%s), start = %llu, len = %llu",
                  show_root_type(__entry->root_objectid),
                  (unsigned long long)__entry->start,
                  (unsigned long long)__entry->len)
@@ -914,21 +934,21 @@ TRACE_EVENT(find_free_extent,
 
        TP_ARGS(root, num_bytes, empty_size, data),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,    root_objectid           )
                __field(        u64,    num_bytes               )
                __field(        u64,    empty_size              )
                __field(        u64,    data                    )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->root_objectid  = root->root_key.objectid;
                __entry->num_bytes      = num_bytes;
                __entry->empty_size     = empty_size;
                __entry->data           = data;
        ),
 
-       TP_printk("root = %Lu(%s), len = %Lu, empty_size = %Lu, "
+       TP_printk_btrfs("root = %Lu(%s), len = %Lu, empty_size = %Lu, "
                  "flags = %Lu(%s)", show_root_type(__entry->root_objectid),
                  __entry->num_bytes, __entry->empty_size, __entry->data,
                  __print_flags((unsigned long)__entry->data, "|",
@@ -943,8 +963,7 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent,
 
        TP_ARGS(root, block_group, start, len),
 
-       TP_STRUCT__entry(
-               __array(        u8,     fsid,   BTRFS_UUID_SIZE )
+       TP_STRUCT__entry_btrfs(
                __field(        u64,    root_objectid           )
                __field(        u64,    bg_objectid             )
                __field(        u64,    flags                   )
@@ -952,8 +971,7 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent,
                __field(        u64,    len                     )
        ),
 
-       TP_fast_assign(
-               memcpy(__entry->fsid, root->fs_info->fsid, BTRFS_UUID_SIZE);
+       TP_fast_assign_btrfs(root->fs_info,
                __entry->root_objectid  = root->root_key.objectid;
                __entry->bg_objectid    = block_group->key.objectid;
                __entry->flags          = block_group->flags;
@@ -961,8 +979,8 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent,
                __entry->len            = len;
        ),
 
-       TP_printk("%pU: root = %Lu(%s), block_group = %Lu, flags = %Lu(%s), "
-                 "start = %Lu, len = %Lu", __entry->fsid,
+       TP_printk_btrfs("root = %Lu(%s), block_group = %Lu, flags = %Lu(%s), "
+                 "start = %Lu, len = %Lu",
                  show_root_type(__entry->root_objectid), __entry->bg_objectid,
                  __entry->flags, __print_flags((unsigned long)__entry->flags,
                                                "|", BTRFS_GROUP_FLAGS),
@@ -994,7 +1012,7 @@ TRACE_EVENT(btrfs_find_cluster,
 
        TP_ARGS(block_group, start, bytes, empty_size, min_bytes),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,    bg_objectid             )
                __field(        u64,    flags                   )
                __field(        u64,    start                   )
@@ -1003,7 +1021,7 @@ TRACE_EVENT(btrfs_find_cluster,
                __field(        u64,    min_bytes               )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(block_group->fs_info,
                __entry->bg_objectid    = block_group->key.objectid;
                __entry->flags          = block_group->flags;
                __entry->start          = start;
@@ -1012,7 +1030,7 @@ TRACE_EVENT(btrfs_find_cluster,
                __entry->min_bytes      = min_bytes;
        ),
 
-       TP_printk("block_group = %Lu, flags = %Lu(%s), start = %Lu, len = %Lu,"
+       TP_printk_btrfs("block_group = %Lu, flags = %Lu(%s), start = %Lu, len = %Lu,"
                  " empty_size = %Lu, min_bytes = %Lu", __entry->bg_objectid,
                  __entry->flags,
                  __print_flags((unsigned long)__entry->flags, "|",
@@ -1026,15 +1044,15 @@ TRACE_EVENT(btrfs_failed_cluster_setup,
 
        TP_ARGS(block_group),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,    bg_objectid             )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(block_group->fs_info,
                __entry->bg_objectid    = block_group->key.objectid;
        ),
 
-       TP_printk("block_group = %Lu", __entry->bg_objectid)
+       TP_printk_btrfs("block_group = %Lu", __entry->bg_objectid)
 );
 
 TRACE_EVENT(btrfs_setup_cluster,
@@ -1044,7 +1062,7 @@ TRACE_EVENT(btrfs_setup_cluster,
 
        TP_ARGS(block_group, cluster, size, bitmap),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        u64,    bg_objectid             )
                __field(        u64,    flags                   )
                __field(        u64,    start                   )
@@ -1053,7 +1071,7 @@ TRACE_EVENT(btrfs_setup_cluster,
                __field(        int,    bitmap                  )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(block_group->fs_info,
                __entry->bg_objectid    = block_group->key.objectid;
                __entry->flags          = block_group->flags;
                __entry->start          = cluster->window_start;
@@ -1062,7 +1080,7 @@ TRACE_EVENT(btrfs_setup_cluster,
                __entry->bitmap         = bitmap;
        ),
 
-       TP_printk("block_group = %Lu, flags = %Lu(%s), window_start = %Lu, "
+       TP_printk_btrfs("block_group = %Lu, flags = %Lu(%s), window_start = %Lu, "
                  "size = %Lu, max_size = %Lu, bitmap = %d",
                  __entry->bg_objectid,
                  __entry->flags,
@@ -1120,7 +1138,7 @@ DECLARE_EVENT_CLASS(btrfs__work,
 
        TP_ARGS(work),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        void *, work                    )
                __field(        void *, wq                      )
                __field(        void *, func                    )
@@ -1129,7 +1147,7 @@ DECLARE_EVENT_CLASS(btrfs__work,
                __field(        void *, normal_work             )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_work_owner(work),
                __entry->work           = work;
                __entry->wq             = work->wq;
                __entry->func           = work->func;
@@ -1138,7 +1156,7 @@ DECLARE_EVENT_CLASS(btrfs__work,
                __entry->normal_work    = &work->normal_work;
        ),
 
-       TP_printk("work=%p (normal_work=%p), wq=%p, func=%pf, ordered_func=%p,"
+       TP_printk_btrfs("work=%p (normal_work=%p), wq=%p, func=%pf, ordered_func=%p,"
                  " ordered_free=%p",
                  __entry->work, __entry->normal_work, __entry->wq,
                   __entry->func, __entry->ordered_func, __entry->ordered_free)
@@ -1151,15 +1169,15 @@ DECLARE_EVENT_CLASS(btrfs__work__done,
 
        TP_ARGS(work),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        void *, work                    )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_work_owner(work),
                __entry->work           = work;
        ),
 
-       TP_printk("work->%p", __entry->work)
+       TP_printk_btrfs("work->%p", __entry->work)
 );
 
 DEFINE_EVENT(btrfs__work, btrfs_work_queued,
@@ -1196,19 +1214,19 @@ DECLARE_EVENT_CLASS(btrfs__workqueue,
 
        TP_ARGS(wq, name, high),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        void *, wq                      )
                __string(       name,   name                    )
                __field(        int ,   high                    )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_workqueue_owner(wq),
                __entry->wq             = wq;
                __assign_str(name, name);
                __entry->high           = high;
        ),
 
-       TP_printk("name=%s%s, wq=%p", __get_str(name),
+       TP_printk_btrfs("name=%s%s, wq=%p", __get_str(name),
                  __print_flags(__entry->high, "",
                                {(WQ_HIGHPRI),  "-high"}),
                  __entry->wq)
@@ -1227,15 +1245,15 @@ DECLARE_EVENT_CLASS(btrfs__workqueue_done,
 
        TP_ARGS(wq),
 
-       TP_STRUCT__entry(
+       TP_STRUCT__entry_btrfs(
                __field(        void *, wq                      )
        ),
 
-       TP_fast_assign(
+       TP_fast_assign_btrfs(btrfs_workqueue_owner(wq),
                __entry->wq             = wq;
        ),
 
-       TP_printk("wq=%p", __entry->wq)
+       TP_printk_btrfs(