Btrfs: transaction handles everywhere
authorChris Mason <chris.mason@oracle.com>
Fri, 16 Mar 2007 20:20:31 +0000 (16:20 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Fri, 16 Mar 2007 20:20:31 +0000 (16:20 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
16 files changed:
fs/btrfs/Makefile
fs/btrfs/TODO
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/debug-tree.c
fs/btrfs/dir-item.c
fs/btrfs/dir-test.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/inode-item.c
fs/btrfs/print-tree.h
fs/btrfs/quick-test.c
fs/btrfs/random-test.c
fs/btrfs/root-tree.c
fs/btrfs/transaction.h [new file with mode: 0644]

index 36964f54bb47b808d7a8f740588e5e702411a4f2..76bcd87d8575894e4ec4a532e692b2c94ecfbb0c 100644 (file)
@@ -1,5 +1,5 @@
 CC=gcc
-CFLAGS = -g -Wall
+CFLAGS = -g -Wall -Werror
 headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
 objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o \
          root-tree.o dir-item.o hash.o file-item.o inode-item.o
@@ -14,7 +14,7 @@ check=sparse $(CHECKFLAGS)
        $(check) $<
        $(CC) $(CFLAGS) -c $<
 
-all: tester debug-tree quick-test dir-test
+all: tester debug-tree quick-test dir-test tags
 
 debug-tree: $(objects) debug-tree.o
        gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o
index 2ae4b3aae1e5502e6ce96587ac0194e5411629a9..e9894999322e3bf71bd8979eed9e39986abee47d 100644 (file)
@@ -8,6 +8,8 @@
 * Add block mapping tree (simple dm layer)
 * Add simple tree locking (semaphore per tree)
 * Make allocator smarter
+* Only pin blocks allocated in this transaction
+* Add transaction handles
 * Do actual block accounting
 * Check compat and incompat flags on the inode
 * Port into the kernel
index 13128b5ed65c2d89d8b9d47010a119641dcdd6a3..17a3ff2f182818d01a8bdeddb8ad348f740ae298 100644 (file)
@@ -6,17 +6,18 @@
 #include "disk-io.h"
 #include "print-tree.h"
 
-static int split_node(struct btrfs_root *root, struct btrfs_path *path,
-                     int level);
-static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
-                     int data_size);
-static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst,
-                         struct btrfs_buffer *src);
-static int balance_node_right(struct btrfs_root *root,
-                             struct btrfs_buffer *dst_buf,
+static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_path *path, int level);
+static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_path *path, int data_size);
+static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_buffer *dst, struct btrfs_buffer
+                         *src);
+static int balance_node_right(struct btrfs_trans_handle *trans, struct
+                             btrfs_root *root, struct btrfs_buffer *dst_buf,
                              struct btrfs_buffer *src_buf);
-static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
-                  int slot);
+static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_path *path, int level, int slot);
 
 inline void btrfs_init_path(struct btrfs_path *p)
 {
@@ -34,11 +35,10 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
        memset(p, 0, sizeof(*p));
 }
 
-static int btrfs_cow_block(struct btrfs_root *root,
-                   struct btrfs_buffer *buf,
-                   struct btrfs_buffer *parent,
-                   int parent_slot,
-                   struct btrfs_buffer **cow_ret)
+static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
+                          *root, struct btrfs_buffer *buf, struct btrfs_buffer
+                          *parent, int parent_slot, struct btrfs_buffer
+                          **cow_ret)
 {
        struct btrfs_buffer *cow;
 
@@ -46,22 +46,22 @@ static int btrfs_cow_block(struct btrfs_root *root,
                *cow_ret = buf;
                return 0;
        }
-       cow = btrfs_alloc_free_block(root);
+       cow = btrfs_alloc_free_block(trans, root);
        memcpy(&cow->node, &buf->node, root->blocksize);
        btrfs_set_header_blocknr(&cow->node.header, cow->blocknr);
        *cow_ret = cow;
-       btrfs_inc_ref(root, buf);
+       btrfs_inc_ref(trans, root, buf);
        if (buf == root->node) {
                root->node = cow;
                cow->count++;
                if (buf != root->commit_root)
-                       btrfs_free_extent(root, buf->blocknr, 1, 1);
+                       btrfs_free_extent(trans, root, buf->blocknr, 1, 1);
                btrfs_block_release(root, buf);
        } else {
                btrfs_set_node_blockptr(&parent->node, parent_slot,
                                        cow->blocknr);
                BUG_ON(list_empty(&parent->dirty));
-               btrfs_free_extent(root, buf->blocknr, 1, 1);
+               btrfs_free_extent(trans, root, buf->blocknr, 1, 1);
        }
        btrfs_block_release(root, buf);
        return 0;
@@ -266,8 +266,8 @@ static struct btrfs_buffer *read_node_slot(struct btrfs_root *root,
        return read_tree_block(root, btrfs_node_blockptr(node, slot));
 }
 
-static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
-                       int level)
+static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
+                        *root, struct btrfs_path *path, int level)
 {
        struct btrfs_buffer *right_buf;
        struct btrfs_buffer *mid_buf;
@@ -310,8 +310,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
                btrfs_block_release(root, mid_buf);
                /* once for the root ptr */
                btrfs_block_release(root, mid_buf);
-               clean_tree_block(root, mid_buf);
-               return btrfs_free_extent(root, blocknr, 1, 1);
+               clean_tree_block(trans, root, mid_buf);
+               return btrfs_free_extent(trans, root, blocknr, 1, 1);
        }
        parent = &parent_buf->node;
 
@@ -324,11 +324,11 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
 
        /* first, try to make some room in the middle buffer */
        if (left_buf) {
-               btrfs_cow_block(root, left_buf, parent_buf,
-                               pslot - 1, &left_buf);
+               btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
+                               &left_buf);
                left = &left_buf->node;
                orig_slot += btrfs_header_nritems(&left->header);
-               wret = push_node_left(root, left_buf, mid_buf);
+               wret = push_node_left(trans, root, left_buf, mid_buf);
                if (wret < 0)
                        ret = wret;
        }
@@ -337,22 +337,23 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
         * then try to empty the right most buffer into the middle
         */
        if (right_buf) {
-               btrfs_cow_block(root, right_buf, parent_buf,
-                               pslot + 1, &right_buf);
+               btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
+                               &right_buf);
                right = &right_buf->node;
-               wret = push_node_left(root, mid_buf, right_buf);
+               wret = push_node_left(trans, root, mid_buf, right_buf);
                if (wret < 0)
                        ret = wret;
                if (btrfs_header_nritems(&right->header) == 0) {
                        u64 blocknr = right_buf->blocknr;
                        btrfs_block_release(root, right_buf);
-                       clean_tree_block(root, right_buf);
+                       clean_tree_block(trans, root, right_buf);
                        right_buf = NULL;
                        right = NULL;
-                       wret = del_ptr(root, path, level + 1, pslot + 1);
+                       wret = del_ptr(trans, root, path, level + 1, pslot +
+                                      1);
                        if (wret)
                                ret = wret;
-                       wret = btrfs_free_extent(root, blocknr, 1, 1);
+                       wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
                        if (wret)
                                ret = wret;
                } else {
@@ -373,7 +374,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
                 * right
                 */
                BUG_ON(!left_buf);
-               wret = balance_node_right(root, mid_buf, left_buf);
+               wret = balance_node_right(trans, root, mid_buf, left_buf);
                if (wret < 0)
                        ret = wret;
                BUG_ON(wret == 1);
@@ -382,13 +383,13 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
                /* we've managed to empty the middle node, drop it */
                u64 blocknr = mid_buf->blocknr;
                btrfs_block_release(root, mid_buf);
-               clean_tree_block(root, mid_buf);
+               clean_tree_block(trans, root, mid_buf);
                mid_buf = NULL;
                mid = NULL;
-               wret = del_ptr(root, path, level + 1, pslot);
+               wret = del_ptr(trans, root, path, level + 1, pslot);
                if (wret)
                        ret = wret;
-               wret = btrfs_free_extent(root, blocknr, 1, 1);
+               wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
                if (wret)
                        ret = wret;
        } else {
@@ -438,8 +439,9 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
  * possible)
  */
-int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
-               struct btrfs_path *p, int ins_len, int cow)
+int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_path *p, int
+                     ins_len, int cow)
 {
        struct btrfs_buffer *b;
        struct btrfs_buffer *cow_buf;
@@ -455,8 +457,9 @@ again:
                level = btrfs_header_level(&b->node.header);
                if (cow) {
                        int wret;
-                       wret = btrfs_cow_block(root, b, p->nodes[level + 1],
-                                              p->slots[level + 1], &cow_buf);
+                       wret = btrfs_cow_block(trans, root, b, p->nodes[level +
+                                              1], p->slots[level + 1],
+                                              &cow_buf);
                        b = cow_buf;
                }
                BUG_ON(!cow && ins_len);
@@ -472,7 +475,7 @@ again:
                        p->slots[level] = slot;
                        if (ins_len > 0 && btrfs_header_nritems(&c->header) ==
                            BTRFS_NODEPTRS_PER_BLOCK(root)) {
-                               int sret = split_node(root, p, level);
+                               int sret = split_node(trans, root, p, level);
                                BUG_ON(sret > 0);
                                if (sret)
                                        return sret;
@@ -480,7 +483,8 @@ again:
                                c = &b->node;
                                slot = p->slots[level];
                        } else if (ins_len < 0) {
-                               int sret = balance_level(root, p, level);
+                               int sret = balance_level(trans, root, p,
+                                                        level);
                                if (sret)
                                        return sret;
                                b = p->nodes[level];
@@ -496,7 +500,7 @@ again:
                        p->slots[level] = slot;
                        if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
                            sizeof(struct btrfs_item) + ins_len) {
-                               int sret = split_leaf(root, p, ins_len);
+                               int sret = split_leaf(trans, root, p, ins_len);
                                BUG_ON(sret > 0);
                                if (sret)
                                        return sret;
@@ -519,9 +523,9 @@ again:
  * If this fails to write a tree block, it returns -1, but continues
  * fixing up the blocks in ram so the tree is consistent.
  */
-static int fixup_low_keys(struct btrfs_root *root,
-                          struct btrfs_path *path, struct btrfs_disk_key *key,
-                          int level)
+static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_path *path, struct btrfs_disk_key
+                         *key, int level)
 {
        int i;
        int ret = 0;
@@ -546,8 +550,9 @@ static int fixup_low_keys(struct btrfs_root *root,
  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
  * error, and > 0 if there was no room in the left hand block.
  */
-static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
-                         struct btrfs_buffer *src_buf)
+static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_buffer *dst_buf, struct
+                         btrfs_buffer *src_buf)
 {
        struct btrfs_node *src = &src_buf->node;
        struct btrfs_node *dst = &dst_buf->node;
@@ -589,8 +594,8 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
  *
  * this will  only push up to 1/2 the contents of the left node over
  */
-static int balance_node_right(struct btrfs_root *root,
-                             struct btrfs_buffer *dst_buf,
+static int balance_node_right(struct btrfs_trans_handle *trans, struct
+                             btrfs_root *root, struct btrfs_buffer *dst_buf,
                              struct btrfs_buffer *src_buf)
 {
        struct btrfs_node *src = &src_buf->node;
@@ -635,8 +640,8 @@ static int balance_node_right(struct btrfs_root *root,
  *
  * returns zero on success or < 0 on failure.
  */
-static int insert_new_root(struct btrfs_root *root,
-                          struct btrfs_path *path, int level)
+static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
+                          *root, struct btrfs_path *path, int level)
 {
        struct btrfs_buffer *t;
        struct btrfs_node *lower;
@@ -646,7 +651,7 @@ static int insert_new_root(struct btrfs_root *root,
        BUG_ON(path->nodes[level]);
        BUG_ON(path->nodes[level-1] != root->node);
 
-       t = btrfs_alloc_free_block(root);
+       t = btrfs_alloc_free_block(trans, root);
        c = &t->node;
        memset(c, 0, root->blocksize);
        btrfs_set_header_nritems(&c->header, 1);
@@ -679,9 +684,9 @@ static int insert_new_root(struct btrfs_root *root,
  *
  * returns zero on success and < 0 on any error
  */
-static int insert_ptr(struct btrfs_root *root,
-               struct btrfs_path *path, struct btrfs_disk_key *key,
-               u64 blocknr, int slot, int level)
+static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_path *path, struct btrfs_disk_key
+                     *key, u64 blocknr, int slot, int level)
 {
        struct btrfs_node *lower;
        int nritems;
@@ -713,8 +718,8 @@ static int insert_ptr(struct btrfs_root *root,
  *
  * returns 0 on success and < 0 on failure
  */
-static int split_node(struct btrfs_root *root, struct btrfs_path *path,
-                     int level)
+static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_path *path, int level)
 {
        struct btrfs_buffer *t;
        struct btrfs_node *c;
@@ -729,12 +734,12 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path,
        c = &t->node;
        if (t == root->node) {
                /* trying to split the root, lets make a new one */
-               ret = insert_new_root(root, path, level + 1);
+               ret = insert_new_root(trans, root, path, level + 1);
                if (ret)
                        return ret;
        }
        c_nritems = btrfs_header_nritems(&c->header);
-       split_buffer = btrfs_alloc_free_block(root);
+       split_buffer = btrfs_alloc_free_block(trans, root);
        split = &split_buffer->node;
        btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
        btrfs_set_header_blocknr(&split->header, split_buffer->blocknr);
@@ -748,7 +753,7 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path,
        ret = 0;
 
        BUG_ON(list_empty(&t->dirty));
-       wret = insert_ptr(root, path, &split->ptrs[0].key,
+       wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
                          split_buffer->blocknr, path->slots[level + 1] + 1,
                          level + 1);
        if (wret)
@@ -790,8 +795,8 @@ static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
  * returns 1 if the push failed because the other node didn't have enough
  * room, 0 if everything worked out and < 0 if there were major errors.
  */
-static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
-                          int data_size)
+static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
+                          *root, struct btrfs_path *path, int data_size)
 {
        struct btrfs_buffer *left_buf = path->nodes[0];
        struct btrfs_leaf *left = &left_buf->leaf;
@@ -824,7 +829,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
                return 1;
        }
        /* cow and double check */
-       btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf);
+       btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
        right = &right_buf->leaf;
        free_space = btrfs_leaf_free_space(root, right);
        if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -897,8 +902,8 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
  * push some data in the path leaf to the left, trying to free up at
  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
  */
-static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
-                         int data_size)
+static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_path *path, int data_size)
 {
        struct btrfs_buffer *right_buf = path->nodes[0];
        struct btrfs_leaf *right = &right_buf->leaf;
@@ -931,7 +936,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
        }
 
        /* cow and double check */
-       btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t);
+       btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
        left = &t->leaf;
        free_space = btrfs_leaf_free_space(root, left);
        if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -997,7 +1002,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
        BUG_ON(list_empty(&t->dirty));
        BUG_ON(list_empty(&right_buf->dirty));
 
-       wret = fixup_low_keys(root, path, &right->items[0].key, 1);
+       wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
        if (wret)
                ret = wret;
 
@@ -1021,8 +1026,8 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
  *
  * returns 0 if all went well and < 0 on failure.
  */
-static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
-                     int data_size)
+static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_path *path, int data_size)
 {
        struct btrfs_buffer *l_buf;
        struct btrfs_leaf *l;
@@ -1038,11 +1043,11 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
        int ret;
        int wret;
 
-       wret = push_leaf_left(root, path, data_size);
+       wret = push_leaf_left(trans, root, path, data_size);
        if (wret < 0)
                return wret;
        if (wret) {
-               wret = push_leaf_right(root, path, data_size);
+               wret = push_leaf_right(trans, root, path, data_size);
                if (wret < 0)
                        return wret;
        }
@@ -1055,14 +1060,14 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
                return 0;
 
        if (!path->nodes[1]) {
-               ret = insert_new_root(root, path, 1);
+               ret = insert_new_root(trans, root, path, 1);
                if (ret)
                        return ret;
        }
        slot = path->slots[0];
        nritems = btrfs_header_nritems(&l->header);
        mid = (nritems + 1)/ 2;
-       right_buffer = btrfs_alloc_free_block(root);
+       right_buffer = btrfs_alloc_free_block(trans, root);
        BUG_ON(!right_buffer);
        BUG_ON(mid == nritems);
        right = &right_buffer->leaf;
@@ -1100,7 +1105,7 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
 
        btrfs_set_header_nritems(&l->header, mid);
        ret = 0;
-       wret = insert_ptr(root, path, &right->items[0].key,
+       wret = insert_ptr(trans, root, path, &right->items[0].key,
                          right_buffer->blocknr, path->slots[1] + 1, 1);
        if (wret)
                ret = wret;
@@ -1122,8 +1127,9 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
  * Given a key and some data, insert an item into the tree.
  * This does all the path init required, making room in the tree if needed.
  */
-int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path,
-                           struct btrfs_key *cpu_key, u32 data_size)
+int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                           *root, struct btrfs_path *path, struct btrfs_key
+                           *cpu_key, u32 data_size)
 {
        int ret = 0;
        int slot;
@@ -1139,7 +1145,7 @@ int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path,
        /* create a root if there isn't one */
        if (!root->node)
                BUG();
-       ret = btrfs_search_slot(root, cpu_key, path, data_size, 1);
+       ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
        if (ret == 0) {
                btrfs_release_path(root, path);
                return -EEXIST;
@@ -1193,7 +1199,7 @@ int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path,
 
        ret = 0;
        if (slot == 0)
-               ret = fixup_low_keys(root, path, &disk_key, 1);
+               ret = fixup_low_keys(trans, root, path, &disk_key, 1);
 
        BUG_ON(list_empty(&leaf_buf->dirty));
        if (btrfs_leaf_free_space(root, leaf) < 0)
@@ -1207,15 +1213,16 @@ out:
  * Given a key and some data, insert an item into the tree.
  * This does all the path init required, making room in the tree if needed.
  */
-int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
-                         void *data, u32 data_size)
+int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *cpu_key, void *data, u32
+                     data_size)
 {
        int ret = 0;
        struct btrfs_path path;
        u8 *ptr;
 
        btrfs_init_path(&path);
-       ret = btrfs_insert_empty_item(root, &path, cpu_key, data_size);
+       ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size);
        if (!ret) {
                ptr = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], u8);
                memcpy(ptr, data, data_size);
