提交 e089f05c 编写于 作者: C Chris Mason 提交者: David Woodhouse

Btrfs: transaction handles everywhere

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 88fd146c
CC=gcc 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 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 \ 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 root-tree.o dir-item.o hash.o file-item.o inode-item.o
...@@ -14,7 +14,7 @@ check=sparse $(CHECKFLAGS) ...@@ -14,7 +14,7 @@ check=sparse $(CHECKFLAGS)
$(check) $< $(check) $<
$(CC) $(CFLAGS) -c $< $(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 debug-tree: $(objects) debug-tree.o
gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* Add block mapping tree (simple dm layer) * Add block mapping tree (simple dm layer)
* Add simple tree locking (semaphore per tree) * Add simple tree locking (semaphore per tree)
* Make allocator smarter * Make allocator smarter
* Only pin blocks allocated in this transaction
* Add transaction handles
* Do actual block accounting * Do actual block accounting
* Check compat and incompat flags on the inode * Check compat and incompat flags on the inode
* Port into the kernel * Port into the kernel
......
此差异已折叠。
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "list.h" #include "list.h"
#include "kerncompat.h" #include "kerncompat.h"
struct btrfs_trans_handle;
#define BTRFS_MAGIC "_BtRfS_M" #define BTRFS_MAGIC "_BtRfS_M"
#define BTRFS_ROOT_TREE_OBJECTID 1 #define BTRFS_ROOT_TREE_OBJECTID 1
...@@ -200,6 +202,7 @@ struct btrfs_root { ...@@ -200,6 +202,7 @@ struct btrfs_root {
struct btrfs_root_item root_item; struct btrfs_root_item root_item;
struct btrfs_key root_key; struct btrfs_key root_key;
u32 blocksize; u32 blocksize;
struct btrfs_trans_handle *running_transaction;
}; };
/* the lower bits in the key flags defines the item type */ /* 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) ...@@ -656,34 +659,46 @@ static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
((type *)(btrfs_leaf_data(leaf) + \ ((type *)(btrfs_leaf_data(leaf) + \
btrfs_item_offset((leaf)->items + (slot)))) btrfs_item_offset((leaf)->items + (slot))))
struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root); struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf); struct btrfs_root *root);
int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int pin); struct btrfs_buffer *buf);
int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key, int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_path *p, int ins_len, int cow); *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_release_path(struct btrfs_root *root, struct btrfs_path *p);
void btrfs_init_path(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_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *key, struct btrfs_path *path);
void *data, u32 data_size); int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path, *root, struct btrfs_key *key, void *data, u32 data_size);
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 btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 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_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_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
int btrfs_finish_extent_commit(struct btrfs_root *root); *root, struct btrfs_buffer *snap);
int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key); int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
int btrfs_insert_root(struct btrfs_root *root, struct btrfs_key *key, btrfs_root *root);
struct btrfs_root_item *item); int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key, struct btrfs_key *key);
struct btrfs_root_item *item); int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, *root, struct btrfs_key *key, struct btrfs_root_item
struct btrfs_root_item *item, struct btrfs_key *key); *item);
int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len, int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
u64 dir, u64 objectid, u8 type); *root, struct btrfs_key *key, struct btrfs_root_item
int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path, *item);
u64 dir, char *name, int name_len, int mod); 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, int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
char *name, int name_len); char *name, int name_len);
#endif #endif
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "print-tree.h" #include "print-tree.h"
#include "transaction.h"
int main(int ac, char **av) { int main(int ac, char **av) {
struct btrfs_super_block super; struct btrfs_super_block super;
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "hash.h" #include "hash.h"
#include "transaction.h"
int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len, int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
u64 dir, u64 objectid, u8 type) *root, char *name, int name_len, u64 dir, u64
objectid, u8 type)
{ {
int ret = 0; int ret = 0;
struct btrfs_path path; struct btrfs_path path;
...@@ -23,7 +25,7 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len, ...@@ -23,7 +25,7 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
BUG_ON(ret); BUG_ON(ret);
btrfs_init_path(&path); btrfs_init_path(&path);
data_size = sizeof(*dir_item) + name_len; 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) if (ret)
goto out; goto out;
...@@ -40,8 +42,9 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len, ...@@ -40,8 +42,9 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
return ret; return ret;
} }
int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path, int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
u64 dir, char *name, int name_len, int mod) *root, struct btrfs_path *path, u64 dir, char *name,
int name_len, int mod)
{ {
int ret; int ret;
struct btrfs_key key; struct btrfs_key key;
...@@ -53,12 +56,13 @@ int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path, ...@@ -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); btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
ret = btrfs_name_hash(name, name_len, &key.offset); ret = btrfs_name_hash(name, name_len, &key.offset);
BUG_ON(ret); 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; return ret;
} }
int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path, int btrfs_match_dir_item_name(struct btrfs_root *root,
char *name, int name_len) struct btrfs_path *path, char
*name, int name_len)
{ {
struct btrfs_dir_item *dir_item; struct btrfs_dir_item *dir_item;
char *name_ptr; char *name_ptr;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "disk-io.h" #include "disk-io.h"
#include "print-tree.h" #include "print-tree.h"
#include "hash.h" #include "hash.h"
#include "transaction.h"
int keep_running = 1; int keep_running = 1;
struct btrfs_super_block super; struct btrfs_super_block super;
...@@ -38,7 +39,8 @@ static int find_num(struct radix_tree_root *root, unsigned long *num_ret, ...@@ -38,7 +39,8 @@ static int find_num(struct radix_tree_root *root, unsigned long *num_ret,
return 0; 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; int ret;
char buf[128]; char buf[128];
...@@ -48,8 +50,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -48,8 +50,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
find_num(radix, &oid, 0); find_num(radix, &oid, 0);
sprintf(buf, "str-%lu", oid); sprintf(buf, "str-%lu", oid);
ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid, ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
1); file_oid, 1);
if (ret) if (ret)
goto error; goto error;
...@@ -68,7 +70,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -68,7 +70,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
* check * check
*/ */
btrfs_init_path(&path); 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) if (ret)
goto fatal_release; goto fatal_release;
if (!btrfs_match_dir_item_name(root, &path, buf, strlen(buf))) { if (!btrfs_match_dir_item_name(root, &path, buf, strlen(buf))) {
...@@ -96,7 +99,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -96,7 +99,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; 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; int ret;
char buf[128]; char buf[128];
...@@ -107,8 +111,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -107,8 +111,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; return 0;
sprintf(buf, "str-%lu", oid); sprintf(buf, "str-%lu", oid);
ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid, ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
1); file_oid, 1);
if (ret != -EEXIST) { if (ret != -EEXIST) {
printf("insert on %s gave us %d\n", buf, ret); printf("insert on %s gave us %d\n", buf, ret);
return 1; return 1;
...@@ -116,7 +120,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -116,7 +120,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; 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; int ret;
char buf[128]; char buf[128];
...@@ -129,10 +134,11 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -129,10 +134,11 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; return 0;
sprintf(buf, "str-%lu", oid); sprintf(buf, "str-%lu", oid);
btrfs_init_path(&path); 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) if (ret)
goto out_release; goto out_release;
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
if (ret) if (ret)
goto out_release; goto out_release;
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
...@@ -149,7 +155,8 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -149,7 +155,8 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; 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_path path;
char buf[128]; char buf[128];
...@@ -161,7 +168,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -161,7 +168,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; return 0;
sprintf(buf, "str-%lu", oid); sprintf(buf, "str-%lu", oid);
btrfs_init_path(&path); 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); btrfs_release_path(root, &path);
if (ret) { if (ret) {
printf("unable to find key %lu\n", oid); 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) ...@@ -170,7 +178,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; 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; struct btrfs_path path;
char buf[128]; char buf[128];
...@@ -182,7 +191,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -182,7 +191,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; return 0;
sprintf(buf, "str-%lu", oid); sprintf(buf, "str-%lu", oid);
btrfs_init_path(&path); 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); btrfs_release_path(root, &path);
if (!ret) { if (!ret) {
printf("able to find key that should not exist %lu\n", oid); 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) ...@@ -191,8 +201,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; return 0;
} }
static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
int nr) *root, struct radix_tree_root *radix, int nr)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -211,7 +221,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -211,7 +221,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
key.objectid = dir_oid; key.objectid = dir_oid;
while(nr-- >= 0) { while(nr-- >= 0) {
btrfs_init_path(&path); 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) { if (ret < 0) {
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
return ret; return ret;
...@@ -231,7 +241,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -231,7 +241,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
BUG_ON(found_len > 128); BUG_ON(found_len > 128);
buf[found_len] = '\0'; buf[found_len] = '\0';
found = atoi(buf + 4); found = atoi(buf + 4);
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
count++; count++;
if (ret) { if (ret) {
fprintf(stderr, fprintf(stderr,
...@@ -252,19 +262,19 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -252,19 +262,19 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
return -1; return -1;
} }
static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix, static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int count) struct radix_tree_root *radix, int count)
{ {
int i; int i;
int ret = 0; int ret = 0;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = ins_one(root, radix); ret = ins_one(trans, root, radix);
if (ret) { if (ret) {
fprintf(stderr, "fill failed\n"); fprintf(stderr, "fill failed\n");
goto out; goto out;
} }
if (i % 1000 == 0) { if (i % 1000 == 0) {
ret = btrfs_commit_transaction(root, &super); ret = btrfs_commit_transaction(trans, root, &super);
if (ret) { if (ret) {
fprintf(stderr, "fill commit failed\n"); fprintf(stderr, "fill commit failed\n");
return ret; return ret;
...@@ -280,7 +290,8 @@ static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -280,7 +290,8 @@ static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
return ret; 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 ret;
int nr = rand() % 5000; int nr = rand() % 5000;
...@@ -289,17 +300,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -289,17 +300,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
/* do the bulk op much less frequently */ /* do the bulk op much less frequently */
if (run_nr++ % 100) if (run_nr++ % 100)
return 0; return 0;
ret = empty_tree(root, radix, nr); ret = empty_tree(trans, root, radix, nr);
if (ret) if (ret)
return ret; return ret;
ret = fill_tree(root, radix, nr); ret = fill_tree(trans, root, radix, nr);
if (ret) if (ret)
return ret; return ret;
return 0; 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, { ins_one, insert_dup, del_one, lookup_item,
lookup_enoent, bulk_op }; lookup_enoent, bulk_op };
...@@ -330,11 +342,13 @@ int main(int ac, char **av) ...@@ -330,11 +342,13 @@ int main(int ac, char **av)
int init_fill_count = 800000; int init_fill_count = 800000;
int err = 0; int err = 0;
int initial_only = 0; int initial_only = 0;
struct btrfs_trans_handle *trans;
radix_tree_init(); radix_tree_init();
printf("removing old tree\n"); printf("removing old tree\n");
unlink("dbfile"); unlink("dbfile");
root = open_ctree("dbfile", &super); root = open_ctree("dbfile", &super);
trans = btrfs_start_transaction(root, 1);
signal(SIGTERM, sigstopper); signal(SIGTERM, sigstopper);
signal(SIGINT, sigstopper); signal(SIGINT, sigstopper);
...@@ -353,7 +367,7 @@ int main(int ac, char **av) ...@@ -353,7 +367,7 @@ int main(int ac, char **av)
} }
} }
printf("initial fill\n"); 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"); printf("starting run\n");
if (ret) { if (ret) {
err = ret; err = ret;
...@@ -377,7 +391,7 @@ int main(int ac, char **av) ...@@ -377,7 +391,7 @@ int main(int ac, char **av)
root = open_ctree("dbfile", &super); root = open_ctree("dbfile", &super);
} }
while(count--) { while(count--) {
ret = ops[op](root, &radix); ret = ops[op](trans, root, &radix);
if (ret) { if (ret) {
fprintf(stderr, "op %d failed %d:%d\n", fprintf(stderr, "op %d failed %d:%d\n",
op, i, iterations); op, i, iterations);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "radix-tree.h" #include "radix-tree.h"
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "transaction.h"
static int allocated_blocks = 0; static int allocated_blocks = 0;
int cache_max = 10000; int cache_max = 10000;
...@@ -107,7 +108,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) ...@@ -107,7 +108,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
return buf; 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)) if (!list_empty(&buf->dirty))
return 0; return 0;
...@@ -116,7 +118,8 @@ int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) ...@@ -116,7 +118,8 @@ int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
return 0; 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)) { if (!list_empty(&buf->dirty)) {
list_del_init(&buf->dirty); list_del_init(&buf->dirty);
...@@ -125,7 +128,8 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) ...@@ -125,7 +128,8 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
return 0; 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; u64 blocknr = buf->blocknr;
loff_t offset = blocknr * root->blocksize; loff_t offset = blocknr * root->blocksize;
...@@ -139,7 +143,8 @@ int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) ...@@ -139,7 +143,8 @@ int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
return 0; 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; struct btrfs_buffer *b;
int ret = 0; int ret = 0;
...@@ -147,7 +152,7 @@ static int __commit_transaction(struct btrfs_root *root) ...@@ -147,7 +152,7 @@ static int __commit_transaction(struct btrfs_root *root)
while(!list_empty(&root->trans)) { while(!list_empty(&root->trans)) {
b = list_entry(root->trans.next, struct btrfs_buffer, dirty); b = list_entry(root->trans.next, struct btrfs_buffer, dirty);
list_del_init(&b->dirty); list_del_init(&b->dirty);
wret = write_tree_block(root, b); wret = write_tree_block(trans, root, b);
if (wret) if (wret)
ret = wret; ret = wret;
btrfs_block_release(root, b); btrfs_block_release(root, b);
...@@ -155,8 +160,9 @@ static int __commit_transaction(struct btrfs_root *root) ...@@ -155,8 +160,9 @@ static int __commit_transaction(struct btrfs_root *root)
return ret; return ret;
} }
static int commit_extent_and_tree_roots(struct btrfs_root *tree_root, static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans,
struct btrfs_root *extent_root) struct btrfs_root *tree_root, struct
btrfs_root *extent_root)
{ {
int ret; int ret;
u64 old_extent_block; u64 old_extent_block;
...@@ -167,24 +173,24 @@ static int commit_extent_and_tree_roots(struct btrfs_root *tree_root, ...@@ -167,24 +173,24 @@ static int commit_extent_and_tree_roots(struct btrfs_root *tree_root,
break; break;
btrfs_set_root_blocknr(&extent_root->root_item, btrfs_set_root_blocknr(&extent_root->root_item,
extent_root->node->blocknr); extent_root->node->blocknr);
ret = btrfs_update_root(tree_root, ret = btrfs_update_root(trans, tree_root,
&extent_root->root_key, &extent_root->root_key,
&extent_root->root_item); &extent_root->root_item);
BUG_ON(ret); BUG_ON(ret);
} }
__commit_transaction(extent_root); __commit_transaction(trans, extent_root);
__commit_transaction(tree_root); __commit_transaction(trans, tree_root);
return 0; return 0;
} }
int btrfs_commit_transaction(struct btrfs_root *root, int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
struct btrfs_super_block *s) btrfs_root *root, struct btrfs_super_block *s)
{ {
int ret = 0; int ret = 0;
struct btrfs_buffer *snap = root->commit_root; struct btrfs_buffer *snap = root->commit_root;
struct btrfs_key snap_key; struct btrfs_key snap_key;
ret = __commit_transaction(root); ret = __commit_transaction(trans, root);
BUG_ON(ret); BUG_ON(ret);
if (root->commit_root == root->node) if (root->commit_root == root->node)
...@@ -194,23 +200,24 @@ int btrfs_commit_transaction(struct btrfs_root *root, ...@@ -194,23 +200,24 @@ int btrfs_commit_transaction(struct btrfs_root *root,
root->root_key.offset++; root->root_key.offset++;
btrfs_set_root_blocknr(&root->root_item, root->node->blocknr); 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); &root->root_item);
BUG_ON(ret); 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); BUG_ON(ret);
write_ctree_super(root, s); write_ctree_super(trans, root, s);
btrfs_finish_extent_commit(root->extent_root); btrfs_finish_extent_commit(trans, root->extent_root);
btrfs_finish_extent_commit(root->tree_root); btrfs_finish_extent_commit(trans, root->tree_root);
root->commit_root = root->node; root->commit_root = root->node;
root->node->count++; root->node->count++;
ret = btrfs_drop_snapshot(root, snap); ret = btrfs_drop_snapshot(trans, root, snap);
BUG_ON(ret); 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); BUG_ON(ret);
return ret; return ret;
...@@ -312,7 +319,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) ...@@ -312,7 +319,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
return root; 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; int ret;
btrfs_set_super_root(s, root->tree_root->node->blocknr); btrfs_set_super_root(s, root->tree_root->node->blocknr);
...@@ -338,10 +346,14 @@ static int drop_cache(struct btrfs_root *root) ...@@ -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 close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
{ {
int ret; int ret;
btrfs_commit_transaction(root, s); struct btrfs_trans_handle *trans;
ret = commit_extent_and_tree_roots(root->tree_root, root->extent_root);
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); BUG_ON(ret);
write_ctree_super(root, s); write_ctree_super(trans, root, s);
drop_cache(root->extent_root); drop_cache(root->extent_root);
drop_cache(root->tree_root); drop_cache(root->tree_root);
drop_cache(root); drop_cache(root);
......
...@@ -15,15 +15,19 @@ struct btrfs_buffer { ...@@ -15,15 +15,19 @@ struct btrfs_buffer {
struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr); struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr);
struct btrfs_buffer *find_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 write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf); struct btrfs_buffer *buf);
int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf); int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_commit_transaction(struct btrfs_root *root, struct btrfs_buffer *buf);
struct btrfs_super_block *s); 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); struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
int close_ctree(struct btrfs_root *root, 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); 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); int mkfs(int fd, u64 num_blocks, u32 blocksize);
#define BTRFS_SUPER_INFO_OFFSET (16 * 1024) #define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
......
...@@ -5,12 +5,15 @@ ...@@ -5,12 +5,15 @@
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "print-tree.h" #include "print-tree.h"
#include "transaction.h"
static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
u64 search_start, u64 search_end, *orig_root, u64 num_blocks, u64 search_start, u64
struct btrfs_key *ins); search_end, struct btrfs_key *ins);
static int finish_current_insert(struct btrfs_root *extent_root); static int finish_current_insert(struct btrfs_trans_handle *trans, struct
static int run_pending(struct btrfs_root *extent_root); 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 * 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); ...@@ -21,7 +24,8 @@ static int run_pending(struct btrfs_root *extent_root);
*/ */
#define CTREE_EXTENT_PENDING_DEL 0 #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; struct btrfs_path path;
int ret; int ret;
...@@ -31,13 +35,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr) ...@@ -31,13 +35,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
struct btrfs_key ins; struct btrfs_key ins;
u32 refs; 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); btrfs_init_path(&path);
key.objectid = blocknr; key.objectid = blocknr;
key.flags = 0; key.flags = 0;
btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
key.offset = 1; 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) if (ret != 0)
BUG(); BUG();
BUG_ON(ret != 0); BUG_ON(ret != 0);
...@@ -48,12 +52,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr) ...@@ -48,12 +52,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr)
BUG_ON(list_empty(&path.nodes[0]->dirty)); BUG_ON(list_empty(&path.nodes[0]->dirty));
btrfs_release_path(root->extent_root, &path); btrfs_release_path(root->extent_root, &path);
finish_current_insert(root->extent_root); finish_current_insert(trans, root->extent_root);
run_pending(root->extent_root); run_pending(trans, root->extent_root);
return 0; 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; struct btrfs_path path;
int ret; int ret;
...@@ -65,7 +70,7 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs) ...@@ -65,7 +70,7 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
key.offset = 1; key.offset = 1;
key.flags = 0; key.flags = 0;
btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 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) if (ret != 0)
BUG(); BUG();
l = &path.nodes[0]->leaf; l = &path.nodes[0]->leaf;
...@@ -75,7 +80,8 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs) ...@@ -75,7 +80,8 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs)
return 0; 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; u64 blocknr;
int i; int i;
...@@ -87,12 +93,13 @@ int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf) ...@@ -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++) { for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
blocknr = btrfs_node_blockptr(&buf->node, i); blocknr = btrfs_node_blockptr(&buf->node, i);
inc_block_ref(root, blocknr); inc_block_ref(trans, root, blocknr);
} }
return 0; 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]; unsigned long gang[8];
u64 first = 0; u64 first = 0;
...@@ -116,7 +123,8 @@ int btrfs_finish_extent_commit(struct btrfs_root *root) ...@@ -116,7 +123,8 @@ int btrfs_finish_extent_commit(struct btrfs_root *root)
return 0; 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_key ins;
struct btrfs_extent_item extent_item; struct btrfs_extent_item extent_item;
...@@ -132,8 +140,8 @@ static int finish_current_insert(struct btrfs_root *extent_root) ...@@ -132,8 +140,8 @@ static int finish_current_insert(struct btrfs_root *extent_root)
for (i = 0; i < extent_root->current_insert.flags; i++) { for (i = 0; i < extent_root->current_insert.flags; i++) {
ins.objectid = extent_root->current_insert.objectid + i; ins.objectid = extent_root->current_insert.objectid + i;
ret = btrfs_insert_item(extent_root, &ins, &extent_item, ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item,
sizeof(extent_item)); sizeof(extent_item));
BUG_ON(ret); BUG_ON(ret);
} }
extent_root->current_insert.offset = 0; extent_root->current_insert.offset = 0;
...@@ -143,8 +151,8 @@ static int finish_current_insert(struct btrfs_root *extent_root) ...@@ -143,8 +151,8 @@ static int finish_current_insert(struct btrfs_root *extent_root)
/* /*
* remove an extent from the root, returns 0 on success * remove an extent from the root, returns 0 on success
*/ */
static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
int pin) *root, u64 blocknr, u64 num_blocks, int pin)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -160,9 +168,9 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, ...@@ -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); btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
key.offset = num_blocks; 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); 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) { if (ret) {
printf("failed to find %Lu\n", key.objectid); printf("failed to find %Lu\n", key.objectid);
btrfs_print_tree(extent_root, extent_root->node); 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, ...@@ -183,14 +191,14 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
BUG_ON(err); BUG_ON(err);
radix_tree_preload_end(); 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) if (!pin && extent_root->last_insert.objectid > blocknr)
extent_root->last_insert.objectid = blocknr; extent_root->last_insert.objectid = blocknr;
if (ret) if (ret)
BUG(); BUG();
} }
btrfs_release_path(extent_root, &path); btrfs_release_path(extent_root, &path);
finish_current_insert(extent_root); finish_current_insert(trans, extent_root);
return ret; return ret;
} }
...@@ -198,7 +206,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, ...@@ -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 * find all the blocks marked as pending in the radix tree and remove
* them from the extent map * 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; int ret;
struct btrfs_buffer *gang[4]; struct btrfs_buffer *gang[4];
...@@ -212,7 +221,7 @@ static int del_pending_extents(struct btrfs_root *extent_root) ...@@ -212,7 +221,7 @@ static int del_pending_extents(struct btrfs_root *extent_root)
if (!ret) if (!ret)
break; break;
for (i = 0; i < ret; i++) { for (i = 0; i < ret; i++) {
ret = __free_extent(extent_root, ret = __free_extent(trans, extent_root,
gang[i]->blocknr, 1, 1); gang[i]->blocknr, 1, 1);
radix_tree_tag_clear(&extent_root->cache_radix, radix_tree_tag_clear(&extent_root->cache_radix,
gang[i]->blocknr, gang[i]->blocknr,
...@@ -223,11 +232,12 @@ static int del_pending_extents(struct btrfs_root *extent_root) ...@@ -223,11 +232,12 @@ static int del_pending_extents(struct btrfs_root *extent_root)
return 0; 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, while(radix_tree_tagged(&extent_root->cache_radix,
CTREE_EXTENT_PENDING_DEL)) CTREE_EXTENT_PENDING_DEL))
del_pending_extents(extent_root); del_pending_extents(trans, extent_root);
return 0; return 0;
} }
...@@ -235,8 +245,8 @@ static int run_pending(struct btrfs_root *extent_root) ...@@ -235,8 +245,8 @@ static int run_pending(struct btrfs_root *extent_root)
/* /*
* remove an extent from the root, returns 0 on success * remove an extent from the root, returns 0 on success
*/ */
int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
int pin) *root, u64 blocknr, u64 num_blocks, int pin)
{ {
struct btrfs_root *extent_root = root->extent_root; struct btrfs_root *extent_root = root->extent_root;
struct btrfs_buffer *t; struct btrfs_buffer *t;
...@@ -249,8 +259,8 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, ...@@ -249,8 +259,8 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
CTREE_EXTENT_PENDING_DEL); CTREE_EXTENT_PENDING_DEL);
return 0; return 0;
} }
ret = __free_extent(root, blocknr, num_blocks, pin); ret = __free_extent(trans, root, blocknr, num_blocks, pin);
pending_ret = run_pending(root->extent_root); pending_ret = run_pending(trans, root->extent_root);
return ret ? ret : pending_ret; return ret ? ret : pending_ret;
} }
...@@ -262,9 +272,9 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, ...@@ -262,9 +272,9 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks,
* ins->offset == number of blocks * ins->offset == number of blocks
* Any available blocks before search_start are skipped. * Any available blocks before search_start are skipped.
*/ */
static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
u64 search_start, u64 search_end, *orig_root, u64 num_blocks, u64 search_start, u64
struct btrfs_key *ins) search_end, struct btrfs_key *ins)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -290,7 +300,7 @@ static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, ...@@ -290,7 +300,7 @@ static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
ins->objectid = search_start; ins->objectid = search_start;
ins->offset = 0; ins->offset = 0;
start_found = 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) if (ret < 0)
goto error; goto error;
...@@ -367,9 +377,9 @@ static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, ...@@ -367,9 +377,9 @@ static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks,
* *
* returns 0 if everything worked, non-zero otherwise. * returns 0 if everything worked, non-zero otherwise.
*/ */
static int alloc_extent(struct btrfs_root *root, u64 num_blocks, static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
u64 search_start, u64 search_end, u64 owner, *root, u64 num_blocks, u64 search_start, u64
struct btrfs_key *ins) search_end, u64 owner, struct btrfs_key *ins)
{ {
int ret; int ret;
int pending_ret; int pending_ret;
...@@ -389,16 +399,16 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks, ...@@ -389,16 +399,16 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks,
extent_root->current_insert.flags++; extent_root->current_insert.flags++;
return 0; return 0;
} }
ret = find_free_extent(root, num_blocks, search_start, ret = find_free_extent(trans, root, num_blocks, search_start,
search_end, ins); search_end, ins);
if (ret) if (ret)
return ret; return ret;
ret = btrfs_insert_item(extent_root, ins, &extent_item, ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
sizeof(extent_item)); sizeof(extent_item));
finish_current_insert(extent_root); finish_current_insert(trans, extent_root);
pending_ret = run_pending(extent_root); pending_ret = run_pending(trans, extent_root);
if (ret) if (ret)
return ret; return ret;
if (pending_ret) if (pending_ret)
...@@ -410,13 +420,14 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks, ...@@ -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 * helper function to allocate a block for a given tree
* returns the tree buffer or NULL. * 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; struct btrfs_key ins;
int ret; int ret;
struct btrfs_buffer *buf; 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), btrfs_header_parentid(&root->node->node.header),
&ins); &ins);
if (ret) { if (ret) {
...@@ -424,7 +435,7 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root) ...@@ -424,7 +435,7 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root)
return NULL; return NULL;
} }
buf = find_tree_block(root, ins.objectid); buf = find_tree_block(root, ins.objectid);
dirty_tree_block(root, buf); dirty_tree_block(trans, root, buf);
return buf; return buf;
} }
...@@ -432,8 +443,8 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root) ...@@ -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 * helper function for drop_snapshot, this walks down the tree dropping ref
* counts as it goes. * counts as it goes.
*/ */
static int walk_down_tree(struct btrfs_root *root, static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_path *path, int *level) *root, struct btrfs_path *path, int *level)
{ {
struct btrfs_buffer *next; struct btrfs_buffer *next;
struct btrfs_buffer *cur; struct btrfs_buffer *cur;
...@@ -441,7 +452,8 @@ static int walk_down_tree(struct btrfs_root *root, ...@@ -441,7 +452,8 @@ static int walk_down_tree(struct btrfs_root *root,
int ret; int ret;
u32 refs; 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); BUG_ON(ret);
if (refs > 1) if (refs > 1)
goto out; goto out;
...@@ -454,10 +466,10 @@ static int walk_down_tree(struct btrfs_root *root, ...@@ -454,10 +466,10 @@ static int walk_down_tree(struct btrfs_root *root,
btrfs_header_nritems(&cur->node.header)) btrfs_header_nritems(&cur->node.header))
break; break;
blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]); 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) { if (refs != 1 || *level == 1) {
path->slots[*level]++; path->slots[*level]++;
ret = btrfs_free_extent(root, blocknr, 1, 1); ret = btrfs_free_extent(trans, root, blocknr, 1, 1);
BUG_ON(ret); BUG_ON(ret);
continue; continue;
} }
...@@ -470,7 +482,8 @@ static int walk_down_tree(struct btrfs_root *root, ...@@ -470,7 +482,8 @@ static int walk_down_tree(struct btrfs_root *root,
path->slots[*level] = 0; path->slots[*level] = 0;
} }
out: 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]); btrfs_block_release(root, path->nodes[*level]);
path->nodes[*level] = NULL; path->nodes[*level] = NULL;
*level += 1; *level += 1;
...@@ -483,8 +496,8 @@ static int walk_down_tree(struct btrfs_root *root, ...@@ -483,8 +496,8 @@ static int walk_down_tree(struct btrfs_root *root,
* to find the first node higher up where we haven't yet gone through * to find the first node higher up where we haven't yet gone through
* all the slots * all the slots
*/ */
static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
int *level) *root, struct btrfs_path *path, int *level)
{ {
int i; int i;
int slot; int slot;
...@@ -497,8 +510,9 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, ...@@ -497,8 +510,9 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path,
*level = i; *level = i;
return 0; return 0;
} else { } else {
ret = btrfs_free_extent(root, ret = btrfs_free_extent(trans, root,
path->nodes[*level]->blocknr, 1, 1); path->nodes[*level]->blocknr,
1, 1);
btrfs_block_release(root, path->nodes[*level]); btrfs_block_release(root, path->nodes[*level]);
path->nodes[*level] = NULL; path->nodes[*level] = NULL;
*level = i + 1; *level = i + 1;
...@@ -513,7 +527,8 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, ...@@ -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 * the tree freeing any blocks that have a ref count of zero after being
* decremented. * 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 ret = 0;
int wret; int wret;
...@@ -529,13 +544,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap) ...@@ -529,13 +544,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap)
path.nodes[level] = snap; path.nodes[level] = snap;
path.slots[level] = 0; path.slots[level] = 0;
while(1) { while(1) {
wret = walk_down_tree(root, &path, &level); wret = walk_down_tree(trans, root, &path, &level);
if (wret > 0) if (wret > 0)
break; break;
if (wret < 0) if (wret < 0)
ret = wret; ret = wret;
wret = walk_up_tree(root, &path, &level); wret = walk_up_tree(trans, root, &path, &level);
if (wret > 0) if (wret > 0)
break; break;
if (wret < 0) if (wret < 0)
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
#include "radix-tree.h" #include "radix-tree.h"
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "transaction.h"
int btrfs_insert_inode(struct btrfs_root *root, u64 objectid, int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_inode_item *inode_item) *root, u64 objectid, struct btrfs_inode_item
*inode_item)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -17,13 +19,14 @@ int btrfs_insert_inode(struct btrfs_root *root, u64 objectid, ...@@ -17,13 +19,14 @@ int btrfs_insert_inode(struct btrfs_root *root, u64 objectid,
key.offset = 0; key.offset = 0;
btrfs_init_path(&path); 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); btrfs_release_path(root, &path);
return ret; return ret;
} }
int btrfs_lookup_inode(struct btrfs_root *root, struct btrfs_path *path, int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
u64 objectid, int mod) *root, struct btrfs_path *path, u64 objectid, int mod)
{ {
struct btrfs_key key; struct btrfs_key key;
int ins_len = mod < 0 ? -1 : 0; int ins_len = mod < 0 ? -1 : 0;
...@@ -33,5 +36,5 @@ int btrfs_lookup_inode(struct btrfs_root *root, struct btrfs_path *path, ...@@ -33,5 +36,5 @@ int btrfs_lookup_inode(struct btrfs_root *root, struct btrfs_path *path,
key.flags = 0; key.flags = 0;
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
key.offset = 0; key.offset = 0;
return btrfs_search_slot(root, &key, path, ins_len, cow); return btrfs_search_slot(trans, root, &key, path, ins_len, cow);
} }
#ifndef __PRINT_TREE_
#define __PRINT_TREE_
void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l); void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l);
void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t); void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t);
#endif
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "print-tree.h" #include "print-tree.h"
#include "transaction.h"
/* for testing only */ /* for testing only */
int next_key(int i, int max_key) { int next_key(int i, int max_key) {
...@@ -25,10 +26,12 @@ int main(int ac, char **av) { ...@@ -25,10 +26,12 @@ int main(int ac, char **av) {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_super_block super; struct btrfs_super_block super;
struct btrfs_root *root; struct btrfs_root *root;
struct btrfs_trans_handle *trans;
radix_tree_init(); radix_tree_init();
root = open_ctree("dbfile", &super); root = open_ctree("dbfile", &super);
trans = btrfs_start_transaction(root, 1);
srand(55); srand(55);
ins.flags = 0; ins.flags = 0;
btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY); btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY);
...@@ -41,12 +44,12 @@ int main(int ac, char **av) { ...@@ -41,12 +44,12 @@ int main(int ac, char **av) {
fprintf(stderr, "insert %d:%d\n", num, i); fprintf(stderr, "insert %d:%d\n", num, i);
ins.objectid = num; ins.objectid = num;
ins.offset = 0; ins.offset = 0;
ret = btrfs_insert_item(root, &ins, buf, strlen(buf)); ret = btrfs_insert_item(trans, root, &ins, buf, strlen(buf));
if (!ret) if (!ret)
tree_size++; tree_size++;
free(buf); free(buf);
if (i == run_size - 5) { 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) { ...@@ -61,7 +64,7 @@ int main(int ac, char **av) {
btrfs_init_path(&path); btrfs_init_path(&path);
if (i % 10000 == 0) if (i % 10000 == 0)
fprintf(stderr, "search %d:%d\n", num, i); 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) { if (ret) {
btrfs_print_tree(root, root->node); btrfs_print_tree(root, root->node);
printf("unable to find %d\n", num); printf("unable to find %d\n", num);
...@@ -83,11 +86,11 @@ int main(int ac, char **av) { ...@@ -83,11 +86,11 @@ int main(int ac, char **av) {
num = next_key(i, max_key); num = next_key(i, max_key);
ins.objectid = num; ins.objectid = num;
btrfs_init_path(&path); 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 (!ret) {
if (i % 10000 == 0) if (i % 10000 == 0)
fprintf(stderr, "del %d:%d\n", num, i); fprintf(stderr, "del %d:%d\n", num, i);
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
if (ret != 0) if (ret != 0)
BUG(); BUG();
tree_size--; tree_size--;
...@@ -104,7 +107,7 @@ int main(int ac, char **av) { ...@@ -104,7 +107,7 @@ int main(int ac, char **av) {
ins.objectid = num; ins.objectid = num;
if (i % 10000 == 0) if (i % 10000 == 0)
fprintf(stderr, "insert %d:%d\n", num, i); 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) if (!ret)
tree_size++; tree_size++;
free(buf); free(buf);
...@@ -119,7 +122,7 @@ int main(int ac, char **av) { ...@@ -119,7 +122,7 @@ int main(int ac, char **av) {
btrfs_init_path(&path); btrfs_init_path(&path);
if (i % 10000 == 0) if (i % 10000 == 0)
fprintf(stderr, "search %d:%d\n", num, i); 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) { if (ret) {
btrfs_print_tree(root, root->node); btrfs_print_tree(root, root->node);
printf("unable to find %d\n", num); printf("unable to find %d\n", num);
...@@ -134,7 +137,7 @@ int main(int ac, char **av) { ...@@ -134,7 +137,7 @@ int main(int ac, char **av) {
int slot; int slot;
ins.objectid = (u64)-1; ins.objectid = (u64)-1;
btrfs_init_path(&path); 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) if (ret == 0)
BUG(); BUG();
...@@ -150,7 +153,7 @@ int main(int ac, char **av) { ...@@ -150,7 +153,7 @@ int main(int ac, char **av) {
btrfs_disk_key_to_cpu(&last, &leaf->items[slot].key); btrfs_disk_key_to_cpu(&last, &leaf->items[slot].key);
if (tree_size % 10000 == 0) if (tree_size % 10000 == 0)
printf("big del %d:%d\n", tree_size, i); 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) { if (ret != 0) {
printf("del_item returned %d\n", ret); printf("del_item returned %d\n", ret);
BUG(); BUG();
...@@ -165,7 +168,7 @@ int main(int ac, char **av) { ...@@ -165,7 +168,7 @@ int main(int ac, char **av) {
printf("map before commit\n"); printf("map before commit\n");
btrfs_print_tree(root->extent_root, root->extent_root->node); 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("tree size is now %d\n", tree_size);
printf("root %p commit root %p\n", root->node, root->commit_root); printf("root %p commit root %p\n", root->node, root->commit_root);
printf("map tree\n"); printf("map tree\n");
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "print-tree.h" #include "print-tree.h"
#include "transaction.h"
int keep_running = 1; int keep_running = 1;
struct btrfs_super_block super; struct btrfs_super_block super;
...@@ -37,7 +38,8 @@ static int setup_key(struct radix_tree_root *root, struct btrfs_key *key, ...@@ -37,7 +38,8 @@ static int setup_key(struct radix_tree_root *root, struct btrfs_key *key,
return 0; 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_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -47,7 +49,7 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -47,7 +49,7 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
btrfs_init_path(&path); btrfs_init_path(&path);
ret = setup_key(radix, &key, 0); ret = setup_key(radix, &key, 0);
sprintf(buf, "str-%Lu\n", key.objectid); 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) if (ret)
goto error; goto error;
oid = (unsigned long)key.objectid; oid = (unsigned long)key.objectid;
...@@ -62,7 +64,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -62,7 +64,8 @@ static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; 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_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -73,7 +76,7 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -73,7 +76,7 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
if (ret < 0) if (ret < 0)
return 0; return 0;
sprintf(buf, "str-%Lu\n", key.objectid); 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) { if (ret != -EEXIST) {
printf("insert on %Lu gave us %d\n", key.objectid, ret); printf("insert on %Lu gave us %d\n", key.objectid, ret);
return 1; return 1;
...@@ -81,7 +84,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -81,7 +84,8 @@ static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
return 0; 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_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -91,10 +95,10 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -91,10 +95,10 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
ret = setup_key(radix, &key, 1); ret = setup_key(radix, &key, 1);
if (ret < 0) if (ret < 0)
return 0; return 0;
ret = btrfs_search_slot(root, &key, &path, -1, 1); ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
if (ret) if (ret)
goto error; goto error;
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
if (ret != 0) if (ret != 0)
goto error; goto error;
...@@ -107,7 +111,8 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -107,7 +111,8 @@ static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; 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_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -116,7 +121,7 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -116,7 +121,7 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
ret = setup_key(radix, &key, 1); ret = setup_key(radix, &key, 1);
if (ret < 0) if (ret < 0)
return 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); btrfs_release_path(root, &path);
if (ret) if (ret)
goto error; goto error;
...@@ -126,7 +131,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -126,7 +131,8 @@ static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; 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_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -135,7 +141,7 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -135,7 +141,7 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
ret = setup_key(radix, &key, 0); ret = setup_key(radix, &key, 0);
if (ret < 0) if (ret < 0)
return ret; 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); btrfs_release_path(root, &path);
if (ret <= 0) if (ret <= 0)
goto error; goto error;
...@@ -145,8 +151,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -145,8 +151,8 @@ static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
return -1; return -1;
} }
static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
int nr) *root, struct radix_tree_root *radix, int nr)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_key key; struct btrfs_key key;
...@@ -162,7 +168,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -162,7 +168,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
key.objectid = (unsigned long)-1; key.objectid = (unsigned long)-1;
while(nr-- >= 0) { while(nr-- >= 0) {
btrfs_init_path(&path); 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) { if (ret < 0) {
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
return ret; return ret;
...@@ -177,7 +183,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -177,7 +183,7 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
slot = path.slots[0]; slot = path.slots[0];
found = btrfs_disk_key_objectid( found = btrfs_disk_key_objectid(
&path.nodes[0]->leaf.items[slot].key); &path.nodes[0]->leaf.items[slot].key);
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
count++; count++;
if (ret) { if (ret) {
fprintf(stderr, fprintf(stderr,
...@@ -198,19 +204,19 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -198,19 +204,19 @@ static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
return -1; return -1;
} }
static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix, static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int count) struct radix_tree_root *radix, int count)
{ {
int i; int i;
int ret = 0; int ret = 0;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = ins_one(root, radix); ret = ins_one(trans, root, radix);
if (ret) { if (ret) {
fprintf(stderr, "fill failed\n"); fprintf(stderr, "fill failed\n");
goto out; goto out;
} }
if (i % 1000 == 0) { if (i % 1000 == 0) {
ret = btrfs_commit_transaction(root, &super); ret = btrfs_commit_transaction(trans, root, &super);
if (ret) { if (ret) {
fprintf(stderr, "fill commit failed\n"); fprintf(stderr, "fill commit failed\n");
return ret; return ret;
...@@ -226,7 +232,8 @@ static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix, ...@@ -226,7 +232,8 @@ static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
return ret; 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 ret;
int nr = rand() % 5000; int nr = rand() % 5000;
...@@ -235,17 +242,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -235,17 +242,18 @@ static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
/* do the bulk op much less frequently */ /* do the bulk op much less frequently */
if (run_nr++ % 100) if (run_nr++ % 100)
return 0; return 0;
ret = empty_tree(root, radix, nr); ret = empty_tree(trans, root, radix, nr);
if (ret) if (ret)
return ret; return ret;
ret = fill_tree(root, radix, nr); ret = fill_tree(trans, root, radix, nr);
if (ret) if (ret)
return ret; return ret;
return 0; 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, { ins_one, insert_dup, del_one, lookup_item,
lookup_enoent, bulk_op }; lookup_enoent, bulk_op };
...@@ -264,7 +272,7 @@ static int fill_radix(struct btrfs_root *root, struct radix_tree_root *radix) ...@@ -264,7 +272,7 @@ static int fill_radix(struct btrfs_root *root, struct radix_tree_root *radix)
key.objectid = (unsigned long)-1; key.objectid = (unsigned long)-1;
while(1) { while(1) {
btrfs_init_path(&path); 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) { if (ret < 0) {
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
return ret; return ret;
...@@ -325,6 +333,7 @@ int main(int ac, char **av) ...@@ -325,6 +333,7 @@ int main(int ac, char **av)
int init_fill_count = 800000; int init_fill_count = 800000;
int err = 0; int err = 0;
int initial_only = 0; int initial_only = 0;
struct btrfs_trans_handle *trans;
radix_tree_init(); radix_tree_init();
root = open_ctree("dbfile", &super); root = open_ctree("dbfile", &super);
fill_radix(root, &radix); fill_radix(root, &radix);
...@@ -346,7 +355,8 @@ int main(int ac, char **av) ...@@ -346,7 +355,8 @@ int main(int ac, char **av)
} }
} }
printf("initial fill\n"); 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"); printf("starting run\n");
if (ret) { if (ret) {
err = ret; err = ret;
...@@ -370,7 +380,7 @@ int main(int ac, char **av) ...@@ -370,7 +380,7 @@ int main(int ac, char **av)
root = open_ctree("dbfile", &super); root = open_ctree("dbfile", &super);
} }
while(count--) { while(count--) {
ret = ops[op](root, &radix); ret = ops[op](trans, root, &radix);
if (ret) { if (ret) {
fprintf(stderr, "op %d failed %d:%d\n", fprintf(stderr, "op %d failed %d:%d\n",
op, i, iterations); op, i, iterations);
......
...@@ -20,7 +20,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, ...@@ -20,7 +20,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
search_key.offset = (u32)-1; search_key.offset = (u32)-1;
btrfs_init_path(&path); 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) if (ret < 0)
goto out; goto out;
BUG_ON(ret == 0); BUG_ON(ret == 0);
...@@ -40,8 +40,9 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, ...@@ -40,8 +40,9 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
return ret; return ret;
} }
int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key, int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_root_item *item) *root, struct btrfs_key *key, struct btrfs_root_item
*item)
{ {
struct btrfs_path path; struct btrfs_path path;
struct btrfs_leaf *l; struct btrfs_leaf *l;
...@@ -49,7 +50,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key, ...@@ -49,7 +50,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
int slot; int slot;
btrfs_init_path(&path); 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) if (ret < 0)
goto out; goto out;
BUG_ON(ret != 0); BUG_ON(ret != 0);
...@@ -62,26 +63,28 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key, ...@@ -62,26 +63,28 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
return ret; return ret;
} }
int btrfs_insert_root(struct btrfs_root *root, struct btrfs_key *key, int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_root_item *item) *root, struct btrfs_key *key, struct btrfs_root_item
*item)
{ {
int ret; int ret;
ret = btrfs_insert_item(root, key, item, sizeof(*item)); ret = btrfs_insert_item(trans, root, key, item, sizeof(*item));
BUG_ON(ret); BUG_ON(ret);
return 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; struct btrfs_path path;
int ret; int ret;
btrfs_init_path(&path); 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) if (ret < 0)
goto out; goto out;
BUG_ON(ret != 0); BUG_ON(ret != 0);
ret = btrfs_del_item(root, &path); ret = btrfs_del_item(trans, root, &path);
out: out:
btrfs_release_path(root, &path); btrfs_release_path(root, &path);
return ret; return ret;
......
#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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册