summaryrefslogtreecommitdiff
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-12-11 09:25:06 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:58 -0400
commit74493f7a59bfd4d1c7029c74ab2cd0e400612c6b (patch)
treeb5fc75b08d2edcf8218c814ea02ab6c548e73652 /fs/btrfs/extent-tree.c
parent17636e03f42a1a42fed3834859de4702bd655fd1 (diff)
downloadlwn-74493f7a59bfd4d1c7029c74ab2cd0e400612c6b.tar.gz
lwn-74493f7a59bfd4d1c7029c74ab2cd0e400612c6b.zip
Btrfs: Implement generation numbers in block pointers
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 8ab4954f6ad0..0f1ebdd4e925 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include "hash.h"
#include "ctree.h"
#include "disk-io.h"
#include "print-tree.h"
@@ -352,9 +353,63 @@ found:
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;
@@ -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;
}