@@ -1231,8 +1238,8 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
  * continuing all the way the root if required.  The root is converted into
  * a leaf if all the nodes are emptied.
  */
-static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
-                  int slot)
+static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_path *path, int level, int slot)
 {
        struct btrfs_node *node;
        struct btrfs_buffer *parent = path->nodes[level];
@@ -1253,7 +1260,7 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
                /* just turn the root into a leaf and break */
                btrfs_set_header_level(&root->node->node.header, 0);
        } else if (slot == 0) {
-               wret = fixup_low_keys(root, path, &node->ptrs[0].key,
+               wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
                                      level + 1);
                if (wret)
                        ret = wret;
@@ -1266,7 +1273,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
  * delete the item at the leaf level in path.  If that empties
  * the leaf, remove it from the tree
  */
-int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
+int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_path *path)
 {
        int slot;
        struct btrfs_leaf *leaf;
@@ -1306,19 +1314,20 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
                        btrfs_set_header_level(&leaf->header, 0);
                        BUG_ON(list_empty(&leaf_buf->dirty));
                } else {
-                       clean_tree_block(root, leaf_buf);
-                       wret = del_ptr(root, path, 1, path->slots[1]);
+                       clean_tree_block(trans, root, leaf_buf);
+                       wret = del_ptr(trans, root, path, 1, path->slots[1]);
                        if (wret)
                                ret = wret;
-                       wret = btrfs_free_extent(root, leaf_buf->blocknr, 1, 1);
+                       wret = btrfs_free_extent(trans, root,
+                                                leaf_buf->blocknr, 1, 1);
                        if (wret)
                                ret = wret;
                }
        } else {
                int used = leaf_space_used(leaf, 0, nritems);
                if (slot == 0) {
-                       wret = fixup_low_keys(root, path,
-                                                  &leaf->items[0].key, 1);
+                       wret = fixup_low_keys(trans, root, path,
+                                             &leaf->items[0].key, 1);
                        if (wret)
                                ret = wret;
                }
@@ -1332,23 +1341,24 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
                         */
                        slot = path->slots[1];
                        leaf_buf->count++;
-                       wret = push_leaf_left(root, path, 1);
+                       wret = push_leaf_left(trans, root, path, 1);
                        if (wret < 0)
                                ret = wret;
                        if (path->nodes[0] == leaf_buf &&
                            btrfs_header_nritems(&leaf->header)) {
-                               wret = push_leaf_right(root, path, 1);
+                               wret = push_leaf_right(trans, root, path, 1);
                                if (wret < 0)
                                        ret = wret;
                        }
                        if (btrfs_header_nritems(&leaf->header) == 0) {
                                u64 blocknr = leaf_buf->blocknr;
-                               clean_tree_block(root, leaf_buf);
-                               wret = del_ptr(root, path, 1, slot);
+                               clean_tree_block(trans, root, leaf_buf);
+                               wret = del_ptr(trans, root, path, 1, slot);
                                if (wret)
                                        ret = wret;
                                btrfs_block_release(root, leaf_buf);
-                               wret = btrfs_free_extent(root, blocknr, 1, 1);
+                               wret = btrfs_free_extent(trans, root, blocknr,
+                                                        1, 1);
                                if (wret)
                                        ret = wret;
                        } else {
@@ -1401,5 +1411,3 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
        }
        return 0;
 }
-
-
index d15a2ed95076dc34ae0cc8514b7d88ead6b3812c..68f0af39777f14c07db95fd85706cb7f52325b85 100644 (file)
@@ -4,6 +4,8 @@
 #include "list.h"
 #include "kerncompat.h"
 
+struct btrfs_trans_handle;
+
 #define BTRFS_MAGIC "_BtRfS_M"
 
 #define BTRFS_ROOT_TREE_OBJECTID 1
@@ -200,6 +202,7 @@ struct btrfs_root {
        struct btrfs_root_item root_item;
        struct btrfs_key root_key;
        u32 blocksize;
+       struct btrfs_trans_handle *running_transaction;
 };
 
 /* the lower bits in the key flags defines the item type */
@@ -656,34 +659,46 @@ static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
        ((type *)(btrfs_leaf_data(leaf) + \
        btrfs_item_offset((leaf)->items + (slot))))
 
-struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root);
-int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf);
-int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
-                     int pin);
-int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
-               struct btrfs_path *p, int ins_len, int cow);
+struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
+                                           struct btrfs_root *root);
+int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                 struct btrfs_buffer *buf);
+int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, u64 blocknr, u64 num_blocks, int pin);
+int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_path *p, int
+                     ins_len, int cow);
 void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p);
 void btrfs_init_path(struct btrfs_path *p);
-int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path);
-int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *key,
-               void *data, u32 data_size);
-int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path,
-                           struct btrfs_key *cpu_key, u32 data_size);
+int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_path *path);
+int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, void *data, u32 data_size);
+int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                           *root, struct btrfs_path *path, struct btrfs_key
+                           *cpu_key, u32 data_size);
 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
 int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf);
-int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap);
-int btrfs_finish_extent_commit(struct btrfs_root *root);
-int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key);
-int btrfs_insert_root(struct btrfs_root *root, struct btrfs_key *key,
-                     struct btrfs_root_item *item);
-int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
-                     struct btrfs_root_item *item);
-int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
-                       struct btrfs_root_item *item, struct btrfs_key *key);
-int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
-                         u64 dir, u64 objectid, u8 type);
-int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path,
-                         u64 dir, char *name, int name_len, int mod);
+int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
+                       *root, struct btrfs_buffer *snap);
+int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
+                              btrfs_root *root);
+int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_key *key);
+int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_root_item
+                     *item);
+int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_root_item
+                     *item);
+int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct
+                        btrfs_root_item *item, struct btrfs_key *key);
+int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, char *name, int name_len, u64 dir, u64
+                         objectid, u8 type);
+int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_path *path, u64 dir, char *name,
+                         int name_len, int mod);
 int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
                              char *name, int name_len);
 #endif
index de45fb4dfdddf14b6082dda3bf63014eb339a888..91dea7a0a476f98aeb7a1816401d4f6319d4a546 100644 (file)
@@ -5,6 +5,7 @@
 #include "ctree.h"
 #include "disk-io.h"
 #include "print-tree.h"
+#include "transaction.h"
 
 int main(int ac, char **av) {
        struct btrfs_super_block super;
index a42a67b99753a55146eb01f8fa14c248db736d9a..949c4e52679807b2a6cedfbd1100c9ce9a261b13 100644 (file)
@@ -5,9 +5,11 @@
 #include "ctree.h"
 #include "disk-io.h"
 #include "hash.h"
+#include "transaction.h"
 
-int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
-                         u64 dir, u64 objectid, u8 type)
+int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, char *name, int name_len, u64 dir, u64
+                         objectid, u8 type)
 {
        int ret = 0;
        struct btrfs_path path;
@@ -23,7 +25,7 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
        BUG_ON(ret);
        btrfs_init_path(&path);
        data_size = sizeof(*dir_item) + name_len;
-       ret = btrfs_insert_empty_item(root, &path, &key, data_size);
+       ret = btrfs_insert_empty_item(trans, root, &path, &key, data_size);
        if (ret)
                goto out;
 
@@ -40,8 +42,9 @@ out:
        return ret;
 }
 
