Commit 7bb86316 authored by Chris Mason's avatar Chris Mason

Btrfs: Add back pointers from extents to the btree or file referencing them

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 74493f7a
This diff is collapsed.
......@@ -544,11 +544,12 @@ BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64);
BTRFS_SETGET_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64);
BTRFS_SETGET_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64);
BTRFS_SETGET_STACK_FUNCS(ref_root, struct btrfs_extent_ref, root, 64);
BTRFS_SETGET_STACK_FUNCS(ref_generation, struct btrfs_extent_ref,
BTRFS_SETGET_STACK_FUNCS(stack_ref_root, struct btrfs_extent_ref, root, 64);
BTRFS_SETGET_STACK_FUNCS(stack_ref_generation, struct btrfs_extent_ref,
generation, 64);
BTRFS_SETGET_STACK_FUNCS(ref_objectid, struct btrfs_extent_ref, objectid, 64);
BTRFS_SETGET_STACK_FUNCS(ref_offset, struct btrfs_extent_ref, offset, 64);
BTRFS_SETGET_STACK_FUNCS(stack_ref_objectid, struct btrfs_extent_ref,
objectid, 64);
BTRFS_SETGET_STACK_FUNCS(stack_ref_offset, struct btrfs_extent_ref, offset, 64);
BTRFS_SETGET_STACK_FUNCS(stack_extent_refs, struct btrfs_extent_item,
refs, 32);
......@@ -914,24 +915,45 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
*hint, u64 search_start,
int data, int owner);
int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
struct btrfs_root *root, u64 owner_objectid);
struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u32 size,
u64 root_objectid,
u64 hint, u64 empty_size);
struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
u32 blocksize,
u64 root_objectid,
u64 ref_generation,
u64 first_objectid,
int level,
u64 hint,
u64 empty_size);
int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path, u64 bytenr,
u64 root_objectid, u64 ref_generation,
u64 owner, u64 owner_offset);
int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 owner,
u64 num_bytes, u64 empty_size, u64 search_start,
struct btrfs_root *root,
u64 num_bytes, u64 root_objectid, u64 ref_generation,
u64 owner, u64 owner_offset,
u64 empty_size, u64 hint_byte,
u64 search_end, struct btrfs_key *ins, int data);
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct extent_buffer *buf);
int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
*root, u64 bytenr, u64 num_bytes, int pin);
*root, u64 bytenr, u64 num_bytes,
u64 root_objectid, u64 ref_generation,
u64 owner_objectid, u64 owner_offset, int pin);
int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_map_tree *unpin);
int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
u64 bytenr, u64 num_bytes);
u64 bytenr, u64 num_bytes,
u64 root_objectid, u64 ref_generation,
u64 owner, u64 owner_offset);
int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_free_block_groups(struct btrfs_fs_info *info);
......@@ -966,6 +988,7 @@ 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_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
*root);
......
......@@ -210,7 +210,7 @@ static int btree_writepages(struct address_space *mapping,
{
struct extent_map_tree *tree;
tree = &BTRFS_I(mapping->host)->extent_tree;
if (wbc->sync_mode == WB_SYNC_NONE) {
if (0 && wbc->sync_mode == WB_SYNC_NONE) {
u64 num_dirty;
u64 start = 0;
unsigned long thresh = 96 * 1024 * 1024;
......
This diff is collapsed.
......@@ -496,7 +496,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
sizeof(old));
if (disk_bytenr != 0) {
ret = btrfs_inc_extent_ref(trans, root,
disk_bytenr, disk_num_bytes);
disk_bytenr, disk_num_bytes,
root->root_key.objectid,
trans->transid,
key.objectid, end);
BUG_ON(ret);
}
}
......@@ -541,6 +544,14 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
u64 disk_bytenr = 0;
u64 disk_num_bytes = 0;
u64 extent_num_bytes = 0;
u64 root_gen;
if (leaf != root->node) {
root_gen =
btrfs_header_generation(path->nodes[1]);
} else {
root_gen = btrfs_header_generation(leaf);
}
if (found_extent) {
disk_bytenr =
btrfs_file_extent_disk_bytenr(leaf,
......@@ -563,7 +574,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
inode->i_blocks -= extent_num_bytes >> 9;
ret = btrfs_free_extent(trans, root,
disk_bytenr,
disk_num_bytes, 0);
disk_num_bytes,
root->root_key.objectid,
root_gen, inode->i_ino,
key.offset, 0);
}
BUG_ON(ret);
......
......@@ -93,7 +93,9 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end)
if (alloc_hint == EXTENT_MAP_INLINE)
goto out;
ret = btrfs_alloc_extent(trans, root, inode->i_ino, num_bytes, 0,
ret = btrfs_alloc_extent(trans, root, num_bytes,
root->root_key.objectid, trans->transid,
inode->i_ino, start, 0,
alloc_hint, (u64)-1, &ins, 1);
if (ret) {
WARN_ON(1);
......@@ -560,6 +562,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
u64 extent_start = 0;
u64 extent_num_bytes = 0;
u64 item_end = 0;
u64 root_gen = 0;
int found_extent;
int del_item;
int extent_type = -1;
......@@ -670,6 +673,15 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
found_extent = 1;
inode->i_blocks -= num_dec;
}
if (leaf == root->node) {
root_gen =
btrfs_header_generation(leaf);
} else {
struct extent_buffer *parent;
parent = path->nodes[1];
root_gen =
btrfs_header_generation(parent);
}
}
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE &&
!del_item) {
......@@ -690,7 +702,10 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
btrfs_release_path(root, path);
if (found_extent) {
ret = btrfs_free_extent(trans, root, extent_start,
extent_num_bytes, 0);
extent_num_bytes,
root->root_key.objectid,
root_gen, inode->i_ino,
found_key.offset, 0);
BUG_ON(ret);
}
}
......@@ -1900,7 +1915,14 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
trans = btrfs_start_transaction(root, 1);
BUG_ON(!trans);
leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, 0);
ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root,
0, &objectid);
if (ret)
goto fail;
leaf = __btrfs_alloc_free_block(trans, root, root->leafsize,
objectid, trans->transid, 0, 0,
0, 0);
if (IS_ERR(leaf))
return PTR_ERR(leaf);
......@@ -1908,7 +1930,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
btrfs_set_header_level(leaf, 0);
btrfs_set_header_bytenr(leaf, leaf->start);
btrfs_set_header_generation(leaf, trans->transid);
btrfs_set_header_owner(leaf, root->root_key.objectid);
btrfs_set_header_owner(leaf, objectid);
write_extent_buffer(leaf, root->fs_info->fsid,
(unsigned long)btrfs_header_fsid(leaf),
BTRFS_FSID_SIZE);
......@@ -1933,11 +1956,6 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
free_extent_buffer(leaf);
leaf = NULL;
ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root,
0, &objectid);
if (ret)
goto fail;
btrfs_set_root_dirid(&root_item, new_dirid);
key.objectid = objectid;
......@@ -2056,7 +2074,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
if (ret)
goto fail;
ret = btrfs_inc_root_ref(trans, root);
ret = btrfs_inc_root_ref(trans, root, objectid);
if (ret)
goto fail;
fail:
......
......@@ -33,6 +33,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
struct btrfs_file_extent_item *fi;
struct btrfs_key key;
struct btrfs_key found_key;
struct btrfs_extent_ref *ref;
u32 type;
printk("leaf %llu total ptrs %d free space %d\n",
......@@ -73,6 +74,15 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
printk("\t\textent data refs %u\n",
btrfs_extent_refs(l, ei));
break;
case BTRFS_EXTENT_REF_KEY:
ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref);
printk("\t\textent back ref root %llu gen %llu "
"owner %llu offset %llu\n",
(unsigned long long)btrfs_ref_root(l, ref),
(unsigned long long)btrfs_ref_generation(l, ref),
(unsigned long long)btrfs_ref_objectid(l, ref),
(unsigned long long)btrfs_ref_offset(l, ref));
break;
case BTRFS_EXTENT_DATA_KEY:
fi = btrfs_item_ptr(l, i,
......
......@@ -78,6 +78,8 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
break;
if (*level == 1) {
WARN_ON(btrfs_header_generation(path->nodes[*level]) !=
trans->transid);
ret = btrfs_realloc_node(trans, root,
path->nodes[*level],
path->slots[*level],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment