Loading fs/btrfs/dir-item.c +10 −8 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root objectid, u8 type) { int ret = 0; struct btrfs_path path; struct btrfs_path *path; struct btrfs_dir_item *dir_item; char *name_ptr; struct btrfs_key key; Loading @@ -20,24 +20,26 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); ret = btrfs_name_hash(name, name_len, &key.offset); BUG_ON(ret); btrfs_init_path(&path); path = btrfs_alloc_path(); btrfs_init_path(path); data_size = sizeof(*dir_item) + name_len; ret = btrfs_insert_empty_item(trans, root, &path, &key, data_size); ret = btrfs_insert_empty_item(trans, root, path, &key, data_size); if (ret) goto out; dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_dir_item); btrfs_set_dir_objectid(dir_item, objectid); btrfs_set_dir_type(dir_item, type); btrfs_set_dir_flags(dir_item, 0); btrfs_set_dir_name_len(dir_item, name_len); name_ptr = (char *)(dir_item + 1); btrfs_memcpy(root, path.nodes[0]->b_data, name_ptr, name, name_len); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); btrfs_mark_buffer_dirty(path->nodes[0]); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading fs/btrfs/extent-tree.c +61 −39 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks) { struct btrfs_path path; struct btrfs_path *path; int ret; struct btrfs_key key; struct btrfs_leaf *l; Loading @@ -25,23 +25,26 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1, &ins); btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); key.objectid = blocknr; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); key.offset = num_blocks; ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 0, 1); if (ret != 0) BUG(); BUG_ON(ret != 0); l = btrfs_buffer_leaf(path.nodes[0]); item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); l = btrfs_buffer_leaf(path->nodes[0]); item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(item); btrfs_set_extent_refs(item, refs + 1); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_release_path(root->fs_info->extent_root, &path); btrfs_release_path(root->fs_info->extent_root, path); btrfs_free_path(path); finish_current_insert(trans, root->fs_info->extent_root); del_pending_extents(trans, root->fs_info->extent_root); return 0; Loading @@ -50,24 +53,27 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks, u32 *refs) { struct btrfs_path path; struct btrfs_path *path; int ret; struct btrfs_key key; struct btrfs_leaf *l; struct btrfs_extent_item *item; btrfs_init_path(&path); path = btrfs_alloc_path(); btrfs_init_path(path); key.objectid = blocknr; key.offset = num_blocks; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 0, 0); if (ret != 0) BUG(); l = btrfs_buffer_leaf(path.nodes[0]); item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); l = btrfs_buffer_leaf(path->nodes[0]); item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); *refs = btrfs_extent_refs(item); btrfs_release_path(root->fs_info->extent_root, &path); btrfs_release_path(root->fs_info->extent_root, path); btrfs_free_path(path); return 0; } Loading Loading @@ -200,7 +206,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks, int pin) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; struct btrfs_fs_info *info = root->fs_info; struct btrfs_root *extent_root = info->extent_root; Loading @@ -215,20 +221,22 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root key.offset = num_blocks; find_free_extent(trans, root, 0, 0, (u64)-1, &ins); btrfs_init_path(&path); ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); if (ret) { printk("failed to find %Lu\n", key.objectid); btrfs_print_tree(extent_root, extent_root->node); printk("failed to find %Lu\n", key.objectid); BUG(); } ei = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_extent_item); BUG_ON(ei->refs == 0); refs = btrfs_extent_refs(ei) - 1; btrfs_set_extent_refs(ei, refs); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); if (refs == 0) { u64 super_blocks_used; Loading @@ -240,13 +248,14 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root super_blocks_used = btrfs_super_blocks_used(info->disk_super); btrfs_set_super_blocks_used(info->disk_super, super_blocks_used - num_blocks); ret = btrfs_del_item(trans, extent_root, &path); ret = btrfs_del_item(trans, extent_root, path); if (extent_root->fs_info->last_insert.objectid > blocknr) extent_root->fs_info->last_insert.objectid = blocknr; if (ret) BUG(); } btrfs_release_path(extent_root, &path); btrfs_release_path(extent_root, path); btrfs_free_path(path); finish_current_insert(trans, extent_root); return ret; } Loading Loading @@ -319,7 +328,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *orig_root, u64 num_blocks, u64 search_start, u64 search_end, struct btrfs_key *ins) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; int ret; u64 hole_size = 0; Loading @@ -339,24 +348,25 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root ins->flags = 0; btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); path = btrfs_alloc_path(); check_failed: btrfs_init_path(&path); btrfs_init_path(path); ins->objectid = search_start; ins->offset = 0; start_found = 0; ret = btrfs_search_slot(trans, root, ins, &path, 0, 0); ret = btrfs_search_slot(trans, root, ins, path, 0, 0); if (ret < 0) goto error; if (path.slots[0] > 0) path.slots[0]--; if (path->slots[0] > 0) path->slots[0]--; while (1) { l = btrfs_buffer_leaf(path.nodes[0]); slot = path.slots[0]; l = btrfs_buffer_leaf(path->nodes[0]); slot = path->slots[0]; if (slot >= btrfs_header_nritems(&l->header)) { ret = btrfs_next_leaf(root, &path); ret = btrfs_next_leaf(root, path); if (ret == 0) continue; if (ret < 0) Loading Loading @@ -387,14 +397,14 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root } start_found = 1; last_block = key.objectid + key.offset; path.slots[0]++; path->slots[0]++; } // FIXME -ENOSPC check_pending: /* we have to make sure we didn't find an extent that has already * been allocated by the map tree or the original allocation */ btrfs_release_path(root, &path); btrfs_release_path(root, path); BUG_ON(ins->objectid < search_start); for (test_block = ins->objectid; test_block < ins->objectid + total_needed; test_block++) { Loading @@ -410,9 +420,11 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root root->fs_info->current_insert.flags = 0; root->fs_info->last_insert.objectid = ins->objectid; ins->offset = num_blocks; btrfs_free_path(path); return 0; error: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading Loading @@ -533,6 +545,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root int ret; u32 refs; WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr, 1, &refs); BUG_ON(ret); Loading @@ -542,6 +556,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root * walk down to the last node level and free all the leaves */ while(*level >= 0) { WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); cur = path->nodes[*level]; if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) WARN_ON(1); Loading @@ -564,6 +580,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root continue; } next = read_tree_block(root, blocknr); WARN_ON(*level <= 0); if (path->nodes[*level-1]) btrfs_block_release(root, path->nodes[*level-1]); path->nodes[*level-1] = next; Loading @@ -571,6 +588,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root path->slots[*level] = 0; } out: WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); ret = btrfs_free_extent(trans, root, path->nodes[*level]->b_blocknr, 1, 1); btrfs_block_release(root, path->nodes[*level]); Loading Loading @@ -622,33 +641,36 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root int ret = 0; int wret; int level; struct btrfs_path path; struct btrfs_path *path; int i; int orig_level; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); level = btrfs_header_level(btrfs_buffer_header(snap)); orig_level = level; path.nodes[level] = snap; path.slots[level] = 0; path->nodes[level] = snap; path->slots[level] = 0; while(1) { wret = walk_down_tree(trans, root, &path, &level); wret = walk_down_tree(trans, root, path, &level); if (wret > 0) break; if (wret < 0) ret = wret; wret = walk_up_tree(trans, root, &path, &level); wret = walk_up_tree(trans, root, path, &level); if (wret > 0) break; if (wret < 0) ret = wret; } for (i = 0; i <= orig_level; i++) { if (path.nodes[i]) { btrfs_block_release(root, path.nodes[i]); if (path->nodes[i]) { btrfs_block_release(root, path->nodes[i]); } } btrfs_free_path(path); return ret; } fs/btrfs/file-item.c +26 −17 Original line number Diff line number Diff line Loading @@ -13,9 +13,11 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, int ret = 0; struct btrfs_file_extent_item *item; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, (u64)-1, objectid, &ins); BUG_ON(ret); Loading @@ -24,19 +26,20 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); ret = btrfs_insert_empty_item(trans, root, &path, &file_key, ret = btrfs_insert_empty_item(trans, root, path, &file_key, sizeof(*item)); BUG_ON(ret); item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_file_extent_item); btrfs_set_file_extent_disk_blocknr(item, ins.objectid); btrfs_set_file_extent_disk_num_blocks(item, ins.offset); btrfs_set_file_extent_offset(item, 0); btrfs_set_file_extent_num_blocks(item, ins.offset); btrfs_set_file_extent_generation(item, trans->transid); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); *result = ins.objectid; btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return 0; } Loading Loading @@ -65,25 +68,28 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, { int ret; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; struct btrfs_csum_item *item; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); file_key.objectid = objectid; file_key.offset = offset; file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); ret = btrfs_insert_empty_item(trans, root, &path, &file_key, ret = btrfs_insert_empty_item(trans, root, path, &file_key, BTRFS_CSUM_SIZE); if (ret != 0 && ret != -EEXIST) goto fail; item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_csum_item); ret = 0; ret = btrfs_csum_data(root, data, len, item->csum); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); fail: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -93,19 +99,21 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, { int ret; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; struct btrfs_csum_item *item; char result[BTRFS_CSUM_SIZE]; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); file_key.objectid = objectid; file_key.offset = offset; file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); ret = btrfs_search_slot(NULL, root, &file_key, &path, 0, 0); ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0); if (ret) goto fail; item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_csum_item); ret = 0; ret = btrfs_csum_data(root, data, len, result); Loading @@ -113,7 +121,8 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) ret = 1; fail: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } fs/btrfs/inode-item.c +6 −3 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid, struct btrfs_inode_item *inode_item) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; int ret; key.objectid = objectid; Loading @@ -15,10 +15,13 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); key.offset = 0; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_insert_item(trans, root, &key, inode_item, sizeof(*inode_item)); btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading fs/btrfs/root-tree.c +28 −19 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct btrfs_root_item *item, struct btrfs_key *key) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key search_key; struct btrfs_leaf *l; int ret; Loading @@ -16,14 +16,16 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, search_key.flags = (u32)-1; search_key.offset = (u32)-1; btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &search_key, &path, 0, 0); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); if (ret < 0) goto out; BUG_ON(ret == 0); l = btrfs_buffer_leaf(path.nodes[0]); BUG_ON(path.slots[0] == 0); slot = path.slots[0] - 1; l = btrfs_buffer_leaf(path->nodes[0]); BUG_ON(path->slots[0] == 0); slot = path->slots[0] - 1; if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { ret = 1; goto out; Loading @@ -31,9 +33,10 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item), sizeof(*item)); btrfs_disk_key_to_cpu(key, &l->items[slot].key); btrfs_release_path(root, &path); ret = 0; out: btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -41,24 +44,27 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_leaf *l; int ret; int slot; struct btrfs_root_item *update_item; btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, key, &path, 0, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, root, key, path, 0, 1); if (ret < 0) goto out; BUG_ON(ret != 0); l = btrfs_buffer_leaf(path.nodes[0]); slot = path.slots[0]; l = btrfs_buffer_leaf(path->nodes[0]); slot = path->slots[0]; update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item); btrfs_memcpy(root, l, update_item, item, sizeof(*item)); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -75,16 +81,19 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root 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; btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, key, &path, -1, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, root, key, path, -1, 1); if (ret < 0) goto out; BUG_ON(ret != 0); ret = btrfs_del_item(trans, root, &path); ret = btrfs_del_item(trans, root, path); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading
fs/btrfs/dir-item.c +10 −8 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root objectid, u8 type) { int ret = 0; struct btrfs_path path; struct btrfs_path *path; struct btrfs_dir_item *dir_item; char *name_ptr; struct btrfs_key key; Loading @@ -20,24 +20,26 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); ret = btrfs_name_hash(name, name_len, &key.offset); BUG_ON(ret); btrfs_init_path(&path); path = btrfs_alloc_path(); btrfs_init_path(path); data_size = sizeof(*dir_item) + name_len; ret = btrfs_insert_empty_item(trans, root, &path, &key, data_size); ret = btrfs_insert_empty_item(trans, root, path, &key, data_size); if (ret) goto out; dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_dir_item); btrfs_set_dir_objectid(dir_item, objectid); btrfs_set_dir_type(dir_item, type); btrfs_set_dir_flags(dir_item, 0); btrfs_set_dir_name_len(dir_item, name_len); name_ptr = (char *)(dir_item + 1); btrfs_memcpy(root, path.nodes[0]->b_data, name_ptr, name, name_len); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); btrfs_mark_buffer_dirty(path->nodes[0]); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading
fs/btrfs/extent-tree.c +61 −39 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks) { struct btrfs_path path; struct btrfs_path *path; int ret; struct btrfs_key key; struct btrfs_leaf *l; Loading @@ -25,23 +25,26 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1, &ins); btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); key.objectid = blocknr; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); key.offset = num_blocks; ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 0, 1); if (ret != 0) BUG(); BUG_ON(ret != 0); l = btrfs_buffer_leaf(path.nodes[0]); item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); l = btrfs_buffer_leaf(path->nodes[0]); item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(item); btrfs_set_extent_refs(item, refs + 1); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_release_path(root->fs_info->extent_root, &path); btrfs_release_path(root->fs_info->extent_root, path); btrfs_free_path(path); finish_current_insert(trans, root->fs_info->extent_root); del_pending_extents(trans, root->fs_info->extent_root); return 0; Loading @@ -50,24 +53,27 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks, u32 *refs) { struct btrfs_path path; struct btrfs_path *path; int ret; struct btrfs_key key; struct btrfs_leaf *l; struct btrfs_extent_item *item; btrfs_init_path(&path); path = btrfs_alloc_path(); btrfs_init_path(path); key.objectid = blocknr; key.offset = num_blocks; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 0, 0); if (ret != 0) BUG(); l = btrfs_buffer_leaf(path.nodes[0]); item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); l = btrfs_buffer_leaf(path->nodes[0]); item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); *refs = btrfs_extent_refs(item); btrfs_release_path(root->fs_info->extent_root, &path); btrfs_release_path(root->fs_info->extent_root, path); btrfs_free_path(path); return 0; } Loading Loading @@ -200,7 +206,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 blocknr, u64 num_blocks, int pin) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; struct btrfs_fs_info *info = root->fs_info; struct btrfs_root *extent_root = info->extent_root; Loading @@ -215,20 +221,22 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root key.offset = num_blocks; find_free_extent(trans, root, 0, 0, (u64)-1, &ins); btrfs_init_path(&path); ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); if (ret) { printk("failed to find %Lu\n", key.objectid); btrfs_print_tree(extent_root, extent_root->node); printk("failed to find %Lu\n", key.objectid); BUG(); } ei = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_extent_item); BUG_ON(ei->refs == 0); refs = btrfs_extent_refs(ei) - 1; btrfs_set_extent_refs(ei, refs); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); if (refs == 0) { u64 super_blocks_used; Loading @@ -240,13 +248,14 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root super_blocks_used = btrfs_super_blocks_used(info->disk_super); btrfs_set_super_blocks_used(info->disk_super, super_blocks_used - num_blocks); ret = btrfs_del_item(trans, extent_root, &path); ret = btrfs_del_item(trans, extent_root, path); if (extent_root->fs_info->last_insert.objectid > blocknr) extent_root->fs_info->last_insert.objectid = blocknr; if (ret) BUG(); } btrfs_release_path(extent_root, &path); btrfs_release_path(extent_root, path); btrfs_free_path(path); finish_current_insert(trans, extent_root); return ret; } Loading Loading @@ -319,7 +328,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *orig_root, u64 num_blocks, u64 search_start, u64 search_end, struct btrfs_key *ins) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; int ret; u64 hole_size = 0; Loading @@ -339,24 +348,25 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root ins->flags = 0; btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); path = btrfs_alloc_path(); check_failed: btrfs_init_path(&path); btrfs_init_path(path); ins->objectid = search_start; ins->offset = 0; start_found = 0; ret = btrfs_search_slot(trans, root, ins, &path, 0, 0); ret = btrfs_search_slot(trans, root, ins, path, 0, 0); if (ret < 0) goto error; if (path.slots[0] > 0) path.slots[0]--; if (path->slots[0] > 0) path->slots[0]--; while (1) { l = btrfs_buffer_leaf(path.nodes[0]); slot = path.slots[0]; l = btrfs_buffer_leaf(path->nodes[0]); slot = path->slots[0]; if (slot >= btrfs_header_nritems(&l->header)) { ret = btrfs_next_leaf(root, &path); ret = btrfs_next_leaf(root, path); if (ret == 0) continue; if (ret < 0) Loading Loading @@ -387,14 +397,14 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root } start_found = 1; last_block = key.objectid + key.offset; path.slots[0]++; path->slots[0]++; } // FIXME -ENOSPC check_pending: /* we have to make sure we didn't find an extent that has already * been allocated by the map tree or the original allocation */ btrfs_release_path(root, &path); btrfs_release_path(root, path); BUG_ON(ins->objectid < search_start); for (test_block = ins->objectid; test_block < ins->objectid + total_needed; test_block++) { Loading @@ -410,9 +420,11 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root root->fs_info->current_insert.flags = 0; root->fs_info->last_insert.objectid = ins->objectid; ins->offset = num_blocks; btrfs_free_path(path); return 0; error: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading Loading @@ -533,6 +545,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root int ret; u32 refs; WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr, 1, &refs); BUG_ON(ret); Loading @@ -542,6 +556,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root * walk down to the last node level and free all the leaves */ while(*level >= 0) { WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); cur = path->nodes[*level]; if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) WARN_ON(1); Loading @@ -564,6 +580,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root continue; } next = read_tree_block(root, blocknr); WARN_ON(*level <= 0); if (path->nodes[*level-1]) btrfs_block_release(root, path->nodes[*level-1]); path->nodes[*level-1] = next; Loading @@ -571,6 +588,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root path->slots[*level] = 0; } out: WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); ret = btrfs_free_extent(trans, root, path->nodes[*level]->b_blocknr, 1, 1); btrfs_block_release(root, path->nodes[*level]); Loading Loading @@ -622,33 +641,36 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root int ret = 0; int wret; int level; struct btrfs_path path; struct btrfs_path *path; int i; int orig_level; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); level = btrfs_header_level(btrfs_buffer_header(snap)); orig_level = level; path.nodes[level] = snap; path.slots[level] = 0; path->nodes[level] = snap; path->slots[level] = 0; while(1) { wret = walk_down_tree(trans, root, &path, &level); wret = walk_down_tree(trans, root, path, &level); if (wret > 0) break; if (wret < 0) ret = wret; wret = walk_up_tree(trans, root, &path, &level); wret = walk_up_tree(trans, root, path, &level); if (wret > 0) break; if (wret < 0) ret = wret; } for (i = 0; i <= orig_level; i++) { if (path.nodes[i]) { btrfs_block_release(root, path.nodes[i]); if (path->nodes[i]) { btrfs_block_release(root, path->nodes[i]); } } btrfs_free_path(path); return ret; }
fs/btrfs/file-item.c +26 −17 Original line number Diff line number Diff line Loading @@ -13,9 +13,11 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, int ret = 0; struct btrfs_file_extent_item *item; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, (u64)-1, objectid, &ins); BUG_ON(ret); Loading @@ -24,19 +26,20 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); ret = btrfs_insert_empty_item(trans, root, &path, &file_key, ret = btrfs_insert_empty_item(trans, root, path, &file_key, sizeof(*item)); BUG_ON(ret); item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_file_extent_item); btrfs_set_file_extent_disk_blocknr(item, ins.objectid); btrfs_set_file_extent_disk_num_blocks(item, ins.offset); btrfs_set_file_extent_offset(item, 0); btrfs_set_file_extent_num_blocks(item, ins.offset); btrfs_set_file_extent_generation(item, trans->transid); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); *result = ins.objectid; btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return 0; } Loading Loading @@ -65,25 +68,28 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, { int ret; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; struct btrfs_csum_item *item; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); file_key.objectid = objectid; file_key.offset = offset; file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); ret = btrfs_insert_empty_item(trans, root, &path, &file_key, ret = btrfs_insert_empty_item(trans, root, path, &file_key, BTRFS_CSUM_SIZE); if (ret != 0 && ret != -EEXIST) goto fail; item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_csum_item); ret = 0; ret = btrfs_csum_data(root, data, len, item->csum); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); fail: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -93,19 +99,21 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, { int ret; struct btrfs_key file_key; struct btrfs_path path; struct btrfs_path *path; struct btrfs_csum_item *item; char result[BTRFS_CSUM_SIZE]; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); file_key.objectid = objectid; file_key.offset = offset; file_key.flags = 0; btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); ret = btrfs_search_slot(NULL, root, &file_key, &path, 0, 0); ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0); if (ret) goto fail; item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_csum_item); ret = 0; ret = btrfs_csum_data(root, data, len, result); Loading @@ -113,7 +121,8 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) ret = 1; fail: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; }
fs/btrfs/inode-item.c +6 −3 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid, struct btrfs_inode_item *inode_item) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key key; int ret; key.objectid = objectid; Loading @@ -15,10 +15,13 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); key.offset = 0; btrfs_init_path(&path); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_insert_item(trans, root, &key, inode_item, sizeof(*inode_item)); btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading
fs/btrfs/root-tree.c +28 −19 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct btrfs_root_item *item, struct btrfs_key *key) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_key search_key; struct btrfs_leaf *l; int ret; Loading @@ -16,14 +16,16 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, search_key.flags = (u32)-1; search_key.offset = (u32)-1; btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &search_key, &path, 0, 0); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); if (ret < 0) goto out; BUG_ON(ret == 0); l = btrfs_buffer_leaf(path.nodes[0]); BUG_ON(path.slots[0] == 0); slot = path.slots[0] - 1; l = btrfs_buffer_leaf(path->nodes[0]); BUG_ON(path->slots[0] == 0); slot = path->slots[0] - 1; if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { ret = 1; goto out; Loading @@ -31,9 +33,10 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item), sizeof(*item)); btrfs_disk_key_to_cpu(key, &l->items[slot].key); btrfs_release_path(root, &path); ret = 0; out: btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -41,24 +44,27 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item) { struct btrfs_path path; struct btrfs_path *path; struct btrfs_leaf *l; int ret; int slot; struct btrfs_root_item *update_item; btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, key, &path, 0, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, root, key, path, 0, 1); if (ret < 0) goto out; BUG_ON(ret != 0); l = btrfs_buffer_leaf(path.nodes[0]); slot = path.slots[0]; l = btrfs_buffer_leaf(path->nodes[0]); slot = path->slots[0]; update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item); btrfs_memcpy(root, l, update_item, item, sizeof(*item)); btrfs_mark_buffer_dirty(path.nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; } Loading @@ -75,16 +81,19 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root 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; btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, key, &path, -1, 1); path = btrfs_alloc_path(); BUG_ON(!path); btrfs_init_path(path); ret = btrfs_search_slot(trans, root, key, path, -1, 1); if (ret < 0) goto out; BUG_ON(ret != 0); ret = btrfs_del_item(trans, root, &path); ret = btrfs_del_item(trans, root, path); out: btrfs_release_path(root, &path); btrfs_release_path(root, path); btrfs_free_path(path); return ret; }