-int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path,
-                         u64 dir, char *name, int name_len, int mod)
+int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_path *path, u64 dir, char *name,
+                         int name_len, int mod)
 {
        int ret;
        struct btrfs_key key;
@@ -53,12 +56,13 @@ int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path,
        btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
        ret = btrfs_name_hash(name, name_len, &key.offset);
        BUG_ON(ret);
-       ret = btrfs_search_slot(root, &key, path, ins_len, cow);
+       ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
        return ret;
 }
 
-int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
-                             char *name, int name_len)
+int btrfs_match_dir_item_name(struct btrfs_root *root,
+                             struct btrfs_path *path, char
+                             *name, int name_len)
 {
        struct btrfs_dir_item *dir_item;
        char *name_ptr;
index f73aa7623398b873977b459d609a57e66d9d1468..e908c0c588cc3397975c751add995a4e16571e84 100644 (file)
@@ -8,6 +8,7 @@
 #include "disk-io.h"
 #include "print-tree.h"
 #include "hash.h"
+#include "transaction.h"
 
 int keep_running = 1;
 struct btrfs_super_block super;
@@ -38,7 +39,8 @@ again:
        return 0;
 }
 
-static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
+static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        int ret;
        char buf[128];
@@ -48,8 +50,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
        find_num(radix, &oid, 0);
        sprintf(buf, "str-%lu", oid);
 
-       ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid,
-                                   1);
+       ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
+                                   file_oid, 1);
        if (ret)
                goto error;
 
@@ -68,7 +70,8 @@ error:
         * check
         */
        btrfs_init_path(&path);
-       ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
+       ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
+                                   strlen(buf), 0);
        if (ret)
                goto fatal_release;
        if (!btrfs_match_dir_item_name(root, &path, buf, strlen(buf))) {
@@ -96,7 +99,8 @@ fatal:
        return -1;
 }
 
-static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
+static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct radix_tree_root *radix)
 {
        int ret;
        char buf[128];
@@ -107,8 +111,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
                return 0;
        sprintf(buf, "str-%lu", oid);
 
-       ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid,
-                                   1);
+       ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
+                                   file_oid, 1);
        if (ret != -EEXIST) {
                printf("insert on %s gave us %d\n", buf, ret);
                return 1;
@@ -116,7 +120,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
        return 0;
 }
 
-static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
+static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        int ret;
        char buf[128];
@@ -129,10 +134,11 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
                return 0;
        sprintf(buf, "str-%lu", oid);
        btrfs_init_path(&path);
-       ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), -1);
+       ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
+                                   strlen(buf), -1);
        if (ret)
                goto out_release;
-       ret = btrfs_del_item(root, &path);
+       ret = btrfs_del_item(trans, root, &path);
        if (ret)
                goto out_release;
        btrfs_release_path(root, &path);
@@ -149,7 +155,8 @@ out:
        return -1;
 }
 
-static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
+static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *root, struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        char buf[128];
@@ -161,7 +168,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
                return 0;
        sprintf(buf, "str-%lu", oid);
        btrfs_init_path(&path);
-       ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
+       ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
+                                   strlen(buf), 0);
        btrfs_release_path(root, &path);
        if (ret) {
                printf("unable to find key %lu\n", oid);
@@ -170,7 +178,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
        return 0;
 }
 
-static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
+static int lookup_enoent(struct btrfs_trans_handle *trans, struct btrfs_root
+                        *root, struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        char buf[128];
@@ -182,7 +191,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
                return 0;
        sprintf(buf, "str-%lu", oid);
        btrfs_init_path(&path);
-       ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
+       ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
+                                   strlen(buf), 0);
        btrfs_release_path(root, &path);
        if (!ret) {
                printf("able to find key that should not exist %lu\n", oid);
@@ -191,8 +201,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
        return 0;
 }
 
-static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
-                     int nr)
+static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct radix_tree_root *radix, int nr)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -211,7 +221,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
        key.objectid = dir_oid;
        while(nr-- >= 0) {
                btrfs_init_path(&path);
-               ret = btrfs_search_slot(root, &key, &path, -1, 1);
+               ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
                if (ret < 0) {
                        btrfs_release_path(root, &path);
                        return ret;
@@ -231,7 +241,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
                BUG_ON(found_len > 128);
                buf[found_len] = '\0';
                found = atoi(buf + 4);
-               ret = btrfs_del_item(root, &path);
+               ret = btrfs_del_item(trans, root, &path);
                count++;
                if (ret) {
                        fprintf(stderr,
@@ -252,19 +262,19 @@ error:
        return -1;
 }
 
-static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
-                    int count)
+static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct radix_tree_root *radix, int count)
 {
        int i;
        int ret = 0;
        for (i = 0; i < count; i++) {
-               ret = ins_one(root, radix);
+               ret = ins_one(trans, root, radix);
                if (ret) {
                        fprintf(stderr, "fill failed\n");
                        goto out;
                }
                if (i % 1000 == 0) {
-                       ret = btrfs_commit_transaction(root, &super);
+                       ret = btrfs_commit_transaction(trans, root, &super);
                        if (ret) {
                                fprintf(stderr, "fill commit failed\n");
                                return ret;
@@ -280,7 +290,8 @@ out:
        return ret;
 }
 
-static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
+static int bulk_op(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        int ret;
        int nr = rand() % 5000;
@@ -289,17 +300,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
        /* do the bulk op much less frequently */
        if (run_nr++ % 100)
                return 0;
-       ret = empty_tree(root, radix, nr);
+       ret = empty_tree(trans, root, radix, nr);
        if (ret)
                return ret;
-       ret = fill_tree(root, radix, nr);
+       ret = fill_tree(trans, root, radix, nr);
        if (ret)
                return ret;
        return 0;
 }
 
 
-int (*ops[])(struct btrfs_root *root, struct radix_tree_root *radix) =
+int (*ops[])(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct
+            radix_tree_root *radix) =
        { ins_one, insert_dup, del_one, lookup_item,
          lookup_enoent, bulk_op };
 
@@ -330,11 +342,13 @@ int main(int ac, char **av)
        int init_fill_count = 800000;
        int err = 0;
        int initial_only = 0;
+       struct btrfs_trans_handle *trans;
        radix_tree_init();
 
        printf("removing old tree\n");
        unlink("dbfile");
        root = open_ctree("dbfile", &super);
+       trans = btrfs_start_transaction(root, 1);
 
        signal(SIGTERM, sigstopper);
        signal(SIGINT, sigstopper);
@@ -353,7 +367,7 @@ int main(int ac, char **av)
                }
        }
        printf("initial fill\n");
-       ret = fill_tree(root, &radix, init_fill_count);
+       ret = fill_tree(trans, root, &radix, init_fill_count);
        printf("starting run\n");
        if (ret) {
                err = ret;
@@ -377,7 +391,7 @@ int main(int ac, char **av)
                        root = open_ctree("dbfile", &super);
                }
                while(count--) {
-                       ret = ops[op](root, &radix);
+                       ret = ops[op](trans, root, &radix);
                        if (ret) {
                                fprintf(stderr, "op %d failed %d:%d\n",
                                        op, i, iterations);
index 8d9457b5aef5704acc09123d5db7702d530d848f..25ce07908ee3f89cb94679932a16d33963785f26 100644 (file)
@@ -9,6 +9,7 @@
 #include "radix-tree.h"
 #include "ctree.h"
 #include "disk-io.h"
+#include "transaction.h"
 
 static int allocated_blocks = 0;
 int cache_max = 10000;
@@ -107,7 +108,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
        return buf;
 }
 
-int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
+int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct btrfs_buffer *buf)
 {
        if (!list_empty(&buf->dirty))
                return 0;
@@ -116,7 +118,8 @@ int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
        return 0;
 }
 
-int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
+int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct btrfs_buffer *buf)
 {
        if (!list_empty(&buf->dirty)) {
                list_del_init(&buf->dirty);
@@ -125,7 +128,8 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
        return 0;
 }
 
-int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
+int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct btrfs_buffer *buf)
 {
        u64 blocknr = buf->blocknr;
        loff_t offset = blocknr * root->blocksize;
@@ -139,7 +143,8 @@ int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
        return 0;
 }
 
-static int __commit_transaction(struct btrfs_root *root)
+static int __commit_transaction(struct btrfs_trans_handle *trans, struct
+                               btrfs_root *root)
 {
        struct btrfs_buffer *b;
        int ret = 0;
@@ -147,7 +152,7 @@ static int __commit_transaction(struct btrfs_root *root)
        while(!list_empty(&root->trans)) {
                b = list_entry(root->trans.next, struct btrfs_buffer, dirty);
                list_del_init(&b->dirty);
-               wret = write_tree_block(root, b);
+               wret = write_tree_block(trans, root, b);
                if (wret)
                        ret = wret;
                btrfs_block_release(root, b);
@@ -155,8 +160,9 @@ static int __commit_transaction(struct btrfs_root *root)
        return ret;
 }
 
-static int commit_extent_and_tree_roots(struct btrfs_root *tree_root,
-                                       struct btrfs_root *extent_root)
+static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans,
+                                       struct btrfs_root *tree_root, struct
+                                       btrfs_root *extent_root)
 {
        int ret;
        u64 old_extent_block;
@@ -167,24 +173,24 @@ static int commit_extent_and_tree_roots(struct btrfs_root *tree_root,
                        break;
                btrfs_set_root_blocknr(&extent_root->root_item,
                                       extent_root->node->blocknr);
-               ret = btrfs_update_root(tree_root,
+               ret = btrfs_update_root(trans, tree_root,
                                        &extent_root->root_key,
                                        &extent_root->root_item);
                BUG_ON(ret);
        }
-       __commit_transaction(extent_root);
-       __commit_transaction(tree_root);
+       __commit_transaction(trans, extent_root);
+       __commit_transaction(trans, tree_root);
        return 0;
 }
 
-int btrfs_commit_transaction(struct btrfs_root *root,
-                            struct btrfs_super_block *s)
+int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
+                            btrfs_root *root, struct btrfs_super_block *s)
 {
        int ret = 0;
        struct btrfs_buffer *snap = root->commit_root;
        struct btrfs_key snap_key;
 
-       ret = __commit_transaction(root);
+       ret = __commit_transaction(trans, root);
        BUG_ON(ret);
 
        if (root->commit_root == root->node)
@@ -194,23 +200,24 @@ int btrfs_commit_transaction(struct btrfs_root *root,
        root->root_key.offset++;
 
        btrfs_set_root_blocknr(&root->root_item, root->node->blocknr);
-       ret = btrfs_insert_root(root->tree_root, &root->root_key,
+       ret = btrfs_insert_root(trans, root->tree_root, &root->root_key,
                                &root->root_item);
        BUG_ON(ret);
 
-       ret = commit_extent_and_tree_roots(root->tree_root, root->extent_root);
+       ret = commit_extent_and_tree_roots(trans, root->tree_root,
+                                          root->extent_root);
        BUG_ON(ret);
 
-        write_ctree_super(root, s);
-       btrfs_finish_extent_commit(root->extent_root);
-       btrfs_finish_extent_commit(root->tree_root);
+       write_ctree_super(trans, root, s);
+       btrfs_finish_extent_commit(trans, root->extent_root);
+       btrfs_finish_extent_commit(trans, root->tree_root);
 
        root->commit_root = root->node;
        root->node->count++;
-       ret = btrfs_drop_snapshot(root, snap);
+       ret = btrfs_drop_snapshot(trans, root, snap);
        BUG_ON(ret);
 
-       ret = btrfs_del_root(root->tree_root, &snap_key);
+       ret = btrfs_del_root(trans, root->tree_root, &snap_key);
        BUG_ON(ret);
 
        return ret;
@@ -312,7 +319,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
        return root;
 }
 
-int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s)
+int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_super_block *s)
 {
        int ret;
        btrfs_set_super_root(s, root->tree_root->node->blocknr);
@@ -338,10 +346,14 @@ static int drop_cache(struct btrfs_root *root)
 int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
 {
        int ret;
-       btrfs_commit_transaction(root, s);
-       ret = commit_extent_and_tree_roots(root->tree_root, root->extent_root);
+       struct btrfs_trans_handle *trans;
+
+       trans = root->running_transaction;
+       btrfs_commit_transaction(trans, root, s);
+       ret = commit_extent_and_tree_roots(trans, root->tree_root,
+                                          root->extent_root);
        BUG_ON(ret);
-       write_ctree_super(root, s);
+       write_ctree_super(trans, root, s);
        drop_cache(root->extent_root);
        drop_cache(root->tree_root);
        drop_cache(root);
index 5771bb90acb21678c452e7d1229bafe193291a2b..24a9e77c831176e93d54bc70c85ab1c58309d705 100644 (file)
@@ -15,15 +15,19 @@ struct btrfs_buffer {
 
 struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr);
 struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr);
-int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf);
-int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf);
-int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf);
-int btrfs_commit_transaction(struct btrfs_root *root,
-                            struct btrfs_super_block *s);
+int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct btrfs_buffer *buf);
+int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct btrfs_buffer *buf);
+int clean_tree_block(struct btrfs_trans_handle *trans,
+                    struct btrfs_root *root, struct btrfs_buffer *buf);
+int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root
+                            *root, struct btrfs_super_block *s);
 struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
 int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s);
 void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf);
-int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s);
+int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                     struct btrfs_super_block *s);
 int mkfs(int fd, u64 num_blocks, u32 blocksize);
 
 #define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
index 4a40282b45f772dc8d32c351b9a3121dccfaedb6..c29b92d440e05bf11c99ee7d2c25e8ad076e38a3 100644 (file)
@@ -5,12 +5,15 @@
 #include "ctree.h"
 #include "disk-io.h"
 #include "print-tree.h"
+#include "transaction.h"
 
-static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
-                           u64 search_start, u64 search_end,
-                           struct btrfs_key *ins);
-static int finish_current_insert(struct btrfs_root *extent_root);
-static int run_pending(struct btrfs_root *extent_root);
+static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                           *orig_root, u64 num_blocks, u64 search_start, u64
+                           search_end, struct btrfs_key *ins);
+static int finish_current_insert(struct btrfs_trans_handle *trans, struct
+                                btrfs_root *extent_root);
+static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *extent_root);
 
 /*
  * pending extents are blocks that we're trying to allocate in the extent
@@ -21,7 +24,8 @@ static int run_pending(struct btrfs_root *extent_root);
  */
 #define CTREE_EXTENT_PENDING_DEL 0
 
-static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
+static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+                        *root, u64 blocknr)
 {
        struct btrfs_path path;
        int ret;
@@ -31,13 +35,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
        struct btrfs_key ins;
        u32 refs;
 
-       find_free_extent(root->extent_root, 0, 0, (u64)-1, &ins);
+       find_free_extent(trans, root->extent_root, 0, 0, (u64)-1, &ins);
        btrfs_init_path(&path);
        key.objectid = blocknr;
        key.flags = 0;
        btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
        key.offset = 1;
-       ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 1);
+       ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 1);
        if (ret != 0)
                BUG();
        BUG_ON(ret != 0);
@@ -48,12 +52,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
 
        BUG_ON(list_empty(&path.nodes[0]->dirty));
        btrfs_release_path(root->extent_root, &path);
-       finish_current_insert(root->extent_root);
-       run_pending(root->extent_root);
+       finish_current_insert(trans, root->extent_root);
+       run_pending(trans, root->extent_root);
        return 0;
 }
 
-static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
+static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+                           *root, u64 blocknr, u32 *refs)
 {
        struct btrfs_path path;
        int ret;
@@ -65,7 +70,7 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
        key.offset = 1;
        key.flags = 0;
        btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
-       ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 0);
+       ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 0);
        if (ret != 0)
                BUG();
        l = &path.nodes[0]->leaf;
@@ -75,7 +80,8 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
        return 0;
 }
 
-int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf)
+int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                 struct btrfs_buffer *buf)
 {
        u64 blocknr;
        int i;
@@ -87,12 +93,13 @@ int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf)
 
        for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
                blocknr = btrfs_node_blockptr(&buf->node, i);
-               inc_block_ref(root, blocknr);
+               inc_block_ref(trans, root, blocknr);
        }
        return 0;
 }
 
-int btrfs_finish_extent_commit(struct btrfs_root *root)
+int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
+                              btrfs_root *root)
 {
        unsigned long gang[8];
        u64 first = 0;
@@ -116,7 +123,8 @@ int btrfs_finish_extent_commit(struct btrfs_root *root)
        return 0;
 }
 
-static int finish_current_insert(struct btrfs_root *extent_root)
+static int finish_current_insert(struct btrfs_trans_handle *trans, struct
+                                btrfs_root *extent_root)
 {
        struct btrfs_key ins;
        struct btrfs_extent_item extent_item;
@@ -132,8 +140,8 @@ static int finish_current_insert(struct btrfs_root *extent_root)
 
        for (i = 0; i < extent_root->current_insert.flags; i++) {
                ins.objectid = extent_root->current_insert.objectid + i;
-               ret = btrfs_insert_item(extent_root, &ins, &extent_item,
-                                 sizeof(extent_item));
+               ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item,
+                                       sizeof(extent_item));
                BUG_ON(ret);
        }
        extent_root->current_insert.offset = 0;
