Loading fs/btrfs/ctree.c +16 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, } else { btrfs_set_node_blockptr(parent, parent_slot, cow->start); WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); btrfs_mark_buffer_dirty(parent); WARN_ON(btrfs_header_generation(parent) != trans->transid); btrfs_free_extent(trans, root, buf->start, buf->len, 1); Loading Loading @@ -967,6 +970,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root { struct extent_buffer *b; u64 bytenr; u64 ptr_gen; int slot; int ret; int level; Loading Loading @@ -1031,10 +1035,18 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if (level == lowest_level) break; bytenr = btrfs_node_blockptr(b, slot); ptr_gen = btrfs_node_ptr_generation(b, slot); if (should_reada) reada_for_search(root, p, level, slot); b = read_tree_block(root, bytenr, btrfs_level_size(root, level - 1)); if (ptr_gen != btrfs_header_generation(b)) { printk("block %llu bad gen wanted %llu " "found %llu\n", (unsigned long long)b->start, (unsigned long long)ptr_gen, (unsigned long long)btrfs_header_generation(b)); } } else { p->slots[level] = slot; if (ins_len > 0 && btrfs_leaf_free_space(root, b) < Loading Loading @@ -1218,6 +1230,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans, btrfs_node_key(lower, &lower_key, 0); btrfs_set_node_key(c, &lower_key, 0); btrfs_set_node_blockptr(c, 0, lower->start); WARN_ON(btrfs_header_generation(lower) == 0); btrfs_set_node_ptr_generation(c, 0, btrfs_header_generation(lower)); btrfs_mark_buffer_dirty(c); Loading Loading @@ -1261,6 +1275,8 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root } btrfs_set_node_key(lower, key, slot); btrfs_set_node_blockptr(lower, slot, bytenr); WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(lower, nritems + 1); btrfs_mark_buffer_dirty(lower); return 0; Loading fs/btrfs/ctree.h +41 −6 Original line number Diff line number Diff line Loading @@ -110,7 +110,7 @@ struct btrfs_header { #define BTRFS_MAX_LEVEL 8 #define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \ sizeof(struct btrfs_header)) / \ (sizeof(struct btrfs_disk_key) + sizeof(u64))) sizeof(struct btrfs_key_ptr)) #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) #define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize)) #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ Loading Loading @@ -168,6 +168,7 @@ struct btrfs_leaf { struct btrfs_key_ptr { struct btrfs_disk_key key; __le64 blockptr; __le64 generation; } __attribute__ ((__packed__)); struct btrfs_node { Loading Loading @@ -196,7 +197,13 @@ struct btrfs_path { */ struct btrfs_extent_item { __le32 refs; __le64 owner; } __attribute__ ((__packed__)); struct btrfs_extent_ref { __le64 root; __le64 generation; __le64 objectid; __le64 offset; } __attribute__ ((__packed__)); struct btrfs_inode_timespec { Loading Loading @@ -402,12 +409,13 @@ struct btrfs_root { * are used, and how many references there are to each block */ #define BTRFS_EXTENT_ITEM_KEY 33 #define BTRFS_EXTENT_REF_KEY 34 /* * block groups give us hints into the extent allocation trees. Which * blocks are free etc etc */ #define BTRFS_BLOCK_GROUP_ITEM_KEY 34 #define BTRFS_BLOCK_GROUP_ITEM_KEY 50 /* * string items are for debugging. They just store a short string of Loading Loading @@ -529,15 +537,25 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32); /* struct btrfs_extent_item */ BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); BTRFS_SETGET_FUNCS(extent_owner, struct btrfs_extent_item, owner, 64); /* struct btrfs_extent_ref */ BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64); 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, 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_extent_refs, struct btrfs_extent_item, refs, 32); BTRFS_SETGET_STACK_FUNCS(stack_extent_owner, struct btrfs_extent_item, owner, 64); /* struct btrfs_node */ BTRFS_SETGET_FUNCS(key_blockptr, struct btrfs_key_ptr, blockptr, 64); BTRFS_SETGET_FUNCS(key_generation, struct btrfs_key_ptr, generation, 64); static inline u64 btrfs_node_blockptr(struct extent_buffer *eb, int nr) { Loading @@ -556,6 +574,23 @@ static inline void btrfs_set_node_blockptr(struct extent_buffer *eb, btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); } static inline u64 btrfs_node_ptr_generation(struct extent_buffer *eb, int nr) { unsigned long ptr; ptr = offsetof(struct btrfs_node, ptrs) + sizeof(struct btrfs_key_ptr) * nr; return btrfs_key_generation(eb, (struct btrfs_key_ptr *)ptr); } static inline void btrfs_set_node_ptr_generation(struct extent_buffer *eb, int nr, u64 val) { unsigned long ptr; ptr = offsetof(struct btrfs_node, ptrs) + sizeof(struct btrfs_key_ptr) * nr; btrfs_set_key_generation(eb, (struct btrfs_key_ptr *)ptr, val); } static inline unsigned long btrfs_node_key_ptr_offset(int nr) { return offsetof(struct btrfs_node, ptrs) + Loading fs/btrfs/extent-tree.c +58 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ */ #include <linux/sched.h> #include "hash.h" #include "ctree.h" #include "disk-io.h" #include "print-tree.h" Loading Loading @@ -352,9 +353,63 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, return found_group; } static u64 hash_extent_ref(u64 root_objectid, u64 root_generation, u64 owner, u64 owner_offset) { u32 high_crc = ~(u32)0; u32 low_crc = ~(u32)0; __le64 lenum; lenum = cpu_to_le64(root_objectid); high_crc = crc32c(high_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(root_generation); high_crc = crc32c(high_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(owner); low_crc = crc32c(low_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(owner_offset); low_crc = crc32c(low_crc, &lenum, sizeof(lenum)); return ((u64)high_crc << 32) | (u64)low_crc; } int insert_extent_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 bytenr, u64 root_objectid, u64 root_generation, u64 owner, u64 owner_offset) { u64 hash; struct btrfs_key key; struct btrfs_extent_ref ref; struct extent_buffer *l; struct btrfs_extent_item *item; int ret; btrfs_set_stack_ref_root(&ref, root_objectid); btrfs_set_stack_ref_generation(&ref, root_generation); btrfs_set_stack_ref_objectid(&ref, owner); btrfs_set_stack_ref_offset(&ref, owner_offset); ret = btrfs_name_hash(&ref, sizeof(ref), &hash); key.offset = hash; key.objectid = bytenr; key.type = BTRFS_EXTENT_REF_KEY; ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(ref)); while (ret == -EEXIST) { } } 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 root_generation, u64 owner, u64 owner_offset) { struct btrfs_path *path; int ret; Loading Loading @@ -386,9 +441,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(path->nodes[0]); 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); btrfs_free_path(path); return 0; } Loading Loading
fs/btrfs/ctree.c +16 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, } else { btrfs_set_node_blockptr(parent, parent_slot, cow->start); WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); btrfs_mark_buffer_dirty(parent); WARN_ON(btrfs_header_generation(parent) != trans->transid); btrfs_free_extent(trans, root, buf->start, buf->len, 1); Loading Loading @@ -967,6 +970,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root { struct extent_buffer *b; u64 bytenr; u64 ptr_gen; int slot; int ret; int level; Loading Loading @@ -1031,10 +1035,18 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if (level == lowest_level) break; bytenr = btrfs_node_blockptr(b, slot); ptr_gen = btrfs_node_ptr_generation(b, slot); if (should_reada) reada_for_search(root, p, level, slot); b = read_tree_block(root, bytenr, btrfs_level_size(root, level - 1)); if (ptr_gen != btrfs_header_generation(b)) { printk("block %llu bad gen wanted %llu " "found %llu\n", (unsigned long long)b->start, (unsigned long long)ptr_gen, (unsigned long long)btrfs_header_generation(b)); } } else { p->slots[level] = slot; if (ins_len > 0 && btrfs_leaf_free_space(root, b) < Loading Loading @@ -1218,6 +1230,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans, btrfs_node_key(lower, &lower_key, 0); btrfs_set_node_key(c, &lower_key, 0); btrfs_set_node_blockptr(c, 0, lower->start); WARN_ON(btrfs_header_generation(lower) == 0); btrfs_set_node_ptr_generation(c, 0, btrfs_header_generation(lower)); btrfs_mark_buffer_dirty(c); Loading Loading @@ -1261,6 +1275,8 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root } btrfs_set_node_key(lower, key, slot); btrfs_set_node_blockptr(lower, slot, bytenr); WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(lower, nritems + 1); btrfs_mark_buffer_dirty(lower); return 0; Loading
fs/btrfs/ctree.h +41 −6 Original line number Diff line number Diff line Loading @@ -110,7 +110,7 @@ struct btrfs_header { #define BTRFS_MAX_LEVEL 8 #define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \ sizeof(struct btrfs_header)) / \ (sizeof(struct btrfs_disk_key) + sizeof(u64))) sizeof(struct btrfs_key_ptr)) #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) #define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize)) #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ Loading Loading @@ -168,6 +168,7 @@ struct btrfs_leaf { struct btrfs_key_ptr { struct btrfs_disk_key key; __le64 blockptr; __le64 generation; } __attribute__ ((__packed__)); struct btrfs_node { Loading Loading @@ -196,7 +197,13 @@ struct btrfs_path { */ struct btrfs_extent_item { __le32 refs; __le64 owner; } __attribute__ ((__packed__)); struct btrfs_extent_ref { __le64 root; __le64 generation; __le64 objectid; __le64 offset; } __attribute__ ((__packed__)); struct btrfs_inode_timespec { Loading Loading @@ -402,12 +409,13 @@ struct btrfs_root { * are used, and how many references there are to each block */ #define BTRFS_EXTENT_ITEM_KEY 33 #define BTRFS_EXTENT_REF_KEY 34 /* * block groups give us hints into the extent allocation trees. Which * blocks are free etc etc */ #define BTRFS_BLOCK_GROUP_ITEM_KEY 34 #define BTRFS_BLOCK_GROUP_ITEM_KEY 50 /* * string items are for debugging. They just store a short string of Loading Loading @@ -529,15 +537,25 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32); /* struct btrfs_extent_item */ BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); BTRFS_SETGET_FUNCS(extent_owner, struct btrfs_extent_item, owner, 64); /* struct btrfs_extent_ref */ BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64); 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, 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_extent_refs, struct btrfs_extent_item, refs, 32); BTRFS_SETGET_STACK_FUNCS(stack_extent_owner, struct btrfs_extent_item, owner, 64); /* struct btrfs_node */ BTRFS_SETGET_FUNCS(key_blockptr, struct btrfs_key_ptr, blockptr, 64); BTRFS_SETGET_FUNCS(key_generation, struct btrfs_key_ptr, generation, 64); static inline u64 btrfs_node_blockptr(struct extent_buffer *eb, int nr) { Loading @@ -556,6 +574,23 @@ static inline void btrfs_set_node_blockptr(struct extent_buffer *eb, btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); } static inline u64 btrfs_node_ptr_generation(struct extent_buffer *eb, int nr) { unsigned long ptr; ptr = offsetof(struct btrfs_node, ptrs) + sizeof(struct btrfs_key_ptr) * nr; return btrfs_key_generation(eb, (struct btrfs_key_ptr *)ptr); } static inline void btrfs_set_node_ptr_generation(struct extent_buffer *eb, int nr, u64 val) { unsigned long ptr; ptr = offsetof(struct btrfs_node, ptrs) + sizeof(struct btrfs_key_ptr) * nr; btrfs_set_key_generation(eb, (struct btrfs_key_ptr *)ptr, val); } static inline unsigned long btrfs_node_key_ptr_offset(int nr) { return offsetof(struct btrfs_node, ptrs) + Loading
fs/btrfs/extent-tree.c +58 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ */ #include <linux/sched.h> #include "hash.h" #include "ctree.h" #include "disk-io.h" #include "print-tree.h" Loading Loading @@ -352,9 +353,63 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, return found_group; } static u64 hash_extent_ref(u64 root_objectid, u64 root_generation, u64 owner, u64 owner_offset) { u32 high_crc = ~(u32)0; u32 low_crc = ~(u32)0; __le64 lenum; lenum = cpu_to_le64(root_objectid); high_crc = crc32c(high_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(root_generation); high_crc = crc32c(high_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(owner); low_crc = crc32c(low_crc, &lenum, sizeof(lenum)); lenum = cpu_to_le64(owner_offset); low_crc = crc32c(low_crc, &lenum, sizeof(lenum)); return ((u64)high_crc << 32) | (u64)low_crc; } int insert_extent_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 bytenr, u64 root_objectid, u64 root_generation, u64 owner, u64 owner_offset) { u64 hash; struct btrfs_key key; struct btrfs_extent_ref ref; struct extent_buffer *l; struct btrfs_extent_item *item; int ret; btrfs_set_stack_ref_root(&ref, root_objectid); btrfs_set_stack_ref_generation(&ref, root_generation); btrfs_set_stack_ref_objectid(&ref, owner); btrfs_set_stack_ref_offset(&ref, owner_offset); ret = btrfs_name_hash(&ref, sizeof(ref), &hash); key.offset = hash; key.objectid = bytenr; key.type = BTRFS_EXTENT_REF_KEY; ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(ref)); while (ret == -EEXIST) { } } 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 root_generation, u64 owner, u64 owner_offset) { struct btrfs_path *path; int ret; Loading Loading @@ -386,9 +441,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(path->nodes[0]); 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); btrfs_free_path(path); return 0; } Loading