From 73372dcf8f21427363a398b29171440b42077ce7 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Sun, 9 Dec 2007 13:46:24 -0500 Subject: [PATCH] Add generation numbers to block pointers --- ctree.c | 8 +++++++- ctree.h | 15 +++++++++++++-- extent-tree.c | 3 +-- mkfs.c | 2 +- print-tree.c | 5 +++-- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ctree.c b/ctree.c index 88261838..71796067 100644 --- a/ctree.c +++ b/ctree.c @@ -23,6 +23,7 @@ #include "disk-io.h" #include "transaction.h" #include "print-tree.h" + static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level); static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root @@ -80,6 +81,8 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root } else { btrfs_set_node_blockptr(&parent->node, parent_slot, cow->bytenr); + btrfs_set_node_ptr_generation(&parent->node, parent_slot, + trans->transid); BUG_ON(list_empty(&parent->dirty)); btrfs_free_extent(trans, root, buf->bytenr, buf->size, 1); } @@ -849,6 +852,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key)); btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->bytenr); BUG_ON(list_empty(&t->dirty)); + btrfs_set_node_ptr_generation(c, 0, + btrfs_header_generation(&path->nodes[level - 1]->node.header)); /* the super has an extra ref to root->node */ btrfs_block_release(root, root->node); root->node = t; @@ -887,6 +892,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root } memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key)); btrfs_set_node_blockptr(lower, slot, bytenr); + btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(&lower->header, nritems + 1); BUG_ON(list_empty(&path->nodes[level]->dirty)); return 0; @@ -1287,9 +1293,9 @@ again: right = &right_buffer->leaf; memset(&right->header, 0, sizeof(right->header)); btrfs_set_header_bytenr(&right->header, right_buffer->bytenr); - btrfs_set_header_generation(&right->header, trans->transid); btrfs_set_header_level(&right->header, 0); btrfs_set_header_owner(&right->header, root->root_key.objectid); + btrfs_set_header_generation(&right->header, trans->transid); memcpy(right->header.fsid, root->fs_info->disk_super->fsid, sizeof(right->header.fsid)); if (mid <= slot) { diff --git a/ctree.h b/ctree.h index 57d04ae8..d1df4f2a 100644 --- a/ctree.h +++ b/ctree.h @@ -98,7 +98,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) - \ @@ -156,6 +156,7 @@ struct btrfs_leaf { struct btrfs_key_ptr { struct btrfs_disk_key key; __le64 blockptr; + __le64 generation; } __attribute__ ((__packed__)); struct btrfs_node { @@ -562,13 +563,23 @@ static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr) return le64_to_cpu(n->ptrs[nr].blockptr); } - static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr, u64 val) { n->ptrs[nr].blockptr = cpu_to_le64(val); } +static inline u64 btrfs_node_ptr_generation(struct btrfs_node *n, int nr) +{ + return le64_to_cpu(n->ptrs[nr].generation); +} + +static inline void btrfs_set_node_ptr_generation(struct btrfs_node *n, int nr, + u64 val) +{ + n->ptrs[nr].generation = cpu_to_le64(val); +} + static inline u32 btrfs_item_offset(struct btrfs_item *item) { return le32_to_cpu(item->offset); diff --git a/extent-tree.c b/extent-tree.c index 621f3f6c..ac8ae752 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -572,8 +572,7 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, return NULL; } buf = find_tree_block(root, ins.objectid, blocksize); - btrfs_set_header_generation(&buf->node.header, - root->root_key.offset + 1); + btrfs_set_header_generation(&buf->node.header, trans->transid); btrfs_set_header_bytenr(&buf->node.header, buf->bytenr); memcpy(buf->node.header.fsid, root->fs_info->disk_super->fsid, sizeof(buf->node.header.fsid)); diff --git a/mkfs.c b/mkfs.c index 044117a8..2b1b5003 100644 --- a/mkfs.c +++ b/mkfs.c @@ -224,7 +224,7 @@ printf("blocksize is %d\n", leafsize); memset(empty_leaf, 0, leafsize); btrfs_set_header_bytenr(&empty_leaf->header, first_free); btrfs_set_header_nritems(&empty_leaf->header, 2); - btrfs_set_header_generation(&empty_leaf->header, 0); + btrfs_set_header_generation(&empty_leaf->header, 1); btrfs_set_header_owner(&empty_leaf->header, BTRFS_ROOT_TREE_OBJECTID); memcpy(empty_leaf->header.fsid, super.fsid, sizeof(empty_leaf->header.fsid)); diff --git a/print-tree.c b/print-tree.c index dd442c53..8a30919f 100644 --- a/print-tree.c +++ b/print-tree.c @@ -179,13 +179,14 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t) size = btrfs_level_size(root, btrfs_header_level(&c->header) - 1); for (i = 0; i < nr; i++) { u64 blocknr = btrfs_node_blockptr(c, i); - printf("\tkey %d (%llu %x %llu) block %llu (%llu)\n", + printf("\tkey %d (%llu %x %llu) block %llu (%llu) gen %llu\n", i, (unsigned long long)c->ptrs[i].key.objectid, c->ptrs[i].key.type, (unsigned long long)c->ptrs[i].key.offset, (unsigned long long)blocknr, - (unsigned long long)blocknr / size); + (unsigned long long)blocknr / size, + (unsigned long long)btrfs_node_ptr_generation(c, i)); fflush(stdout); } for (i = 0; i < nr; i++) { -- 2.11.4.GIT