@@ -143,8 +151,8 @@ static int finish_current_insert(struct btrfs_root *extent_root)
 /*
  * remove an extent from the root, returns 0 on success
  */
-static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
-                        int pin)
+static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                        *root, u64 blocknr, u64 num_blocks, int pin)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -160,9 +168,9 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
        btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
        key.offset = num_blocks;
 
-       find_free_extent(root, 0, 0, (u64)-1, &ins);
+       find_free_extent(trans, root, 0, 0, (u64)-1, &ins);
        btrfs_init_path(&path);
-       ret = btrfs_search_slot(extent_root, &key, &path, -1, 1);
+       ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1);
        if (ret) {
                printf("failed to find %Lu\n", key.objectid);
                btrfs_print_tree(extent_root, extent_root->node);
@@ -183,14 +191,14 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
                        BUG_ON(err);
                        radix_tree_preload_end();
                }
-               ret = btrfs_del_item(extent_root, &path);
+               ret = btrfs_del_item(trans, extent_root, &path);
                if (!pin && extent_root->last_insert.objectid > blocknr)
                        extent_root->last_insert.objectid = blocknr;
                if (ret)
                        BUG();
        }
        btrfs_release_path(extent_root, &path);
-       finish_current_insert(extent_root);
+       finish_current_insert(trans, extent_root);
        return ret;
 }
 
@@ -198,7 +206,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
  * find all the blocks marked as pending in the radix tree and remove
  * them from the extent map
  */
-static int del_pending_extents(struct btrfs_root *extent_root)
+static int del_pending_extents(struct btrfs_trans_handle *trans, struct
+                              btrfs_root *extent_root)
 {
        int ret;
        struct btrfs_buffer *gang[4];
@@ -212,7 +221,7 @@ static int del_pending_extents(struct btrfs_root *extent_root)
                if (!ret)
                        break;
                for (i = 0; i < ret; i++) {
-                       ret = __free_extent(extent_root,
+                       ret = __free_extent(trans, extent_root,
                                            gang[i]->blocknr, 1, 1);
                        radix_tree_tag_clear(&extent_root->cache_radix,
                                                gang[i]->blocknr,
@@ -223,11 +232,12 @@ static int del_pending_extents(struct btrfs_root *extent_root)
        return 0;
 }
 
-static int run_pending(struct btrfs_root *extent_root)
+static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *extent_root)
 {
        while(radix_tree_tagged(&extent_root->cache_radix,
                                CTREE_EXTENT_PENDING_DEL))
-               del_pending_extents(extent_root);
+               del_pending_extents(trans, extent_root);
        return 0;
 }
 
@@ -235,8 +245,8 @@ static int run_pending(struct btrfs_root *extent_root)
 /*
  * remove an extent from the root, returns 0 on success
  */
-int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
-                     int pin)
+int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, u64 blocknr, u64 num_blocks, int pin)
 {
        struct btrfs_root *extent_root = root->extent_root;
        struct btrfs_buffer *t;
@@ -249,8 +259,8 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
                                   CTREE_EXTENT_PENDING_DEL);
                return 0;
        }
-       ret = __free_extent(root, blocknr, num_blocks, pin);
-       pending_ret = run_pending(root->extent_root);
+       ret = __free_extent(trans, root, blocknr, num_blocks, pin);
+       pending_ret = run_pending(trans, root->extent_root);
        return ret ? ret : pending_ret;
 }
 
@@ -262,9 +272,9 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
  * ins->offset == number of blocks
  * Any available blocks before search_start are skipped.
  */
-static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
-                           u64 search_start, u64 search_end,
-                           struct btrfs_key *ins)
+static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                           *orig_root, u64 num_blocks, u64 search_start, u64
+                           search_end, struct btrfs_key *ins)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -290,7 +300,7 @@ check_failed:
        ins->objectid = search_start;
        ins->offset = 0;
        start_found = 0;
-       ret = btrfs_search_slot(root, ins, &path, 0, 0);
+       ret = btrfs_search_slot(trans, root, ins, &path, 0, 0);
        if (ret < 0)
                goto error;
 
@@ -367,9 +377,9 @@ error:
  *
  * returns 0 if everything worked, non-zero otherwise.
  */
-static int alloc_extent(struct btrfs_root *root, u64 num_blocks,
-                       u64 search_start, u64 search_end, u64 owner,
-                       struct btrfs_key *ins)
+static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
+                       *root, u64 num_blocks, u64 search_start, u64
+                       search_end, u64 owner, struct btrfs_key *ins)
 {
        int ret;
        int pending_ret;
@@ -389,16 +399,16 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks,
                                extent_root->current_insert.flags++;
                return 0;
        }
-       ret = find_free_extent(root, num_blocks, search_start,
+       ret = find_free_extent(trans, root, num_blocks, search_start,
                               search_end, ins);
        if (ret)
                return ret;
 
-       ret = btrfs_insert_item(extent_root, ins, &extent_item,
-                         sizeof(extent_item));
+       ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
+                               sizeof(extent_item));
 
-       finish_current_insert(extent_root);
-       pending_ret = run_pending(extent_root);
+       finish_current_insert(trans, extent_root);
+       pending_ret = run_pending(trans, extent_root);
        if (ret)
                return ret;
        if (pending_ret)
@@ -410,13 +420,14 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks,
  * helper function to allocate a block for a given tree
  * returns the tree buffer or NULL.
  */
-struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root)
+struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
+                                           struct btrfs_root *root)
 {
        struct btrfs_key ins;
        int ret;
        struct btrfs_buffer *buf;
 
-       ret = alloc_extent(root, 1, 0, (unsigned long)-1,
+       ret = alloc_extent(trans, root, 1, 0, (unsigned long)-1,
                           btrfs_header_parentid(&root->node->node.header),
                           &ins);
        if (ret) {
@@ -424,7 +435,7 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root)
                return NULL;
        }
        buf = find_tree_block(root, ins.objectid);
-       dirty_tree_block(root, buf);
+       dirty_tree_block(trans, root, buf);
        return buf;
 }
 
@@ -432,8 +443,8 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root)
  * helper function for drop_snapshot, this walks down the tree dropping ref
  * counts as it goes.
  */
-static int walk_down_tree(struct btrfs_root *root,
-                         struct btrfs_path *path, int *level)
+static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
+                         *root, struct btrfs_path *path, int *level)
 {
        struct btrfs_buffer *next;
        struct btrfs_buffer *cur;
@@ -441,7 +452,8 @@ static int walk_down_tree(struct btrfs_root *root,
        int ret;
        u32 refs;
 
-       ret = lookup_block_ref(root, path->nodes[*level]->blocknr, &refs);
+       ret = lookup_block_ref(trans, root, path->nodes[*level]->blocknr,
+                              &refs);
        BUG_ON(ret);
        if (refs > 1)
                goto out;
@@ -454,10 +466,10 @@ static int walk_down_tree(struct btrfs_root *root,
                    btrfs_header_nritems(&cur->node.header))
                        break;
                blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]);
-               ret = lookup_block_ref(root, blocknr, &refs);
+               ret = lookup_block_ref(trans, root, blocknr, &refs);
                if (refs != 1 || *level == 1) {
                        path->slots[*level]++;
-                       ret = btrfs_free_extent(root, blocknr, 1, 1);
+                       ret = btrfs_free_extent(trans, root, blocknr, 1, 1);
                        BUG_ON(ret);
                        continue;
                }
@@ -470,7 +482,8 @@ static int walk_down_tree(struct btrfs_root *root,
                path->slots[*level] = 0;
        }
 out:
-       ret = btrfs_free_extent(root, path->nodes[*level]->blocknr, 1, 1);
+       ret = btrfs_free_extent(trans, root, path->nodes[*level]->blocknr, 1,
+                               1);
        btrfs_block_release(root, path->nodes[*level]);
        path->nodes[*level] = NULL;
        *level += 1;
@@ -483,8 +496,8 @@ out:
  * to find the first node higher up where we haven't yet gone through
  * all the slots
  */
