From 7777e63b425f1444d2472ea05a6b2b9cf865f35b Mon Sep 17 00:00:00 2001 From: Yan Date: Fri, 4 Jan 2008 10:38:22 -0500 Subject: Update btrfs-progs to match kernel sources --- disk-io.c | 665 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 345 insertions(+), 320 deletions(-) (limited to 'disk-io.c') diff --git a/disk-io.c b/disk-io.c index c401e3fb..fad099a3 100644 --- a/disk-io.c +++ b/disk-io.c @@ -31,215 +31,130 @@ #include "transaction.h" #include "crc32c.h" -static u64 allocated_bytes = 0; -int cache_max = 10000; - -int btrfs_map_bh_to_logical(struct btrfs_root *root, struct btrfs_buffer *bh, - u64 logical) +int btrfs_map_bh_to_logical(struct btrfs_root *root, struct extent_buffer *buf, + u64 logical) { - bh->fd = root->fs_info->fp; - bh->dev_bytenr = logical; + buf->fd = root->fs_info->fp; + buf->dev_bytenr = logical; return 0; } -static int check_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) +static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) { - if (buf->bytenr != btrfs_header_bytenr(&buf->node.header)) + if (buf->start != btrfs_header_bytenr(buf)) BUG(); - if (memcmp(root->fs_info->disk_super->fsid, buf->node.header.fsid, - sizeof(buf->node.header.fsid))) + + if (memcmp_extent_buffer(buf, root->fs_info->fsid, + (unsigned long)btrfs_header_fsid(buf), + BTRFS_FSID_SIZE)) BUG(); return 0; } -static int free_some_buffers(struct btrfs_root *root) +u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len) { - struct list_head *node, *next; - struct btrfs_buffer *b; - if (root->fs_info->cache_size < cache_max) - return 0; - list_for_each_safe(node, next, &root->fs_info->cache) { - b = list_entry(node, struct btrfs_buffer, cache); - if (b->count == 1) { - BUG_ON(!list_empty(&b->dirty)); - list_del_init(&b->cache); - btrfs_block_release(root, b); - if (root->fs_info->cache_size < cache_max) - break; - } - } - return 0; + return crc32c(seed, data, len); } -struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 bytenr, - u32 blocksize) +void btrfs_csum_final(u32 crc, char *result) { - struct btrfs_buffer *buf; - int ret; - - buf = malloc(sizeof(struct btrfs_buffer) + blocksize); - if (!buf) - return buf; - allocated_bytes += blocksize; - - buf->bytenr = bytenr; - buf->count = 2; - buf->size = blocksize; - buf->cache_node.start = bytenr; - buf->cache_node.size = blocksize; - - INIT_LIST_HEAD(&buf->dirty); - free_some_buffers(root); - - ret = insert_existing_cache_extent(&root->fs_info->extent_cache, - &buf->cache_node); - - list_add_tail(&buf->cache, &root->fs_info->cache); - root->fs_info->cache_size += blocksize; - if (ret) { - free(buf); - return NULL; - } - return buf; + *(__le32 *)result = ~cpu_to_le32(crc); } -struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 bytenr, - u32 blocksize) +static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, + int verify) { - struct btrfs_buffer *buf; - struct cache_extent *cache; - - cache = find_cache_extent(&root->fs_info->extent_cache, - bytenr, blocksize); - if (cache) { - buf = container_of(cache, struct btrfs_buffer, cache_node); - buf->count++; - } else { - buf = alloc_tree_block(root, bytenr, blocksize); - if (!buf) { - BUG(); - return NULL; - } - } - return buf; -} + char result[BTRFS_CRC32_SIZE]; + u32 len; + u32 crc = ~(u32)0; -struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, - u32 blocksize) -{ - struct btrfs_buffer *buf; - int ret; - struct cache_extent *cache; + len = buf->len - BTRFS_CSUM_SIZE; + crc = crc32c(crc, buf->data + BTRFS_CSUM_SIZE, len); + btrfs_csum_final(crc, result); - cache = find_cache_extent(&root->fs_info->extent_cache, - bytenr, blocksize); - if (cache) { - buf = container_of(cache, struct btrfs_buffer, cache_node); - buf->count++; - if (check_tree_block(root, buf)) - BUG(); - } else { - buf = alloc_tree_block(root, bytenr, blocksize); - if (!buf) - return NULL; - btrfs_map_bh_to_logical(root, buf, bytenr); - ret = pread(buf->fd, &buf->node, blocksize, - buf->dev_bytenr); - if (ret != blocksize) { - free(buf); - return NULL; + if (verify) { + if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) { + printk("checksum verify failed on %llu\n", buf->start); + return 1; } - if (check_tree_block(root, buf)) - BUG(); + } else { + write_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE); } - return buf; + return 0; } -int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_buffer *buf) +struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, + u64 bytenr, u32 blocksize) { - if (!list_empty(&buf->dirty)) - return 0; - list_add_tail(&buf->dirty, &root->fs_info->trans); - buf->count++; - if (check_tree_block(root, buf)) - BUG(); - return 0; + return find_extent_buffer(&root->fs_info->extent_cache, + bytenr, blocksize); } -int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_buffer *buf) +struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, + u64 bytenr, u32 blocksize) { - if (!list_empty(&buf->dirty)) { - list_del_init(&buf->dirty); - btrfs_block_release(root, buf); - } - return 0; + return alloc_extent_buffer(&root->fs_info->extent_cache, bytenr, + blocksize); } -int btrfs_csum_node(struct btrfs_root *root, struct btrfs_node *node) +int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) { - u32 crc = ~(u32)0; - size_t len = btrfs_level_size(root, btrfs_header_level(&node->header)) - - BTRFS_CSUM_SIZE; - - crc = crc32c(crc, (char *)(node) + BTRFS_CSUM_SIZE, len); - crc = ~cpu_to_le32(crc); - memcpy(node->header.csum, &crc, BTRFS_CRC32_SIZE); return 0; } -int btrfs_csum_super(struct btrfs_root *root, struct btrfs_super_block *super) +struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, + u32 blocksize) { - u32 crc = ~(u32)0; - char block[512]; - size_t len = 512 - BTRFS_CSUM_SIZE; - - memset(block, 0, 512); - memcpy(block, super, sizeof(*super)); + int ret; + struct extent_buffer *eb; - crc = crc32c(crc, block + BTRFS_CSUM_SIZE, len); - crc = ~cpu_to_le32(crc); - memcpy(super->csum, &crc, BTRFS_CRC32_SIZE); - return 0; + eb = btrfs_find_create_tree_block(root, bytenr, blocksize); + if (!eb) + return NULL; + if (!btrfs_buffer_uptodate(eb)) { + btrfs_map_bh_to_logical(root, eb, eb->start); + ret = read_extent_from_disk(eb); + if (ret) { + free_extent_buffer(eb); + return NULL; + } + btrfs_set_buffer_uptodate(eb); + } + return eb; } int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_buffer *buf) + struct extent_buffer *eb) { - int ret; - - if (buf->bytenr != btrfs_header_bytenr(&buf->node.header)) + if (check_tree_block(root, eb)) BUG(); - btrfs_map_bh_to_logical(root, buf, buf->bytenr); - if (check_tree_block(root, buf)) + if (!btrfs_buffer_uptodate(eb)) BUG(); - - btrfs_csum_node(root, &buf->node); - - ret = pwrite(buf->fd, &buf->node, buf->size, - buf->dev_bytenr); - if (ret != buf->size) - return ret; - return 0; + btrfs_map_bh_to_logical(root, eb, eb->start); + csum_tree_block(root, eb, 0); + return write_extent_to_disk(eb); } -static int __commit_transaction(struct btrfs_trans_handle *trans, struct - btrfs_root *root) +static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, + u32 stripesize, struct btrfs_root *root, + struct btrfs_fs_info *fs_info, u64 objectid) { - struct btrfs_buffer *b; - int ret = 0; - int wret; - while(!list_empty(&root->fs_info->trans)) { - b = list_entry(root->fs_info->trans.next, struct btrfs_buffer, - dirty); - list_del_init(&b->dirty); - wret = write_tree_block(trans, root, b); - if (wret) - ret = wret; - btrfs_block_release(root, b); - } - return ret; + root->node = NULL; + root->commit_root = NULL; + root->sectorsize = sectorsize; + root->nodesize = nodesize; + root->leafsize = leafsize; + root->stripesize = stripesize; + root->ref_cows = 0; + root->fs_info = fs_info; + root->objectid = objectid; + root->last_trans = 0; + root->highest_inode = 0; + root->last_inode_alloc = 0; + memset(&root->root_key, 0, sizeof(root->root_key)); + memset(&root->root_item, 0, sizeof(root->root_item)); + root->root_key.objectid = objectid; + return 0; } static int commit_tree_roots(struct btrfs_trans_handle *trans, @@ -253,12 +168,12 @@ static int commit_tree_roots(struct btrfs_trans_handle *trans, btrfs_write_dirty_block_groups(trans, fs_info->extent_root); while(1) { old_extent_bytenr = btrfs_root_bytenr(&extent_root->root_item); - if (old_extent_bytenr == extent_root->node->bytenr) + if (old_extent_bytenr == extent_root->node->start) break; btrfs_set_root_bytenr(&extent_root->root_item, - extent_root->node->bytenr); + extent_root->node->start); extent_root->root_item.level = - btrfs_header_level(&extent_root->node->node.header); + btrfs_header_level(extent_root->node); ret = btrfs_update_root(trans, tree_root, &extent_root->root_key, &extent_root->root_item); @@ -268,96 +183,187 @@ static int commit_tree_roots(struct btrfs_trans_handle *trans, return 0; } -int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct - btrfs_root *root, struct btrfs_super_block *s) +static int __commit_transaction(struct btrfs_trans_handle *trans, + struct btrfs_root *root) +{ + u64 start; + u64 end; + struct extent_buffer *eb; + struct extent_map_tree *tree = &root->fs_info->extent_cache; + int ret; + + while(1) { + ret = find_first_extent_bit(tree, 0, &start, &end, + EXTENT_DIRTY); + if (ret) + break; + while(start <= end) { + eb = find_first_extent_buffer(tree, start); + BUG_ON(!eb || eb->start != start); + ret = write_tree_block(trans, root, eb); + BUG_ON(ret); + start += eb->len; + clear_extent_buffer_dirty(eb); + free_extent_buffer(eb); + } + } + return 0; +} + +int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + struct btrfs_root *root) { int ret = 0; - struct btrfs_buffer *snap = root->commit_root; - struct btrfs_key snap_key; + struct btrfs_root *new_root = NULL; + struct btrfs_fs_info *fs_info = root->fs_info; if (root->commit_root == root->node) - return 0; + goto commit_tree; - memcpy(&snap_key, &root->root_key, sizeof(snap_key)); - root->root_key.offset = trans->transid; + new_root = malloc(sizeof(*new_root)); + if (!new_root) + return -ENOMEM; + memcpy(new_root, root, sizeof(*new_root)); + new_root->node = root->commit_root; + root->commit_root = NULL; - btrfs_set_root_bytenr(&root->root_item, root->node->bytenr); - root->root_item.level = - btrfs_header_level(&root->node->node.header); - ret = btrfs_insert_root(trans, root->fs_info->tree_root, + root->root_key.offset = trans->transid; + btrfs_set_root_bytenr(&root->root_item, root->node->start); + root->root_item.level = btrfs_header_level(root->node); + ret = btrfs_insert_root(trans, fs_info->tree_root, &root->root_key, &root->root_item); BUG_ON(ret); - ret = commit_tree_roots(trans, root->fs_info); + btrfs_set_root_refs(&new_root->root_item, 0); + ret = btrfs_update_root(trans, root->fs_info->tree_root, + &new_root->root_key, &new_root->root_item); BUG_ON(ret); + ret = commit_tree_roots(trans, fs_info); + BUG_ON(ret); ret = __commit_transaction(trans, root); BUG_ON(ret); + write_ctree_super(trans, root); + btrfs_finish_extent_commit(trans, fs_info->extent_root, + &fs_info->pinned_extents); + btrfs_free_transaction(root, trans); + fs_info->running_transaction = NULL; - write_ctree_super(trans, root, s); - btrfs_finish_extent_commit(trans, root->fs_info->extent_root); - btrfs_finish_extent_commit(trans, root->fs_info->tree_root); - - root->commit_root = root->node; - root->node->count++; - ret = btrfs_drop_snapshot(trans, root, snap); + trans = btrfs_start_transaction(root, 1); + ret = btrfs_drop_snapshot(trans, new_root); + BUG_ON(ret); + ret = btrfs_del_root(trans, fs_info->tree_root, &new_root->root_key); + BUG_ON(ret); +commit_tree: + ret = commit_tree_roots(trans, fs_info); BUG_ON(ret); - ret = btrfs_del_root(trans, root->fs_info->tree_root, &snap_key); + ret = __commit_transaction(trans, root); BUG_ON(ret); + write_ctree_super(trans, root); + btrfs_finish_extent_commit(trans, fs_info->extent_root, + &fs_info->pinned_extents); btrfs_free_transaction(root, trans); - return ret; -} - -static int __setup_root(struct btrfs_super_block *super, - struct btrfs_root *root, - struct btrfs_fs_info *fs_info, - u64 objectid, int fp) -{ - root->node = NULL; + free_extent_buffer(root->commit_root); root->commit_root = NULL; - root->sectorsize = btrfs_super_sectorsize(super); - root->nodesize = btrfs_super_nodesize(super); - root->leafsize = btrfs_super_leafsize(super); - root->stripesize = btrfs_super_stripesize(super); - root->ref_cows = 0; - root->fs_info = fs_info; - memset(&root->root_key, 0, sizeof(root->root_key)); - memset(&root->root_item, 0, sizeof(root->root_item)); - root->root_key.objectid = objectid; + fs_info->running_transaction = NULL; + if (new_root) { + free_extent_buffer(new_root->node); + free(new_root); + } return 0; } -struct btrfs_buffer *read_root_block(struct btrfs_root *root, u64 bytenr, - u8 level) -{ - struct btrfs_buffer *node; - u32 size = btrfs_level_size(root, level); - - node = read_tree_block(root, bytenr, size); - BUG_ON(!node); - return node; -} - -static int find_and_setup_root(struct btrfs_super_block *super, - struct btrfs_root *tree_root, +static int find_and_setup_root(struct btrfs_root *tree_root, struct btrfs_fs_info *fs_info, - u64 objectid, - struct btrfs_root *root, int fp) + u64 objectid, struct btrfs_root *root) { int ret; + u32 blocksize; - __setup_root(super, root, fs_info, objectid, fp); + __setup_root(tree_root->nodesize, tree_root->leafsize, + tree_root->sectorsize, tree_root->stripesize, + root, fs_info, objectid); ret = btrfs_find_last_root(tree_root, objectid, &root->root_item, &root->root_key); BUG_ON(ret); - root->node = read_root_block(root, - btrfs_root_bytenr(&root->root_item), - root->root_item.level); + + blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); + root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), + blocksize); BUG_ON(!root->node); return 0; } -struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) +int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) +{ + if (root->node) + free_extent_buffer(root->node); + if (root->commit_root) + free_extent_buffer(root->commit_root); + + free(root); + return 0; +} + +struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, + struct btrfs_key *location) +{ + struct btrfs_root *root; + struct btrfs_root *tree_root = fs_info->tree_root; + struct btrfs_path *path; + struct extent_buffer *l; + u32 blocksize; + int ret = 0; + + root = malloc(sizeof(*root)); + if (!root) + return ERR_PTR(-ENOMEM); + memset(root, 0, sizeof(*root)); + if (location->offset == (u64)-1) { + ret = find_and_setup_root(tree_root, fs_info, + location->objectid, root); + if (ret) { + free(root); + return ERR_PTR(ret); + } + goto insert; + } + + __setup_root(tree_root->nodesize, tree_root->leafsize, + tree_root->sectorsize, tree_root->stripesize, + root, fs_info, location->objectid); + + path = btrfs_alloc_path(); + BUG_ON(!path); + ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); + if (ret != 0) { + if (ret > 0) + ret = -ENOENT; + goto out; + } + l = path->nodes[0]; + read_extent_buffer(l, &root->root_item, + btrfs_item_ptr_offset(l, path->slots[0]), + sizeof(root->root_item)); + memcpy(&root->root_key, location, sizeof(*location)); + ret = 0; +out: + btrfs_release_path(root, path); + btrfs_free_path(path); + if (ret) { + free(root); + return ERR_PTR(ret); + } + blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); + root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), + blocksize); + BUG_ON(!root->node); +insert: + root->ref_cows = 1; + return root; +} + +struct btrfs_root *open_ctree(char *filename, u64 sb_bytenr) { int fp; @@ -365,145 +371,164 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) if (fp < 0) { return NULL; } - return open_ctree_fd(fp, super); + return open_ctree_fd(fp, sb_bytenr); } -struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super) +struct btrfs_root *open_ctree_fd(int fp, u64 sb_bytenr) { + u32 sectorsize; + u32 nodesize; + u32 leafsize; + u32 blocksize; + u32 stripesize; struct btrfs_root *root = malloc(sizeof(struct btrfs_root)); - struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root)); struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root)); + struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root)); struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info)); int ret; + struct btrfs_super_block *disk_super; + + if (sb_bytenr == 0) + sb_bytenr = BTRFS_SUPER_INFO_OFFSET; - INIT_LIST_HEAD(&fs_info->trans); - INIT_LIST_HEAD(&fs_info->cache); - cache_tree_init(&fs_info->extent_cache); - cache_tree_init(&fs_info->pending_tree); - cache_tree_init(&fs_info->pinned_tree); - cache_tree_init(&fs_info->del_pending); - cache_tree_init(&fs_info->block_group_cache); - fs_info->cache_size = 0; fs_info->fp = fp; fs_info->running_transaction = NULL; fs_info->fs_root = root; fs_info->tree_root = tree_root; fs_info->extent_root = extent_root; - fs_info->last_inode_alloc = 0; - fs_info->last_inode_alloc_dirid = 0; - fs_info->disk_super = super; - memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); - - ret = pread(fp, super, sizeof(struct btrfs_super_block), - BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 || btrfs_super_root(super) == 0) { - BUG(); - return NULL; - } - BUG_ON(ret < 0); - __setup_root(super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID, fp); - tree_root->node = read_root_block(tree_root, btrfs_super_root(super), - btrfs_super_root_level(super)); + extent_map_tree_init(&fs_info->extent_cache); + extent_map_tree_init(&fs_info->free_space_cache); + extent_map_tree_init(&fs_info->pending_tree); + extent_map_tree_init(&fs_info->pinned_extents); + extent_map_tree_init(&fs_info->del_pending); + extent_map_tree_init(&fs_info->block_group_cache); + + mutex_init(&fs_info->fs_mutex); + + __setup_root(512, 512, 512, 512, tree_root, + fs_info, BTRFS_ROOT_TREE_OBJECTID); + + fs_info->sb_buffer = read_tree_block(tree_root, sb_bytenr, 512); + BUG_ON(!fs_info->sb_buffer); + read_extent_buffer(fs_info->sb_buffer, &fs_info->super_copy, 0, + sizeof(fs_info->super_copy)); + read_extent_buffer(fs_info->sb_buffer, fs_info->fsid, + (unsigned long)btrfs_super_fsid(fs_info->sb_buffer), + BTRFS_FSID_SIZE); + disk_super = &fs_info->super_copy; + + nodesize = btrfs_super_nodesize(disk_super); + leafsize = btrfs_super_leafsize(disk_super); + sectorsize = btrfs_super_sectorsize(disk_super); + stripesize = btrfs_super_stripesize(disk_super); + tree_root->nodesize = nodesize; + tree_root->leafsize = leafsize; + tree_root->sectorsize = sectorsize; + tree_root->stripesize = stripesize; + + blocksize = btrfs_level_size(tree_root, + btrfs_super_root_level(disk_super)); + tree_root->node = read_tree_block(tree_root, + btrfs_super_root(disk_super), + blocksize); BUG_ON(!tree_root->node); - - ret = find_and_setup_root(super, tree_root, fs_info, - BTRFS_EXTENT_TREE_OBJECTID, extent_root, fp); + ret = find_and_setup_root(tree_root, fs_info, + BTRFS_EXTENT_TREE_OBJECTID, extent_root); BUG_ON(ret); - - ret = find_and_setup_root(super, tree_root, fs_info, - BTRFS_FS_TREE_OBJECTID, root, fp); + ret = find_and_setup_root(tree_root, fs_info, + BTRFS_FS_TREE_OBJECTID, root); BUG_ON(ret); - - root->commit_root = root->node; - root->node->count++; root->ref_cows = 1; - root->fs_info->generation = btrfs_super_generation(super) + 1; + fs_info->generation = btrfs_super_generation(disk_super) + 1; btrfs_read_block_groups(root); return root; } -int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_super_block *s) +int write_ctree_super(struct btrfs_trans_handle *trans, + struct btrfs_root *root) { int ret; - btrfs_set_super_root(s, root->fs_info->tree_root->node->bytenr); - btrfs_set_super_generation(s, trans->transid); - btrfs_set_super_root_level(s, - btrfs_header_level(&root->fs_info->tree_root->node->node.header)); - btrfs_csum_super(root, s); - - ret = pwrite(root->fs_info->fp, s, sizeof(*s), - BTRFS_SUPER_INFO_OFFSET); - if (ret != sizeof(*s)) { + struct btrfs_root *tree_root = root->fs_info->tree_root; + btrfs_set_super_generation(&root->fs_info->super_copy, + trans->transid); + btrfs_set_super_root(&root->fs_info->super_copy, + tree_root->node->start); + btrfs_set_super_root_level(&root->fs_info->super_copy, + btrfs_header_level(tree_root->node)); + write_extent_buffer(root->fs_info->sb_buffer, + &root->fs_info->super_copy, 0, + sizeof(root->fs_info->super_copy)); + ret = write_tree_block(trans, root, root->fs_info->sb_buffer); + if (ret) fprintf(stderr, "failed to write new super block err %d\n", ret); - return ret; - } - return 0; -} - -static int drop_cache(struct btrfs_root *root) -{ - while(!list_empty(&root->fs_info->cache)) { - struct btrfs_buffer *b = list_entry(root->fs_info->cache.next, - struct btrfs_buffer, - cache); - list_del_init(&b->cache); - btrfs_block_release(root, b); - } - return 0; + return ret; } -int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s) +int close_ctree(struct btrfs_root *root) { int ret; struct btrfs_trans_handle *trans; + struct btrfs_fs_info *fs_info = root->fs_info; + trans = btrfs_start_transaction(root, 1); - btrfs_commit_transaction(trans, root, s); + btrfs_commit_transaction(trans, root); trans = btrfs_start_transaction(root, 1); ret = commit_tree_roots(trans, root->fs_info); BUG_ON(ret); ret = __commit_transaction(trans, root); BUG_ON(ret); - write_ctree_super(trans, root, s); + write_ctree_super(trans, root); btrfs_free_transaction(root, trans); - drop_cache(root); - BUG_ON(!list_empty(&root->fs_info->trans)); btrfs_free_block_groups(root->fs_info); close(root->fs_info->fp); if (root->node) - btrfs_block_release(root, root->node); + free_extent_buffer(root->node); if (root->fs_info->extent_root->node) - btrfs_block_release(root->fs_info->extent_root, - root->fs_info->extent_root->node); + free_extent_buffer(root->fs_info->extent_root->node); if (root->fs_info->tree_root->node) - btrfs_block_release(root->fs_info->tree_root, - root->fs_info->tree_root->node); - btrfs_block_release(root, root->commit_root); - free(root); - printf("on close %llu blocks are allocated\n", - (unsigned long long)allocated_bytes); + free_extent_buffer(root->fs_info->tree_root->node); + free_extent_buffer(root->commit_root); + free_extent_buffer(root->fs_info->sb_buffer); + + extent_map_tree_cleanup(&fs_info->extent_cache); + extent_map_tree_cleanup(&fs_info->free_space_cache); + extent_map_tree_cleanup(&fs_info->pending_tree); + extent_map_tree_cleanup(&fs_info->pinned_extents); + extent_map_tree_cleanup(&fs_info->del_pending); + extent_map_tree_cleanup(&fs_info->block_group_cache); + + free(fs_info->tree_root); + free(fs_info->extent_root); + free(fs_info->fs_root); + free(fs_info); + return 0; } -void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf) +int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct extent_buffer *eb) { - buf->count--; - if (buf->count < 0) - BUG(); - if (buf->count == 0) { - BUG_ON(!list_empty(&buf->cache)); - BUG_ON(!list_empty(&buf->dirty)); - - remove_cache_extent(&root->fs_info->extent_cache, - &buf->cache_node); - BUG_ON(allocated_bytes == 0); - allocated_bytes -= buf->size; - BUG_ON(root->fs_info->cache_size == 0); - root->fs_info->cache_size -= buf->size; - - memset(buf, 0, sizeof(*buf)); - free(buf); - } + return clear_extent_buffer_dirty(eb); +} + +int wait_on_tree_block_writeback(struct btrfs_root *root, + struct extent_buffer *eb) +{ + return 0; +} + +void btrfs_mark_buffer_dirty(struct extent_buffer *eb) +{ + set_extent_buffer_dirty(eb); } +int btrfs_buffer_uptodate(struct extent_buffer *eb) +{ + return extent_buffer_uptodate(eb); +} + +int btrfs_set_buffer_uptodate(struct extent_buffer *eb) +{ + return set_extent_buffer_uptodate(eb); +} -- cgit v1.2.3