summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--convert.c4
-rw-r--r--ctree.h16
-rw-r--r--mkfs.c4
-rw-r--r--print-tree.c4
-rw-r--r--utils.c33
5 files changed, 51 insertions, 10 deletions
diff --git a/convert.c b/convert.c
index 5a3c1413..388c6c44 100644
--- a/convert.c
+++ b/convert.c
@@ -2172,7 +2172,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
{
int i, fd, ret;
u32 blocksize;
- u64 blocks[6];
+ u64 blocks[7];
u64 total_bytes;
u64 super_bytenr;
ext2_filsys ext2_fs;
@@ -2195,7 +2195,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
fprintf(stderr, "filetype feature is missing\n");
goto fail;
}
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 7; i++) {
ret = ext2_alloc_block(ext2_fs, 0, blocks + i);
if (ret) {
fprintf(stderr, "not enough free space\n");
diff --git a/ctree.h b/ctree.h
index df2d722a..c640a69a 100644
--- a/ctree.h
+++ b/ctree.h
@@ -54,6 +54,9 @@ struct btrfs_trans_handle;
/* directory objectid inside the root tree */
#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
+/* holds checksums of all the data extents */
+#define BTRFS_CSUM_TREE_OBJECTID 7ULL
+
/* oprhan objectid for tracking unlinked/truncated files */
#define BTRFS_ORPHAN_OBJECTID -5ULL
@@ -66,6 +69,13 @@ struct btrfs_trans_handle;
#define BTRFS_TREE_RELOC_OBJECTID -8ULL
#define BTRFS_DATA_RELOC_TREE_OBJECTID -9ULL
+/*
+ * extent checksums all have this objectid
+ * this allows them to share the logging tree
+ * for fsyncs
+ */
+#define BTRFS_EXTENT_CSUM_OBJECTID -10ULL
+
/* dummy objectid represents multiple objectids */
#define BTRFS_MULTIPLE_OBJECTIDS -255ULL
@@ -583,6 +593,7 @@ struct btrfs_fs_info {
struct btrfs_root *tree_root;
struct btrfs_root *chunk_root;
struct btrfs_root *dev_root;
+ struct btrfs_root *csum_root;
/* the log root tree is a directory of all the other log roots */
struct btrfs_root *log_root_tree;
@@ -688,6 +699,11 @@ struct btrfs_root {
* csum items have the checksums for data in the extents
*/
#define BTRFS_CSUM_ITEM_KEY 120
+/*
+ * extent csums are stored in a separate tree and hold csums for
+ * an entire extent on disk.
+ */
+#define BTRFS_EXTENT_CSUM_KEY 128
/*
* root items point to tree roots. There are typically in the root
diff --git a/mkfs.c b/mkfs.c
index dae43e97..cc0eec02 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -328,7 +328,7 @@ int main(int ac, char **av)
char *first_file;
u64 block_count = 0;
u64 dev_block_count = 0;
- u64 blocks[6];
+ u64 blocks[7];
u64 alloc_start = 0;
u64 metadata_profile = BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_DUP;
u64 data_profile = BTRFS_BLOCK_GROUP_RAID0;
@@ -414,7 +414,7 @@ int main(int ac, char **av)
if (block_count == 0)
block_count = dev_block_count;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < 7; i++)
blocks[i] = BTRFS_SUPER_INFO_OFFSET + leafsize * i;
ret = make_btrfs(fd, file, label, blocks, block_count,
diff --git a/print-tree.c b/print-tree.c
index 114564ad..b69447d0 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -279,6 +279,10 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
ci = btrfs_item_ptr(l, i, struct btrfs_csum_item);
printf("\t\tcsum item\n");
break;
+ case BTRFS_EXTENT_CSUM_KEY:
+ ci = btrfs_item_ptr(l, i, struct btrfs_csum_item);
+ printf("\t\textent csum item\n");
+ break;
case BTRFS_EXTENT_DATA_KEY:
fi = btrfs_item_ptr(l, i,
struct btrfs_file_extent_item);
diff --git a/utils.c b/utils.c
index c2bb9867..76636893 100644
--- a/utils.c
+++ b/utils.c
@@ -46,16 +46,17 @@
static inline int ioctl(int fd, int define, u64 *size) { return 0; }
#endif
-static u64 reference_root_table[6] = {
+static u64 reference_root_table[] = {
[1] = BTRFS_ROOT_TREE_OBJECTID,
[2] = BTRFS_EXTENT_TREE_OBJECTID,
[3] = BTRFS_CHUNK_TREE_OBJECTID,
[4] = BTRFS_DEV_TREE_OBJECTID,
[5] = BTRFS_FS_TREE_OBJECTID,
+ [6] = BTRFS_CSUM_TREE_OBJECTID,
};
int make_btrfs(int fd, const char *device, const char *label,
- u64 blocks[6], u64 num_bytes, u32 nodesize,
+ u64 blocks[7], u64 num_bytes, u32 nodesize,
u32 leafsize, u32 sectorsize, u32 stripesize)
{
struct btrfs_super_block super;
@@ -96,7 +97,7 @@ int make_btrfs(int fd, const char *device, const char *label,
btrfs_set_super_root(&super, blocks[1]);
btrfs_set_super_chunk_root(&super, blocks[3]);
btrfs_set_super_total_bytes(&super, num_bytes);
- btrfs_set_super_bytes_used(&super, 5 * leafsize);
+ btrfs_set_super_bytes_used(&super, 6 * leafsize);
btrfs_set_super_sectorsize(&super, sectorsize);
btrfs_set_super_leafsize(&super, leafsize);
btrfs_set_super_nodesize(&super, nodesize);
@@ -112,7 +113,7 @@ int make_btrfs(int fd, const char *device, const char *label,
memset(buf->data, 0, leafsize);
buf->len = leafsize;
btrfs_set_header_bytenr(buf, blocks[1]);
- btrfs_set_header_nritems(buf, 3);
+ btrfs_set_header_nritems(buf, 4);
btrfs_set_header_generation(buf, 1);
btrfs_set_header_owner(buf, BTRFS_ROOT_TREE_OBJECTID);
write_extent_buffer(buf, super.fsid, (unsigned long)
@@ -174,6 +175,18 @@ int make_btrfs(int fd, const char *device, const char *label,
sizeof(root_item));
nritems++;
+ itemoff = itemoff - sizeof(root_item);
+ btrfs_set_root_bytenr(&root_item, blocks[6]);
+ btrfs_set_disk_key_objectid(&disk_key, BTRFS_CSUM_TREE_OBJECTID);
+ btrfs_set_item_key(buf, &disk_key, nritems);
+ btrfs_set_item_offset(buf, btrfs_item_nr(buf, nritems), itemoff);
+ btrfs_set_item_size(buf, btrfs_item_nr(buf, nritems),
+ sizeof(root_item));
+ write_extent_buffer(buf, &root_item,
+ btrfs_item_ptr_offset(buf, nritems),
+ sizeof(root_item));
+ nritems++;
+
csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
ret = pwrite(fd, buf->data, leafsize, blocks[1]);
@@ -193,7 +206,7 @@ int make_btrfs(int fd, const char *device, const char *label,
extent_item = btrfs_item_ptr(buf, nritems, struct btrfs_extent_item);
btrfs_set_extent_refs(buf, extent_item, 1);
nritems++;
- for (i = 1; i < 6; i++) {
+ for (i = 1; i < 7; i++) {
BUG_ON(blocks[i] < first_free);
BUG_ON(blocks[i] < blocks[i - 1]);
@@ -352,7 +365,7 @@ int make_btrfs(int fd, const char *device, const char *label,
csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
ret = pwrite(fd, buf->data, leafsize, blocks[4]);
- /* finally create the FS root */
+ /* create the FS root */
btrfs_set_header_bytenr(buf, blocks[5]);
btrfs_set_header_owner(buf, BTRFS_FS_TREE_OBJECTID);
btrfs_set_header_nritems(buf, 0);
@@ -360,6 +373,14 @@ int make_btrfs(int fd, const char *device, const char *label,
ret = pwrite(fd, buf->data, leafsize, blocks[5]);
BUG_ON(ret != leafsize);
+ /* finally create the csum root */
+ btrfs_set_header_bytenr(buf, blocks[6]);
+ btrfs_set_header_owner(buf, BTRFS_CSUM_TREE_OBJECTID);
+ btrfs_set_header_nritems(buf, 0);
+ csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
+ ret = pwrite(fd, buf->data, leafsize, blocks[6]);
+ BUG_ON(ret != leafsize);
+
/* and write out the super block */
BUG_ON(sizeof(super) > sectorsize);
memset(buf->data, 0, sectorsize);