-static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path,
-                       int *level)
+static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
+                       *root, struct btrfs_path *path, int *level)
 {
        int i;
        int slot;
@@ -497,8 +510,9 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path,
                        *level = i;
                        return 0;
                } else {
-                       ret = btrfs_free_extent(root,
-                                         path->nodes[*level]->blocknr, 1, 1);
+                       ret = btrfs_free_extent(trans, root,
+                                               path->nodes[*level]->blocknr,
+                                               1, 1);
                        btrfs_block_release(root, path->nodes[*level]);
                        path->nodes[*level] = NULL;
                        *level = i + 1;
@@ -513,7 +527,8 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path,
  * the tree freeing any blocks that have a ref count of zero after being
  * decremented.
  */
-int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap)
+int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
+                       *root, struct btrfs_buffer *snap)
 {
        int ret = 0;
        int wret;
@@ -529,13 +544,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap)
        path.nodes[level] = snap;
        path.slots[level] = 0;
        while(1) {
-               wret = walk_down_tree(root, &path, &level);
+               wret = walk_down_tree(trans, root, &path, &level);
                if (wret > 0)
                        break;
                if (wret < 0)
                        ret = wret;
 
-               wret = walk_up_tree(root, &path, &level);
+               wret = walk_up_tree(trans, root, &path, &level);
                if (wret > 0)
                        break;
                if (wret < 0)
index 4908f9afdf86ba24c29a222ea0a1f245ab239f3e..7caeb11e875620cb2b0a32d5fe755d56abb8899b 100644 (file)
@@ -4,9 +4,11 @@
 #include "radix-tree.h"
 #include "ctree.h"
 #include "disk-io.h"
+#include "transaction.h"
 
-int btrfs_insert_inode(struct btrfs_root *root, u64 objectid,
-                      struct btrfs_inode_item *inode_item)
+int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *root, u64 objectid, struct btrfs_inode_item
+                      *inode_item)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -17,13 +19,14 @@ int btrfs_insert_inode(struct btrfs_root *root, u64 objectid,
        key.offset = 0;
 
        btrfs_init_path(&path);
-       ret = btrfs_insert_item(root, &key, inode_item, sizeof(*inode_item));
+       ret = btrfs_insert_item(trans, root, &key, inode_item,
+                               sizeof(*inode_item));
        btrfs_release_path(root, &path);
        return ret;
 }
 
-int btrfs_lookup_inode(struct btrfs_root *root, struct btrfs_path *path,
-                       u64 objectid, int mod)
+int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *root, struct btrfs_path *path, u64 objectid, int mod)
 {
        struct btrfs_key key;
        int ins_len = mod < 0 ? -1 : 0;
@@ -33,5 +36,5 @@ int btrfs_lookup_inode(struct btrfs_root *root, struct btrfs_path *path,
        key.flags = 0;
        btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
        key.offset = 0;
-       return btrfs_search_slot(root, &key, path, ins_len, cow);
+       return btrfs_search_slot(trans, root, &key, path, ins_len, cow);
 }
index 9236abda2a74e1317216d35a867d019d807dcf56..0882ca904ecaf17fce1bcfa75489393edf6a54ce 100644 (file)
@@ -1,3 +1,5 @@
-
+#ifndef __PRINT_TREE_
+#define __PRINT_TREE_
 void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l);
 void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t);
+#endif
index 3a257161712148da64857e7650ca1b594d1ff0ca..d676577185d559d53827fe4566fb16fcdc810209 100644 (file)
@@ -5,6 +5,7 @@
 #include "ctree.h"
 #include "disk-io.h"
 #include "print-tree.h"
+#include "transaction.h"
 
 /* for testing only */
 int next_key(int i, int max_key) {
@@ -25,10 +26,12 @@ int main(int ac, char **av) {
        struct btrfs_path path;
        struct btrfs_super_block super;
        struct btrfs_root *root;
+       struct btrfs_trans_handle *trans;
 
        radix_tree_init();
 
        root = open_ctree("dbfile", &super);
+       trans = btrfs_start_transaction(root, 1);
        srand(55);
        ins.flags = 0;
        btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY);
@@ -41,12 +44,12 @@ int main(int ac, char **av) {
                        fprintf(stderr, "insert %d:%d\n", num, i);
                ins.objectid = num;
                ins.offset = 0;
-               ret = btrfs_insert_item(root, &ins, buf, strlen(buf));
+               ret = btrfs_insert_item(trans, root, &ins, buf, strlen(buf));
                if (!ret)
                        tree_size++;
                free(buf);
                if (i == run_size - 5) {
-                       btrfs_commit_transaction(root, &super);
+                       btrfs_commit_transaction(trans, root, &super);
                }
 
        }
@@ -61,7 +64,7 @@ int main(int ac, char **av) {
                btrfs_init_path(&path);
                if (i % 10000 == 0)
                        fprintf(stderr, "search %d:%d\n", num, i);
-               ret = btrfs_search_slot(root, &ins, &path, 0, 0);
+               ret = btrfs_search_slot(trans, root, &ins, &path, 0, 0);
                if (ret) {
                        btrfs_print_tree(root, root->node);
                        printf("unable to find %d\n", num);
@@ -83,11 +86,11 @@ int main(int ac, char **av) {
                num = next_key(i, max_key);
                ins.objectid = num;
                btrfs_init_path(&path);
-               ret = btrfs_search_slot(root, &ins, &path, -1, 1);
+               ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1);
                if (!ret) {
                        if (i % 10000 == 0)
                                fprintf(stderr, "del %d:%d\n", num, i);
-                       ret = btrfs_del_item(root, &path);
+                       ret = btrfs_del_item(trans, root, &path);
                        if (ret != 0)
                                BUG();
                        tree_size--;
@@ -104,7 +107,7 @@ int main(int ac, char **av) {
                ins.objectid = num;
                if (i % 10000 == 0)
                        fprintf(stderr, "insert %d:%d\n", num, i);
-               ret = btrfs_insert_item(root, &ins, buf, strlen(buf));
+               ret = btrfs_insert_item(trans, root, &ins, buf, strlen(buf));
                if (!ret)
                        tree_size++;
                free(buf);
@@ -119,7 +122,7 @@ int main(int ac, char **av) {
                btrfs_init_path(&path);
                if (i % 10000 == 0)
                        fprintf(stderr, "search %d:%d\n", num, i);
-               ret = btrfs_search_slot(root, &ins, &path, 0, 0);
+               ret = btrfs_search_slot(trans, root, &ins, &path, 0, 0);
                if (ret) {
                        btrfs_print_tree(root, root->node);
                        printf("unable to find %d\n", num);
@@ -134,7 +137,7 @@ int main(int ac, char **av) {
                int slot;
                ins.objectid = (u64)-1;
                btrfs_init_path(&path);
-               ret = btrfs_search_slot(root, &ins, &path, -1, 1);
+               ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1);
                if (ret == 0)
                        BUG();
 
@@ -150,7 +153,7 @@ int main(int ac, char **av) {
                        btrfs_disk_key_to_cpu(&last, &leaf->items[slot].key);
                        if (tree_size % 10000 == 0)
                                printf("big del %d:%d\n", tree_size, i);
-                       ret = btrfs_del_item(root, &path);
+                       ret = btrfs_del_item(trans, root, &path);
                        if (ret != 0) {
                                printf("del_item returned %d\n", ret);
                                BUG();
@@ -165,7 +168,7 @@ int main(int ac, char **av) {
        printf("map before commit\n");
        btrfs_print_tree(root->extent_root, root->extent_root->node);
        */
-       btrfs_commit_transaction(root, &super);
+       btrfs_commit_transaction(trans, root, &super);
        printf("tree size is now %d\n", tree_size);
        printf("root %p commit root %p\n", root->node, root->commit_root);
        printf("map tree\n");
index f05135f13f9a0afc120755d209c20886fa35f3ed..3a38ae7a886d6db89cd6f2b7e4a3f808386f9148 100644 (file)
@@ -6,6 +6,7 @@
 #include "ctree.h"
 #include "disk-io.h"
 #include "print-tree.h"
+#include "transaction.h"
 
 int keep_running = 1;
 struct btrfs_super_block super;
@@ -37,7 +38,8 @@ again:
        return 0;
 }
 
-static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
+static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -47,7 +49,7 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
        btrfs_init_path(&path);
        ret = setup_key(radix, &key, 0);
        sprintf(buf, "str-%Lu\n", key.objectid);
-       ret = btrfs_insert_item(root, &key, buf, strlen(buf));
+       ret = btrfs_insert_item(trans, root, &key, buf, strlen(buf));
        if (ret)
                goto error;
        oid = (unsigned long)key.objectid;
@@ -62,7 +64,8 @@ error:
        return -1;
 }
 
-static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
+static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -73,7 +76,7 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
        if (ret < 0)
                return 0;
        sprintf(buf, "str-%Lu\n", key.objectid);
-       ret = btrfs_insert_item(root, &key, buf, strlen(buf));
+       ret = btrfs_insert_item(trans, root, &key, buf, strlen(buf));
        if (ret != -EEXIST) {
                printf("insert on %Lu gave us %d\n", key.objectid, ret);
                return 1;
@@ -81,7 +84,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
        return 0;
 }
 
-static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
+static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -91,10 +95,10 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
        ret = setup_key(radix, &key, 1);
        if (ret < 0)
                return 0;
-       ret = btrfs_search_slot(root, &key, &path, -1, 1);
+       ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
        if (ret)
                goto error;
-       ret = btrfs_del_item(root, &path);
+       ret = btrfs_del_item(trans, root, &path);
        btrfs_release_path(root, &path);
        if (ret != 0)
                goto error;
@@ -107,7 +111,8 @@ error:
        return -1;
 }
 
-static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
+static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
+                      *root, struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -116,7 +121,7 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
        ret = setup_key(radix, &key, 1);
        if (ret < 0)
                return 0;
-       ret = btrfs_search_slot(root, &key, &path, 0, 1);
+       ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
        btrfs_release_path(root, &path);
        if (ret)
                goto error;
@@ -126,7 +131,8 @@ error:
        return -1;
 }
 
-static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
+static int lookup_enoent(struct btrfs_trans_handle *trans, struct btrfs_root
+                        *root, struct radix_tree_root *radix)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -135,7 +141,7 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
        ret = setup_key(radix, &key, 0);
        if (ret < 0)
                return ret;
-       ret = btrfs_search_slot(root, &key, &path, 0, 0);
+       ret = btrfs_search_slot(trans, root, &key, &path, 0, 0);
        btrfs_release_path(root, &path);
        if (ret <= 0)
                goto error;
@@ -145,8 +151,8 @@ error:
        return -1;
 }
 
-static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
-                     int nr)
+static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct radix_tree_root *radix, int nr)
 {
        struct btrfs_path path;
        struct btrfs_key key;
@@ -162,7 +168,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
        key.objectid = (unsigned long)-1;
        while(nr-- >= 0) {
                btrfs_init_path(&path);
-               ret = btrfs_search_slot(root, &key, &path, -1, 1);
+               ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
                if (ret < 0) {
                        btrfs_release_path(root, &path);
                        return ret;
@@ -177,7 +183,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
                slot = path.slots[0];
                found = btrfs_disk_key_objectid(
                                        &path.nodes[0]->leaf.items[slot].key);
-               ret = btrfs_del_item(root, &path);
+               ret = btrfs_del_item(trans, root, &path);
                count++;
                if (ret) {
                        fprintf(stderr,
@@ -198,19 +204,19 @@ error:
        return -1;
 }
 
-static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
-                    int count)
+static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                    struct radix_tree_root *radix, int count)
 {
        int i;
        int ret = 0;
        for (i = 0; i < count; i++) {
-               ret = ins_one(root, radix);
+               ret = ins_one(trans, root, radix);
                if (ret) {
                        fprintf(stderr, "fill failed\n");
                        goto out;
                }
                if (i % 1000 == 0) {
-                       ret = btrfs_commit_transaction(root, &super);
+                       ret = btrfs_commit_transaction(trans, root, &super);
                        if (ret) {
                                fprintf(stderr, "fill commit failed\n");
                                return ret;
@@ -226,7 +232,8 @@ out:
        return ret;
 }
 
-static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
+static int bulk_op(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct radix_tree_root *radix)
 {
        int ret;
        int nr = rand() % 5000;
@@ -235,17 +242,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
        /* do the bulk op much less frequently */
        if (run_nr++ % 100)
                return 0;
-       ret = empty_tree(root, radix, nr);
+       ret = empty_tree(trans, root, radix, nr);
        if (ret)
                return ret;
-       ret = fill_tree(root, radix, nr);
+       ret = fill_tree(trans, root, radix, nr);
        if (ret)
                return ret;
        return 0;
 }
 
 
-int (*ops[])(struct btrfs_root *root, struct radix_tree_root *radix) =
+int (*ops[])(struct btrfs_trans_handle *,
+            struct btrfs_root *root, struct radix_tree_root *radix) =
        { ins_one, insert_dup, del_one, lookup_item,
          lookup_enoent, bulk_op };
 
@@ -264,7 +272,7 @@ static int fill_radix(struct btrfs_root *root, struct radix_tree_root *radix)
        key.objectid = (unsigned long)-1;
        while(1) {
                btrfs_init_path(&path);
-               ret = btrfs_search_slot(root, &key, &path, 0, 0);
+               ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
                if (ret < 0) {
                        btrfs_release_path(root, &path);
                        return ret;
@@ -325,6 +333,7 @@ int main(int ac, char **av)
        int init_fill_count = 800000;
        int err = 0;
        int initial_only = 0;
+       struct btrfs_trans_handle *trans;
        radix_tree_init();
        root = open_ctree("dbfile", &super);
        fill_radix(root, &radix);
@@ -346,7 +355,8 @@ int main(int ac, char **av)
                }
        }
        printf("initial fill\n");
-       ret = fill_tree(root, &radix, init_fill_count);
+       trans = btrfs_start_transaction(root, 1);
+       ret = fill_tree(trans, root, &radix, init_fill_count);
        printf("starting run\n");
        if (ret) {
                err = ret;
@@ -370,7 +380,7 @@ int main(int ac, char **av)
                        root = open_ctree("dbfile", &super);
                }
                while(count--) {
-                       ret = ops[op](root, &radix);
+                       ret = ops[op](trans, root, &radix);
                        if (ret) {
                                fprintf(stderr, "op %d failed %d:%d\n",
                                        op, i, iterations);
index a24b472740374b80a9c484ea66fa7efd7f1f3a92..9cccecc0f431c7771e891b824fa66db7365cd815 100644 (file)
@@ -20,7 +20,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
        search_key.offset = (u32)-1;
 
        btrfs_init_path(&path);
-       ret = btrfs_search_slot(root, &search_key, &path, 0, 0);
+       ret = btrfs_search_slot(NULL, root, &search_key, &path, 0, 0);
        if (ret < 0)
                goto out;
        BUG_ON(ret == 0);
@@ -40,8 +40,9 @@ out:
        return ret;
 }
 
-int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
-                     struct btrfs_root_item *item)
+int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_root_item
+                     *item)
 {
        struct btrfs_path path;
        struct btrfs_leaf *l;
@@ -49,7 +50,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
        int slot;
 
        btrfs_init_path(&path);
-       ret = btrfs_search_slot(root, key, &path, 0, 1);
+       ret = btrfs_search_slot(trans, root, key, &path, 0, 1);
        if (ret < 0)
                goto out;
        BUG_ON(ret != 0);
@@ -62,26 +63,28 @@ out:
        return ret;
 }
 
-int btrfs_insert_root(struct btrfs_root *root, struct btrfs_key *key,
-                     struct btrfs_root_item *item)
+int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
+                     *root, struct btrfs_key *key, struct btrfs_root_item
+                     *item)
 {
        int ret;
-       ret = btrfs_insert_item(root, key, item, sizeof(*item));
+       ret = btrfs_insert_item(trans, root, key, item, sizeof(*item));
        BUG_ON(ret);
        return ret;
 }
 
-int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key)
+int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+                  struct btrfs_key *key)
 {
        struct btrfs_path path;
        int ret;
 
        btrfs_init_path(&path);
-       ret = btrfs_search_slot(root, key, &path, -1, 1);
+       ret = btrfs_search_slot(trans, root, key, &path, -1, 1);
        if (ret < 0)
                goto out;
        BUG_ON(ret != 0);
-       ret = btrfs_del_item(root, &path);
+       ret = btrfs_del_item(trans, root, &path);
 out:
        btrfs_release_path(root, &path);
        return ret;
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
new file mode 100644 (file)
index 0000000..3adb6e6
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __TRANSACTION__
+#define __TRANSACTION__
+
+struct btrfs_trans_handle {
+       u64 transid;
+       unsigned long blocks_reserved;
+       unsigned long blocks_used;
+};
+
+static inline struct btrfs_trans_handle *
+btrfs_start_transaction(struct btrfs_root *root, int num_blocks)
+{
+       struct btrfs_trans_handle *h = malloc(sizeof(*h));
+       h->transid = root->root_key.offset;
+       h->blocks_reserved = num_blocks;
+       h->blocks_used = 0;
+       return h;
+}
+
+static inline void btrfs_free_transaction(struct btrfs_root *root,
+                                         struct btrfs_trans_handle *handle)
+{
+       memset(handle, 0, sizeof(*handle));
+       free(handle);
+}
+
+#endif