summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--btrfsck.c6
-rw-r--r--ctree.c97
-rw-r--r--ctree.h122
-rw-r--r--debug-tree.c11
-rw-r--r--disk-io.c114
-rw-r--r--disk-io.h10
-rw-r--r--extent-tree.c172
-rw-r--r--mkfs.c179
-rw-r--r--print-tree.c28
10 files changed, 423 insertions, 319 deletions
diff --git a/Makefile b/Makefile
index 25c94939..aca10613 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,8 @@ INSTALL= install
prefix ?= /usr/local
bindir = $(prefix)/bin
-progs = btrfsctl btrfsck mkfs.btrfs debug-tree
+#progs = btrfsctl btrfsck mkfs.btrfs debug-tree
+progs = btrfsctl mkfs.btrfs debug-tree
# make C=1 to enable sparse
ifdef C
diff --git a/btrfsck.c b/btrfsck.c
index 83c8252c..c5d9dd37 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -78,12 +78,12 @@ static int check_leaf(struct btrfs_root *root,
if (btrfs_header_level(&leaf->header) != 0) {
fprintf(stderr, "leaf is not a leaf %llu\n",
- (unsigned long long)btrfs_header_blocknr(&leaf->header));
+ (unsigned long long)btrfs_header_bytenr(&leaf->header));
return 1;
}
if (btrfs_leaf_free_space(root, leaf) < 0) {
fprintf(stderr, "leaf free space incorrect %llu %d\n",
- (unsigned long long)btrfs_header_blocknr(&leaf->header),
+ (unsigned long long)btrfs_header_bytenr(&leaf->header),
btrfs_leaf_free_space(root, leaf));
return 1;
}
@@ -94,7 +94,7 @@ static int check_leaf(struct btrfs_root *root,
if (parent_key->type && memcmp(parent_key, &leaf->items[0].key,
sizeof(struct btrfs_disk_key))) {
fprintf(stderr, "leaf parent key incorrect %llu\n",
- (unsigned long long)btrfs_header_blocknr(&leaf->header));
+ (unsigned long long)btrfs_header_bytenr(&leaf->header));
return 1;
}
for (i = 0; nritems > 1 && i < nritems - 2; i++) {
diff --git a/ctree.c b/ctree.c
index 0235f98f..1da711ab 100644
--- a/ctree.c
+++ b/ctree.c
@@ -64,9 +64,9 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
*cow_ret = buf;
return 0;
}
- cow = btrfs_alloc_free_block(trans, root);
- memcpy(&cow->node, &buf->node, root->sectorsize);
- btrfs_set_header_blocknr(&cow->node.header, cow->blocknr);
+ cow = btrfs_alloc_free_block(trans, root, buf->size);
+ memcpy(&cow->node, &buf->node, buf->size);
+ btrfs_set_header_bytenr(&cow->node.header, cow->bytenr);
btrfs_set_header_owner(&cow->node.header, root->root_key.objectid);
*cow_ret = cow;
btrfs_inc_ref(trans, root, buf);
@@ -74,13 +74,14 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
root->node = cow;
cow->count++;
if (buf != root->commit_root)
- btrfs_free_extent(trans, root, buf->blocknr, 1, 1);
+ btrfs_free_extent(trans, root, buf->bytenr,
+ buf->size, 1);
btrfs_block_release(root, buf);
} else {
btrfs_set_node_blockptr(&parent->node, parent_slot,
- cow->blocknr);
+ cow->bytenr);
BUG_ON(list_empty(&parent->dirty));
- btrfs_free_extent(trans, root, buf->blocknr, 1, 1);
+ btrfs_free_extent(trans, root, buf->bytenr, buf->size, 1);
}
btrfs_block_release(root, buf);
return 0;
@@ -178,7 +179,7 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path,
BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
sizeof(struct btrfs_disk_key)));
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
- btrfs_header_blocknr(&node->header));
+ btrfs_header_bytenr(&node->header));
}
BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
for (i = 0; nritems > 1 && i < nritems - 2; i++) {
@@ -212,7 +213,7 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
BUG_ON(memcmp(parent_key, &leaf->items[0].key,
sizeof(struct btrfs_disk_key)));
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
- btrfs_header_blocknr(&leaf->header));
+ btrfs_header_bytenr(&leaf->header));
}
for (i = 0; nritems > 1 && i < nritems - 2; i++) {
struct btrfs_key cpukey;
@@ -300,11 +301,13 @@ static struct btrfs_buffer *read_node_slot(struct btrfs_root *root,
int slot)
{
struct btrfs_node *node = &parent_buf->node;
+ int level = btrfs_header_level(&node->header);
if (slot < 0)
return NULL;
if (slot >= btrfs_header_nritems(&node->header))
return NULL;
- return read_tree_block(root, btrfs_node_blockptr(node, slot));
+ return read_tree_block(root, btrfs_node_blockptr(node, slot),
+ btrfs_level_size(root, level - 1));
}
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
@@ -341,7 +344,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
*/
if (!parent_buf) {
struct btrfs_buffer *child;
- u64 blocknr = mid_buf->blocknr;
+ u64 bytenr = mid_buf->bytenr;
if (btrfs_header_nritems(&mid->header) != 1)
return 0;
@@ -356,7 +359,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
/* once for the root ptr */
btrfs_block_release(root, mid_buf);
clean_tree_block(trans, root, mid_buf);
- return btrfs_free_extent(trans, root, blocknr, 1, 1);
+ return btrfs_free_extent(trans, root, bytenr,
+ root->nodesize, 1);
}
parent = &parent_buf->node;
@@ -389,7 +393,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
if (wret < 0)
ret = wret;
if (btrfs_header_nritems(&right->header) == 0) {
- u64 blocknr = right_buf->blocknr;
+ u64 bytenr = right_buf->bytenr;
btrfs_block_release(root, right_buf);
clean_tree_block(trans, root, right_buf);
right_buf = NULL;
@@ -398,7 +402,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
1);
if (wret)
ret = wret;
- wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
+ wret = btrfs_free_extent(trans, root, bytenr,
+ root->nodesize, 1);
if (wret)
ret = wret;
} else {
@@ -426,7 +431,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
}
if (btrfs_header_nritems(&mid->header) == 0) {
/* we've managed to empty the middle node, drop it */
- u64 blocknr = mid_buf->blocknr;
+ u64 bytenr = mid_buf->bytenr;
btrfs_block_release(root, mid_buf);
clean_tree_block(trans, root, mid_buf);
mid_buf = NULL;
@@ -434,7 +439,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
wret = del_ptr(trans, root, path, level + 1, pslot);
if (wret)
ret = wret;
- wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
+ wret = btrfs_free_extent(trans, root, bytenr,
+ root->nodesize, 1);
if (wret)
ret = wret;
} else {
@@ -539,7 +545,9 @@ again:
slot = p->slots[level];
BUG_ON(btrfs_header_nritems(&c->header) == 1);
}
- b = read_tree_block(root, btrfs_node_blockptr(c, slot));
+ b = read_tree_block(root,
+ btrfs_node_blockptr(c, slot),
+ btrfs_level_size(root, level - 1));
} else {
struct btrfs_leaf *l = (struct btrfs_leaf *)c;
p->slots[level] = slot;
@@ -696,22 +704,24 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON(path->nodes[level]);
BUG_ON(path->nodes[level-1] != root->node);
- t = btrfs_alloc_free_block(trans, root);
+ t = btrfs_alloc_free_block(trans, root, root->nodesize);
c = &t->node;
- memset(c, 0, root->sectorsize);
+ memset(c, 0, root->nodesize);
btrfs_set_header_nritems(&c->header, 1);
btrfs_set_header_level(&c->header, level);
- btrfs_set_header_blocknr(&c->header, t->blocknr);
+ btrfs_set_header_bytenr(&c->header, t->bytenr);
btrfs_set_header_owner(&c->header, root->root_key.objectid);
memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
sizeof(c->header.fsid));
lower = &path->nodes[level-1]->node;
+
if (btrfs_is_leaf(lower))
lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
else
lower_key = &lower->ptrs[0].key;
+
memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key));
- btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->blocknr);
+ btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->bytenr);
/* the super has an extra ref to root->node */
btrfs_block_release(root, root->node);
root->node = t;
@@ -726,13 +736,13 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
* the node should have enough room for the pointer already
*
* slot and level indicate where you want the key to go, and
- * blocknr is the block the key points to.
+ * bytenr is the block the key points to.
*
* returns zero on success and < 0 on any error
*/
static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_path *path, struct btrfs_disk_key
- *key, u64 blocknr, int slot, int level)
+ *key, u64 bytenr, int slot, int level)
{
struct btrfs_node *lower;
int nritems;
@@ -749,7 +759,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
(nritems - slot) * sizeof(struct btrfs_key_ptr));
}
memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key));
- btrfs_set_node_blockptr(lower, slot, blocknr);
+ btrfs_set_node_blockptr(lower, slot, bytenr);
btrfs_set_header_nritems(&lower->header, nritems + 1);
BUG_ON(list_empty(&path->nodes[level]->dirty));
return 0;
@@ -785,11 +795,11 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
return ret;
}
c_nritems = btrfs_header_nritems(&c->header);
- split_buffer = btrfs_alloc_free_block(trans, root);
+ split_buffer = btrfs_alloc_free_block(trans, root, root->nodesize);
split = &split_buffer->node;
btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
- btrfs_set_header_blocknr(&split->header, split_buffer->blocknr);
+ btrfs_set_header_bytenr(&split->header, split_buffer->bytenr);
btrfs_set_header_owner(&split->header, root->root_key.objectid);
memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
sizeof(split->header.fsid));
@@ -802,7 +812,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON(list_empty(&t->dirty));
wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
- split_buffer->blocknr, path->slots[level + 1] + 1,
+ split_buffer->bytenr, path->slots[level + 1] + 1,
level + 1);
if (wret)
ret = wret;
@@ -850,8 +860,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
if (slot >= btrfs_header_nritems(&upper->node.header) - 1) {
return 1;
}
- right_buf = read_tree_block(root, btrfs_node_blockptr(&upper->node,
- slot + 1));
+ right_buf = read_tree_block(root,
+ btrfs_node_blockptr(&upper->node, slot + 1),
+ root->leafsize);
right = &right_buf->leaf;
free_space = btrfs_leaf_free_space(root, right);
if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -956,8 +967,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
if (!path->nodes[1]) {
return 1;
}
- t = read_tree_block(root, btrfs_node_blockptr(&path->nodes[1]->node,
- slot - 1));
+ t = read_tree_block(root,
+ btrfs_node_blockptr(&path->nodes[1]->node, slot - 1),
+ root->leafsize);
left = &t->leaf;
free_space = btrfs_leaf_free_space(root, left);
if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -1098,7 +1110,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
slot = path->slots[0];
nritems = btrfs_header_nritems(&l->header);
mid = (nritems + 1)/ 2;
- right_buffer = btrfs_alloc_free_block(trans, root);
+ right_buffer = btrfs_alloc_free_block(trans, root, root->leafsize);
BUG_ON(!right_buffer);
BUG_ON(mid == nritems);
right = &right_buffer->leaf;
@@ -1115,7 +1127,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
BUG();
}
btrfs_set_header_nritems(&right->header, nritems - mid);
- btrfs_set_header_blocknr(&right->header, right_buffer->blocknr);
+ btrfs_set_header_bytenr(&right->header, right_buffer->bytenr);
btrfs_set_header_level(&right->header, 0);
btrfs_set_header_owner(&right->header, root->root_key.objectid);
memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
@@ -1138,7 +1150,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_header_nritems(&l->header, mid);
ret = 0;
wret = insert_ptr(trans, root, path, &right->items[0].key,
- right_buffer->blocknr, path->slots[1] + 1, 1);
+ right_buffer->bytenr, path->slots[1] + 1, 1);
if (wret)
ret = wret;
BUG_ON(list_empty(&right_buffer->dirty));
@@ -1350,7 +1362,8 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if (wret)
ret = wret;
wret = btrfs_free_extent(trans, root,
- leaf_buf->blocknr, 1, 1);
+ leaf_buf->bytenr,
+ leaf_buf->size, 1);
if (wret)
ret = wret;
}
@@ -1382,14 +1395,14 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
ret = wret;
}
if (btrfs_header_nritems(&leaf->header) == 0) {
- u64 blocknr = leaf_buf->blocknr;
+ u64 bytenr = leaf_buf->bytenr;
clean_tree_block(trans, root, leaf_buf);
wret = del_ptr(trans, root, path, 1, slot);
if (wret)
ret = wret;
+ wret = btrfs_free_extent(trans, root, bytenr,
+ leaf_buf->size, 1);
btrfs_block_release(root, leaf_buf);
- wret = btrfs_free_extent(trans, root, blocknr,
- 1, 1);
if (wret)
ret = wret;
} else {
@@ -1461,7 +1474,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
int slot;
int level = 1;
- u64 blocknr;
+ u64 bytenr;
struct btrfs_buffer *c;
struct btrfs_buffer *next = NULL;
@@ -1474,10 +1487,11 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
level++;
continue;
}
- blocknr = btrfs_node_blockptr(&c->node, slot);
+ bytenr = btrfs_node_blockptr(&c->node, slot);
if (next)
btrfs_block_release(root, next);
- next = read_tree_block(root, blocknr);
+ next = read_tree_block(root, bytenr,
+ btrfs_level_size(root, level - 1));
break;
}
path->slots[level] = slot;
@@ -1490,7 +1504,8 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
if (!level)
break;
next = read_tree_block(root,
- btrfs_node_blockptr(&next->node, 0));
+ btrfs_node_blockptr(&next->node, 0),
+ btrfs_level_size(root, level - 1));
}
return 0;
}
diff --git a/ctree.h b/ctree.h
index b37de525..ab2238b6 100644
--- a/ctree.h
+++ b/ctree.h
@@ -86,7 +86,7 @@ struct btrfs_key {
struct btrfs_header {
u8 csum[BTRFS_CSUM_SIZE];
u8 fsid[16]; /* FS specific uuid */
- __le64 blocknr; /* which block this node is supposed to live in */
+ __le64 bytenr; /* which block this node is supposed to live in */
__le64 generation;
__le64 owner;
__le32 nritems;
@@ -110,16 +110,17 @@ struct btrfs_super_block {
u8 csum[BTRFS_CSUM_SIZE];
/* the first 3 fields must match struct btrfs_header */
u8 fsid[16]; /* FS specific uuid */
- __le64 blocknr; /* this block number */
+ __le64 bytenr; /* this block number */
__le64 magic;
__le64 generation;
__le64 root;
- __le64 total_blocks;
- __le64 blocks_used;
+ __le64 total_bytes;
+ __le64 bytes_used;
__le64 root_dir_objectid;
__le32 sectorsize;
__le32 nodesize;
__le32 leafsize;
+ u8 root_level;
} __attribute__ ((__packed__));
/*
@@ -222,13 +223,14 @@ struct btrfs_dir_item {
struct btrfs_root_item {
struct btrfs_inode_item inode;
__le64 root_dirid;
- __le64 blocknr;
- __le64 block_limit;
- __le64 blocks_used;
+ __le64 bytenr;
+ __le64 byte_limit;
+ __le64 bytes_used;
__le32 flags;
__le32 refs;
struct btrfs_disk_key drop_progress;
u8 drop_level;
+ u8 level;
} __attribute__ ((__packed__));
#define BTRFS_FILE_EXTENT_REG 0
@@ -241,8 +243,8 @@ struct btrfs_file_extent_item {
* disk space consumed by the extent, checksum blocks are included
* in these numbers
*/
- __le64 disk_blocknr;
- __le64 disk_num_blocks;
+ __le64 disk_bytenr;
+ __le64 disk_num_bytes;
/*
* the logical offset in file blocks (no csums)
* this extent record is for. This allows a file extent to point
@@ -254,7 +256,7 @@ struct btrfs_file_extent_item {
/*
* the logical number of file blocks (no csums included)
*/
- __le64 num_blocks;
+ __le64 num_bytes;
} __attribute__ ((__packed__));
struct btrfs_csum_item {
@@ -670,14 +672,14 @@ static inline void btrfs_set_key_type(struct btrfs_key *key, u32 val)
key->type = val;
}
-static inline u64 btrfs_header_blocknr(struct btrfs_header *h)
+static inline u64 btrfs_header_bytenr(struct btrfs_header *h)
{
- return le64_to_cpu(h->blocknr);
+ return le64_to_cpu(h->bytenr);
}
-static inline void btrfs_set_header_blocknr(struct btrfs_header *h, u64 blocknr)
+static inline void btrfs_set_header_bytenr(struct btrfs_header *h, u64 bytenr)
{
- h->blocknr = cpu_to_le64(blocknr);
+ h->bytenr = cpu_to_le64(bytenr);
}
static inline u64 btrfs_header_generation(struct btrfs_header *h)
@@ -738,14 +740,14 @@ static inline int btrfs_is_leaf(struct btrfs_node *n)
return (btrfs_header_level(&n->header) == 0);
}
-static inline u64 btrfs_root_blocknr(struct btrfs_root_item *item)
+static inline u64 btrfs_root_bytenr(struct btrfs_root_item *item)
{
- return le64_to_cpu(item->blocknr);
+ return le64_to_cpu(item->bytenr);
}
-static inline void btrfs_set_root_blocknr(struct btrfs_root_item *item, u64 val)
+static inline void btrfs_set_root_bytenr(struct btrfs_root_item *item, u64 val)
{
- item->blocknr = cpu_to_le64(val);
+ item->bytenr = cpu_to_le64(val);
}
static inline u64 btrfs_root_dirid(struct btrfs_root_item *item)
@@ -778,25 +780,25 @@ static inline void btrfs_set_root_flags(struct btrfs_root_item *item, u32 val)
item->flags = cpu_to_le32(val);
}
-static inline void btrfs_set_root_blocks_used(struct btrfs_root_item *item,
+static inline void btrfs_set_root_bytes_used(struct btrfs_root_item *item,
u64 val)
{
- item->blocks_used = cpu_to_le64(val);
+ item->bytes_used = cpu_to_le64(val);
}
-static inline u64 btrfs_root_blocks_used(struct btrfs_root_item *item)
+static inline u64 btrfs_root_bytes_used(struct btrfs_root_item *item)
{
- return le64_to_cpu(item->blocks_used);
+ return le64_to_cpu(item->bytes_used);
}
-static inline u64 btrfs_super_blocknr(struct btrfs_super_block *s)
+static inline u64 btrfs_super_bytenr(struct btrfs_super_block *s)
{
- return le64_to_cpu(s->blocknr);
+ return le64_to_cpu(s->bytenr);
}
-static inline void btrfs_set_super_blocknr(struct btrfs_super_block *s, u64 val)
+static inline void btrfs_set_super_bytenr(struct btrfs_super_block *s, u64 val)
{
- s->blocknr = cpu_to_le64(val);
+ s->bytenr = cpu_to_le64(val);
}
static inline u64 btrfs_super_generation(struct btrfs_super_block *s)
@@ -810,6 +812,17 @@ static inline void btrfs_set_super_generation(struct btrfs_super_block *s,
s->generation = cpu_to_le64(val);
}
+static inline u8 btrfs_super_root_level(struct btrfs_super_block *s)
+{
+ return s->root_level;
+}
+
+static inline void btrfs_set_super_root_level(struct btrfs_super_block *s,
+ u8 val)
+{
+ s->root_level = val;
+}
+
static inline u64 btrfs_super_root(struct btrfs_super_block *s)
{
return le64_to_cpu(s->root);
@@ -820,26 +833,26 @@ static inline void btrfs_set_super_root(struct btrfs_super_block *s, u64 val)
s->root = cpu_to_le64(val);
}
-static inline u64 btrfs_super_total_blocks(struct btrfs_super_block *s)
+static inline u64 btrfs_super_total_bytes(struct btrfs_super_block *s)
{
- return le64_to_cpu(s->total_blocks);
+ return le64_to_cpu(s->total_bytes);
}
-static inline void btrfs_set_super_total_blocks(struct btrfs_super_block *s,
+static inline void btrfs_set_super_total_bytes(struct btrfs_super_block *s,
u64 val)
{
- s->total_blocks = cpu_to_le64(val);
+ s->total_bytes = cpu_to_le64(val);
}
-static inline u64 btrfs_super_blocks_used(struct btrfs_super_block *s)
+static inline u64 btrfs_super_bytes_used(struct btrfs_super_block *s)
{
- return le64_to_cpu(s->blocks_used);
+ return le64_to_cpu(s->bytes_used);
}
-static inline void btrfs_set_super_blocks_used(struct btrfs_super_block *s,
+static inline void btrfs_set_super_bytes_used(struct btrfs_super_block *s,
u64 val)
{
- s->blocks_used = cpu_to_le64(val);
+ s->bytes_used = cpu_to_le64(val);
}
static inline u32 btrfs_super_sectorsize(struct btrfs_super_block *s)
@@ -904,32 +917,32 @@ static inline void btrfs_set_file_extent_type(struct btrfs_file_extent_item *e,
static inline char *btrfs_file_extent_inline_start(struct
btrfs_file_extent_item *e)
{
- return (char *)(&e->disk_blocknr);
+ return (char *)(&e->disk_bytenr);
}
static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize)
{
return (unsigned long)(&((struct
- btrfs_file_extent_item *)NULL)->disk_blocknr) + datasize;
+ btrfs_file_extent_item *)NULL)->disk_bytenr) + datasize;
}
static inline u32 btrfs_file_extent_inline_len(struct btrfs_item *e)
{
struct btrfs_file_extent_item *fe = NULL;
- return btrfs_item_size(e) - (unsigned long)(&fe->disk_blocknr);
+ return btrfs_item_size(e) - (unsigned long)(&fe->disk_bytenr);
}
-static inline u64 btrfs_file_extent_disk_blocknr(struct btrfs_file_extent_item
+static inline u64 btrfs_file_extent_disk_bytenr(struct btrfs_file_extent_item
*e)
{
- return le64_to_cpu(e->disk_blocknr);
+ return le64_to_cpu(e->disk_bytenr);
}
-static inline void btrfs_set_file_extent_disk_blocknr(struct
+static inline void btrfs_set_file_extent_disk_bytenr(struct
btrfs_file_extent_item
*e, u64 val)
{
- e->disk_blocknr = cpu_to_le64(val);
+ e->disk_bytenr = cpu_to_le64(val);
}
static inline u64 btrfs_file_extent_generation(struct btrfs_file_extent_item *e)
@@ -944,17 +957,17 @@ static inline void btrfs_set_file_extent_generation(struct
e->generation = cpu_to_le64(val);
}
-static inline u64 btrfs_file_extent_disk_num_blocks(struct
+static inline u64 btrfs_file_extent_disk_num_bytes(struct
btrfs_file_extent_item *e)
{
- return le64_to_cpu(e->disk_num_blocks);
+ return le64_to_cpu(e->disk_num_bytes);
}
-static inline void btrfs_set_file_extent_disk_num_blocks(struct
+static inline void btrfs_set_file_extent_disk_num_bytes(struct
btrfs_file_extent_item
*e, u64 val)
{
- e->disk_num_blocks = cpu_to_le64(val);
+ e->disk_num_bytes = cpu_to_le64(val);
}
static inline u64 btrfs_file_extent_offset(struct btrfs_file_extent_item *e)
@@ -968,17 +981,17 @@ static inline void btrfs_set_file_extent_offset(struct btrfs_file_extent_item
e->offset = cpu_to_le64(val);
}
-static inline u64 btrfs_file_extent_num_blocks(struct btrfs_file_extent_item
+static inline u64 btrfs_file_extent_num_bytes(struct btrfs_file_extent_item
*e)
{
- return le64_to_cpu(e->num_blocks);
+ return le64_to_cpu(e->num_bytes);
}
-static inline void btrfs_set_file_extent_num_blocks(struct
+static inline void btrfs_set_file_extent_num_bytes(struct
btrfs_file_extent_item *e,
u64 val)
{
- e->num_blocks = cpu_to_le64(val);
+ e->num_bytes = cpu_to_le64(val);
}
/* helper function to cast into the data area of the leaf. */
@@ -986,15 +999,22 @@ static inline void btrfs_set_file_extent_num_blocks(struct
((type *)(btrfs_leaf_data(leaf) + \
btrfs_item_offset((leaf)->items + (slot))))
+static inline u32 btrfs_level_size(struct btrfs_root *root, int level)
+{
+ if (level == 0)
+ return root->leafsize;
+ return root->nodesize;
+}
int btrfs_comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2);
int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_path *path, u32 data_size);
struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
- struct btrfs_root *root);
+ struct btrfs_root *root,
+ u32 blocksize);
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_buffer *buf);
int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 blocknr, u64 num_blocks, int pin);
+ *root, u64 bytenr, u64 num_bytes, int pin);
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_key *key, struct btrfs_path *p, int
ins_len, int cow);
diff --git a/debug-tree.c b/debug-tree.c
index 5a85b080..e3530fed 100644
--- a/debug-tree.c
+++ b/debug-tree.c
@@ -75,7 +75,8 @@ int main(int ac, char **av) {
ri = btrfs_item_ptr(leaf, path.slots[0],
struct btrfs_root_item);
buf = read_tree_block(root->fs_info->tree_root,
- btrfs_root_blocknr(ri));
+ btrfs_root_bytenr(ri),
+ root->leafsize);
switch(found_key.objectid) {
case BTRFS_ROOT_TREE_OBJECTID:
printf("root ");
@@ -93,10 +94,10 @@ int main(int ac, char **av) {
path.slots[0]++;
}
btrfs_release_path(root, &path);
- printf("total blocks %llu\n",
- (unsigned long long)btrfs_super_total_blocks(&super));
- printf("blocks used %llu\n",
- (unsigned long long)btrfs_super_blocks_used(&super));
+ printf("total bytes %llu\n",
+ (unsigned long long)btrfs_super_total_bytes(&super));
+ printf("bytes used %llu\n",
+ (unsigned long long)btrfs_super_bytes_used(&super));
uuidbuf[36] = '\0';
uuid_unparse(super.fsid, uuidbuf);
printf("uuid %s\n", uuidbuf);
diff --git a/disk-io.c b/disk-io.c
index 4c467c5c..72b97c8a 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -31,20 +31,20 @@
#include "transaction.h"
#include "crc32c.h"
-static int allocated_blocks = 0;
+static u64 allocated_bytes = 0;
int cache_max = 10000;
int btrfs_map_bh_to_logical(struct btrfs_root *root, struct btrfs_buffer *bh,
u64 logical)
{
bh->fd = root->fs_info->fp;
- bh->dev_blocknr = logical;
+ bh->dev_bytenr = logical;
return 0;
}
static int check_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
{
- if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
+ if (buf->bytenr != btrfs_header_bytenr(&buf->node.header))
BUG();
if (memcmp(root->fs_info->disk_super->fsid, buf->node.header.fsid,
sizeof(buf->node.header.fsid)))
@@ -71,24 +71,28 @@ static int free_some_buffers(struct btrfs_root *root)
return 0;
}
-struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
+struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 bytenr,
+ u32 blocksize)
{
struct btrfs_buffer *buf;
int ret;
- buf = malloc(sizeof(struct btrfs_buffer) + root->sectorsize);
+ buf = malloc(sizeof(struct btrfs_buffer) + blocksize);
if (!buf)
return buf;
- allocated_blocks++;
- buf->blocknr = blocknr;
+ allocated_bytes += blocksize;
+
+ buf->bytenr = bytenr;
buf->count = 2;
+ buf->size = blocksize;
+
INIT_LIST_HEAD(&buf->dirty);
free_some_buffers(root);
radix_tree_preload(GFP_KERNEL);
- ret = radix_tree_insert(&root->fs_info->cache_radix, blocknr, buf);
+ ret = radix_tree_insert(&root->fs_info->cache_radix, bytenr, buf);
radix_tree_preload_end();
list_add_tail(&buf->cache, &root->fs_info->cache);
- root->fs_info->cache_size++;
+ root->fs_info->cache_size += blocksize;
if (ret) {
free(buf);
return NULL;
@@ -96,14 +100,15 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
return buf;
}
-struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr)
+struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 bytenr,
+ u32 blocksize)
{
struct btrfs_buffer *buf;
- buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr);
+ buf = radix_tree_lookup(&root->fs_info->cache_radix, bytenr);
if (buf) {
buf->count++;
} else {
- buf = alloc_tree_block(root, blocknr);
+ buf = alloc_tree_block(root, bytenr, blocksize);
if (!buf) {
BUG();
return NULL;
@@ -112,23 +117,24 @@ struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr)
return buf;
}
-struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
+struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
+ u32 blocksize)
{
struct btrfs_buffer *buf;
int ret;
- buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr);
+ buf = radix_tree_lookup(&root->fs_info->cache_radix, bytenr);
if (buf) {
buf->count++;
if (check_tree_block(root, buf))
BUG();
} else {
- buf = alloc_tree_block(root, blocknr);
+ buf = alloc_tree_block(root, bytenr, blocksize);
if (!buf)
return NULL;
- btrfs_map_bh_to_logical(root, buf, blocknr);
- ret = pread(buf->fd, &buf->node, root->sectorsize,
- buf->dev_blocknr * root->sectorsize);
- if (ret != root->sectorsize) {
+ btrfs_map_bh_to_logical(root, buf, bytenr);
+ ret = pread(buf->fd, &buf->node, blocksize,
+ buf->dev_bytenr);
+ if (ret != blocksize) {
free(buf);
return NULL;
}
@@ -163,7 +169,8 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_csum_node(struct btrfs_root *root, struct btrfs_node *node)
{
u32 crc;
- size_t len = root->sectorsize - BTRFS_CSUM_SIZE;
+ size_t len = btrfs_level_size(root, btrfs_header_level(&node->header)) -
+ BTRFS_CSUM_SIZE;
crc = crc32c(0, (char *)(node) + BTRFS_CSUM_SIZE, len);
memcpy(node->header.csum, &crc, BTRFS_CRC32_SIZE);
@@ -189,17 +196,17 @@ int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
{
int ret;
- if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
+ if (buf->bytenr != btrfs_header_bytenr(&buf->node.header))
BUG();
- btrfs_map_bh_to_logical(root, buf, buf->blocknr);
+ btrfs_map_bh_to_logical(root, buf, buf->bytenr);
if (check_tree_block(root, buf))
BUG();
btrfs_csum_node(root, &buf->node);
- ret = pwrite(buf->fd, &buf->node, root->sectorsize,
- buf->dev_blocknr * root->sectorsize);
- if (ret != root->sectorsize)
+ ret = pwrite(buf->fd, &buf->node, buf->size,
+ buf->dev_bytenr);
+ if (ret != buf->size)
return ret;
return 0;
}
@@ -226,17 +233,19 @@ static int commit_tree_roots(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info)
{
int ret;
- u64 old_extent_block;
+ u64 old_extent_bytenr;
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_root *extent_root = fs_info->extent_root;
btrfs_write_dirty_block_groups(trans, fs_info->extent_root);
while(1) {
- old_extent_block = btrfs_root_blocknr(&extent_root->root_item);
- if (old_extent_block == extent_root->node->blocknr)
+ old_extent_bytenr = btrfs_root_bytenr(&extent_root->root_item);
+ if (old_extent_bytenr == extent_root->node->bytenr)
break;
- btrfs_set_root_blocknr(&extent_root->root_item,
- extent_root->node->blocknr);
+ btrfs_set_root_bytenr(&extent_root->root_item,
+ extent_root->node->bytenr);
+ extent_root->root_item.level =
+ btrfs_header_level(&extent_root->node->node.header);
ret = btrfs_update_root(trans, tree_root,
&extent_root->root_key,
&extent_root->root_item);
@@ -259,7 +268,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
memcpy(&snap_key, &root->root_key, sizeof(snap_key));
root->root_key.offset++;
- btrfs_set_root_blocknr(&root->root_item, root->node->blocknr);
+ btrfs_set_root_bytenr(&root->root_item, root->node->bytenr);
+ root->root_item.level =
+ btrfs_header_level(&root->node->node.header);
ret = btrfs_insert_root(trans, root->fs_info->tree_root,
&root->root_key, &root->root_item);
BUG_ON(ret);
@@ -304,6 +315,17 @@ static int __setup_root(struct btrfs_super_block *super,
return 0;
}
+struct btrfs_buffer *read_root_block(struct btrfs_root *root, u64 bytenr,
+ u8 level)
+{
+ struct btrfs_buffer *node;
+ u32 size = btrfs_level_size(root, level);
+
+ node = read_tree_block(root, bytenr, size);
+ BUG_ON(!node);
+ return node;
+}
+
static int find_and_setup_root(struct btrfs_super_block *super,
struct btrfs_root *tree_root,
struct btrfs_fs_info *fs_info,
@@ -316,9 +338,9 @@ static int find_and_setup_root(struct btrfs_super_block *super,
ret = btrfs_find_last_root(tree_root, objectid,
&root->root_item, &root->root_key);
BUG_ON(ret);
-
- root->node = read_tree_block(root,
- btrfs_root_blocknr(&root->root_item));
+ root->node = read_root_block(root,
+ btrfs_root_bytenr(&root->root_item),
+ root->root_item.level);
BUG_ON(!root->node);
return 0;
}
@@ -369,7 +391,8 @@ struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super)
BUG_ON(ret < 0);
__setup_root(super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID, fp);
- tree_root->node = read_tree_block(tree_root, btrfs_super_root(super));
+ tree_root->node = read_root_block(tree_root, btrfs_super_root(super),
+ btrfs_super_root_level(super));
BUG_ON(!tree_root->node);
ret = find_and_setup_root(super, tree_root, fs_info,
@@ -393,7 +416,9 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
{
int ret;
- btrfs_set_super_root(s, root->fs_info->tree_root->node->blocknr);
+ btrfs_set_super_root(s, root->fs_info->tree_root->node->bytenr);
+ btrfs_set_super_root_level(s,
+ btrfs_header_level(&root->fs_info->tree_root->node->node.header));
btrfs_csum_super(root, s);
ret = pwrite(root->fs_info->fp, s, sizeof(*s),
@@ -444,7 +469,8 @@ int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
root->fs_info->tree_root->node);
btrfs_block_release(root, root->commit_root);
free(root);
- printf("on close %d blocks are allocated\n", allocated_blocks);
+ printf("on close %llu blocks are allocated\n",
+ (unsigned long long)allocated_bytes);
return 0;
}
@@ -457,15 +483,17 @@ void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf)
BUG_ON(!list_empty(&buf->cache));
BUG_ON(!list_empty(&buf->dirty));
if (!radix_tree_lookup(&root->fs_info->cache_radix,
- buf->blocknr))
+ buf->bytenr))
BUG();
- radix_tree_delete(&root->fs_info->cache_radix, buf->blocknr);
+
+ radix_tree_delete(&root->fs_info->cache_radix, buf->bytenr);
+ BUG_ON(allocated_bytes == 0);
+ allocated_bytes -= buf->size;
+ BUG_ON(root->fs_info->cache_size == 0);
+ root->fs_info->cache_size -= buf->size;
+
memset(buf, 0, sizeof(*buf));
free(buf);
- BUG_ON(allocated_blocks == 0);
- allocated_blocks--;
- BUG_ON(root->fs_info->cache_size == 0);
- root->fs_info->cache_size--;
}
}
diff --git a/disk-io.h b/disk-io.h
index 6c0ba722..43744579 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -21,8 +21,8 @@
#include "list.h"
struct btrfs_buffer {
- u64 blocknr;
- u64 dev_blocknr;
+ u64 bytenr;
+ u64 dev_bytenr;
u32 size;
int count;
int fd;
@@ -34,8 +34,10 @@ struct btrfs_buffer {
};
};
-struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr);
-struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr);
+struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
+ u32 blocksize);
+struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 bytenr,
+ u32 blocksize);
int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_buffer *buf);
int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
diff --git a/extent-tree.c b/extent-tree.c
index 85705dca..38f776e4 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -30,16 +30,8 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
*extent_root);
-/*
- * pending extents are blocks that we're trying to allocate in the extent
- * map while trying to grow the map because of other allocations. To avoid
- * recursing, they are tagged in the radix tree and cleaned up after
- * other allocations are done. The pending tag is also used in the same
- * manner for deletes.
- */
-
static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 blocknr)
+ *root, u64 bytenr, u32 blocksize)
{
struct btrfs_path path;
int ret;
@@ -49,9 +41,9 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
u32 refs;
btrfs_init_path(&path);
- key.objectid = blocknr;
+ key.objectid = bytenr;
btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
- key.offset = 1;
+ key.offset = blocksize;
ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path,
0, 1);
if (ret != 0)
@@ -70,7 +62,7 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
}
static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 blocknr, u32 *refs)
+ *root, u64 bytenr, u32 blocksize, u32 *refs)
{
struct btrfs_path path;
int ret;
@@ -78,8 +70,8 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_leaf *l;
struct btrfs_extent_item *item;
btrfs_init_path(&path);
- key.objectid = blocknr;
- key.offset = 1;
+ key.objectid = bytenr;
+ key.offset = blocksize;
btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path,
0, 0);
@@ -95,17 +87,18 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_buffer *buf)
{
- u64 blocknr;
+ u64 bytenr;
int i;
if (!root->ref_cows)
return 0;
+
if (btrfs_is_leaf(&buf->node))
return 0;
for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
- blocknr = btrfs_node_blockptr(&buf->node, i);
- inc_block_ref(trans, root, blocknr);
+ bytenr = btrfs_node_blockptr(&buf->node, i);
+ inc_block_ref(trans, root, bytenr, root->nodesize);
}
return 0;
}
@@ -171,32 +164,32 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
static int update_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
- u64 blocknr, u64 num, int alloc)
+ u64 bytenr, u64 num, int alloc)
{
struct btrfs_block_group_cache *cache;
struct btrfs_fs_info *info = root->fs_info;
u64 total = num;
u64 old_val;
- u64 block_in_group;
+ u64 byte_in_group;
int ret;
while(total) {
ret = radix_tree_gang_lookup(&info->block_group_radix,
- (void *)&cache, blocknr, 1);
+ (void *)&cache, bytenr, 1);
if (!ret)
return -1;
radix_tree_tag_set(&info->block_group_radix,
cache->key.objectid + cache->key.offset - 1,
BTRFS_BLOCK_GROUP_DIRTY);
- block_in_group = blocknr - cache->key.objectid;
+ byte_in_group = bytenr - cache->key.objectid;
old_val = btrfs_block_group_used(&cache->item);
- if (total > cache->key.offset - block_in_group)
- num = cache->key.offset - block_in_group;
+ if (total > cache->key.offset - byte_in_group)
+ num = cache->key.offset - byte_in_group;
else
num = total;
total -= num;
- blocknr += num;
+ bytenr += num;
if (alloc)
old_val += num;
else
@@ -233,7 +226,6 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
struct btrfs_key ins;
struct btrfs_extent_item extent_item;
int ret;
- u64 super_blocks_used, root_blocks_used;
struct btrfs_fs_info *info = extent_root->fs_info;
struct pending_extent *pe;
struct pending_extent *next;
@@ -256,13 +248,6 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
free_pending_extent(pe);
pe = next;
-
- super_blocks_used = btrfs_super_blocks_used(info->disk_super);
- btrfs_set_super_blocks_used(info->disk_super,
- super_blocks_used + 1);
- root_blocks_used = btrfs_root_blocks_used(&extent_root->root_item);
- btrfs_set_root_blocks_used(&extent_root->root_item,
- root_blocks_used + 1);
ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item,
sizeof(extent_item));
if (ret) {
@@ -277,7 +262,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
* remove an extent from the root, returns 0 on success
*/
static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 blocknr, u64 num_blocks, int pin)
+ *root, u64 bytenr, u64 num_bytes, int pin)
{
struct btrfs_path path;
struct btrfs_key key;
@@ -287,10 +272,9 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_extent_item *ei;
u32 refs;
- BUG_ON(pin && num_blocks != 1);
- key.objectid = blocknr;
+ key.objectid = bytenr;
btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
- key.offset = num_blocks;
+ key.offset = num_bytes;
btrfs_init_path(&path);
ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1);
@@ -306,27 +290,27 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
refs = btrfs_extent_refs(ei) - 1;
btrfs_set_extent_refs(ei, refs);
if (refs == 0) {
- u64 super_blocks_used, root_blocks_used;
+ u64 super_bytes_used, root_bytes_used;
if (pin) {
int err;
err = insert_pending_extent(&info->pinned_tree,
- blocknr, 1);
+ bytenr, num_bytes);
BUG_ON(err);
}
- super_blocks_used = btrfs_super_blocks_used(info->disk_super);
- btrfs_set_super_blocks_used(info->disk_super,
- super_blocks_used - num_blocks);
- root_blocks_used = btrfs_root_blocks_used(&root->root_item);
- btrfs_set_root_blocks_used(&root->root_item,
- root_blocks_used - num_blocks);
+ super_bytes_used = btrfs_super_bytes_used(info->disk_super);
+ btrfs_set_super_bytes_used(info->disk_super,
+ super_bytes_used - num_bytes);
+ root_bytes_used = btrfs_root_bytes_used(&root->root_item);
+ btrfs_set_root_bytes_used(&root->root_item,
+ root_bytes_used - num_bytes);
ret = btrfs_del_item(trans, extent_root, &path);
if (!pin && extent_root->fs_info->last_insert.objectid >
- blocknr)
- extent_root->fs_info->last_insert.objectid = blocknr;
+ bytenr)
+ extent_root->fs_info->last_insert.objectid = bytenr;
if (ret)
BUG();
- ret = update_block_group(trans, root, blocknr, num_blocks, 0);
+ ret = update_block_group(trans, root, bytenr, num_bytes, 0);
BUG_ON(ret);
}
btrfs_release_path(extent_root, &path);
@@ -350,7 +334,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
while(pe) {
remove_pending_extent(del_pending, pe);
ret = __free_extent(trans, extent_root,
- pe->start, 1, 1);
+ pe->start, pe->size, 1);
BUG_ON(ret);
next = next_pending_extent(pe);
if (!next)
@@ -373,7 +357,7 @@ static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
* remove an extent from the root, returns 0 on success
*/
int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 blocknr, u64 num_blocks, int pin)
+ *root, u64 bytenr, u64 num_bytes, int pin)
{
struct btrfs_root *extent_root = root->fs_info->extent_root;
int pending_ret;
@@ -381,11 +365,11 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
if (root == extent_root) {
ret = insert_pending_extent(&root->fs_info->del_pending,
- blocknr, num_blocks);
+ bytenr, num_bytes);
BUG_ON(ret);
return 0;
}
- ret = __free_extent(trans, root, blocknr, num_blocks, pin);
+ ret = __free_extent(trans, root, bytenr, num_bytes, pin);
pending_ret = run_pending(trans, root->fs_info->extent_root);
return ret ? ret : pending_ret;
}
@@ -399,19 +383,18 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
* Any available blocks before search_start are skipped.
*/
static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
- *orig_root, u64 num_blocks, u64 search_start, u64
- search_end, struct btrfs_key *ins)
+ *orig_root, u64 total_needed, u64 search_start,
+ u64 search_end, struct btrfs_key *ins)
{
struct btrfs_path path;
struct btrfs_key key;
int ret;
u64 hole_size = 0;
int slot = 0;
- u64 last_block = 0;
+ u64 last_byte = 0;
int start_found;
struct btrfs_leaf *l;
struct btrfs_root * root = orig_root->fs_info->extent_root;
- int total_needed = num_blocks;
if (root->fs_info->last_insert.objectid > search_start)
search_start = root->fs_info->last_insert.objectid;
@@ -445,8 +428,8 @@ check_failed:
start_found = 1;
goto check_pending;
}
- ins->objectid = last_block > search_start ?
- last_block : search_start;
+ ins->objectid = last_byte > search_start ?
+ last_byte : search_start;
ins->offset = (u64)-1 - ins->objectid;
goto check_pending;
}
@@ -455,18 +438,18 @@ check_failed:
goto next;
if (key.objectid >= search_start) {
if (start_found) {
- if (last_block < search_start)
- last_block = search_start;
- hole_size = key.objectid - last_block;
+ if (last_byte < search_start)
+ last_byte = search_start;
+ hole_size = key.objectid - last_byte;
if (hole_size > total_needed) {
- ins->objectid = last_block;
+ ins->objectid = last_byte;
ins->offset = hole_size;
goto check_pending;
}
}
}
start_found = 1;
- last_block = key.objectid + key.offset;
+ last_byte = key.objectid + key.offset;
next:
path.slots[0]++;
}
@@ -488,7 +471,7 @@ check_pending:
goto check_failed;
}
root->fs_info->last_insert.objectid = ins->objectid;
- ins->offset = num_blocks;
+ ins->offset = total_needed;
return 0;
error:
btrfs_release_path(root, &path);
@@ -501,14 +484,14 @@ error:
*
* returns 0 if everything worked, non-zero otherwise.
*/
-static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, u64 owner, u64 num_blocks,
- u64 search_start, u64
- search_end, struct btrfs_key *ins)
+static int alloc_extent(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 owner,
+ u64 num_bytes, u64 search_start,
+ u64 search_end, struct btrfs_key *ins)
{
int ret;
int pending_ret;
- u64 super_blocks_used, root_blocks_used;
+ u64 super_bytes_used, root_bytes_used;
struct btrfs_fs_info *info = root->fs_info;
struct btrfs_root *extent_root = info->extent_root;
struct btrfs_extent_item extent_item;
@@ -516,23 +499,23 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_extent_refs(&extent_item, 1);
btrfs_set_extent_owner(&extent_item, owner);
- ret = find_free_extent(trans, root, num_blocks, search_start,
+ ret = find_free_extent(trans, root, num_bytes, search_start,
search_end, ins);
if (ret)
return ret;
+ super_bytes_used = btrfs_super_bytes_used(info->disk_super);
+ btrfs_set_super_bytes_used(info->disk_super, super_bytes_used +
+ num_bytes);
+ root_bytes_used = btrfs_root_bytes_used(&root->root_item);
+ btrfs_set_root_bytes_used(&root->root_item, root_bytes_used +
+ num_bytes);
if (root == extent_root) {
ret = insert_pending_extent(&root->fs_info->pending_tree,
ins->objectid, ins->offset);
BUG_ON(ret);
return 0;
}
- super_blocks_used = btrfs_super_blocks_used(info->disk_super);
- btrfs_set_super_blocks_used(info->disk_super, super_blocks_used +
- num_blocks);
- root_blocks_used = btrfs_root_blocks_used(&root->root_item);
- btrfs_set_root_blocks_used(&root->root_item, root_blocks_used +
- num_blocks);
ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
sizeof(extent_item));
@@ -551,23 +534,24 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
* returns the tree buffer or NULL.
*/
struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
- struct btrfs_root *root)
+ struct btrfs_root *root,
+ u32 blocksize)
{
struct btrfs_key ins;
int ret;
struct btrfs_buffer *buf;
ret = alloc_extent(trans, root, root->root_key.objectid,
- 1, 0, (unsigned long)-1, &ins);
+ blocksize, 0, (unsigned long)-1, &ins);
if (ret) {
BUG();
return NULL;
}
ret = update_block_group(trans, root, ins.objectid, ins.offset, 1);
- buf = find_tree_block(root, ins.objectid);
+ buf = find_tree_block(root, ins.objectid, blocksize);
btrfs_set_header_generation(&buf->node.header,
root->root_key.offset + 1);
- btrfs_set_header_blocknr(&buf->node.header, buf->blocknr);
+ 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));
dirty_tree_block(trans, root, buf);
@@ -584,12 +568,12 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
{
struct btrfs_buffer *next;
struct btrfs_buffer *cur;
- u64 blocknr;
+ u64 bytenr;
int ret;
u32 refs;
- ret = lookup_block_ref(trans, root, path->nodes[*level]->blocknr,
- &refs);
+ ret = lookup_block_ref(trans, root, path->nodes[*level]->bytenr,
+ btrfs_level_size(root, *level), &refs);
BUG_ON(ret);
if (refs > 1)
goto out;
@@ -597,20 +581,22 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
* walk down to the last node level and free all the leaves
*/
while(*level > 0) {
+ u32 size = btrfs_level_size(root, *level - 1);
+
cur = path->nodes[*level];
if (path->slots[*level] >=
btrfs_header_nritems(&cur->node.header))
break;
- blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]);
- ret = lookup_block_ref(trans, root, blocknr, &refs);
+ bytenr = btrfs_node_blockptr(&cur->node, path->slots[*level]);
+ ret = lookup_block_ref(trans, root, bytenr, size, &refs);
if (refs != 1 || *level == 1) {
path->slots[*level]++;
- ret = btrfs_free_extent(trans, root, blocknr, 1, 1);
+ ret = btrfs_free_extent(trans, root, bytenr, size, 1);
BUG_ON(ret);
continue;
}
BUG_ON(ret);
- next = read_tree_block(root, blocknr);
+ next = read_tree_block(root, bytenr, size);
if (path->nodes[*level-1])
btrfs_block_release(root, path->nodes[*level-1]);
path->nodes[*level-1] = next;
@@ -618,8 +604,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
path->slots[*level] = 0;
}
out:
- ret = btrfs_free_extent(trans, root, path->nodes[*level]->blocknr, 1,
- 1);
+ ret = btrfs_free_extent(trans, root, path->nodes[*level]->bytenr,
+ btrfs_level_size(root, *level), 1);
btrfs_block_release(root, path->nodes[*level]);
path->nodes[*level] = NULL;
*level += 1;
@@ -647,8 +633,8 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
return 0;
} else {
ret = btrfs_free_extent(trans, root,
- path->nodes[*level]->blocknr,
- 1, 1);
+ path->nodes[*level]->bytenr,
+ btrfs_level_size(root, *level), 1);
btrfs_block_release(root, path->nodes[*level]);
path->nodes[*level] = NULL;
*level = i + 1;
@@ -732,11 +718,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
struct btrfs_key key;
struct btrfs_key found_key;
struct btrfs_leaf *leaf;
- u64 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->sectorsize;
+ u64 group_size = BTRFS_BLOCK_GROUP_SIZE;
root = root->fs_info->extent_root;
key.objectid = 0;
- key.offset = group_size_blocks;
+ key.offset = group_size;
btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
btrfs_init_path(&path);
@@ -766,7 +752,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
found_key.offset - 1, (void *)cache);
BUG_ON(ret);
if (key.objectid >=
- btrfs_super_total_blocks(root->fs_info->disk_super))
+ btrfs_super_total_bytes(root->fs_info->disk_super))
break;
}
btrfs_release_path(root, &path);
diff --git a/mkfs.c b/mkfs.c
index da6722e6..057ff40b 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -85,55 +85,57 @@ error:
static int make_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
- u64 group_size_blocks;
- u64 total_blocks;
+ u64 group_size;
+ u64 total_bytes;
u64 cur_start;
int ret;
u64 nr = 0;
struct btrfs_block_group_cache *cache;
root = root->fs_info->extent_root;
+
/* first we bootstrap the things into cache */
- group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->sectorsize;
+ group_size = BTRFS_BLOCK_GROUP_SIZE;
cache = malloc(sizeof(*cache));
cache->key.objectid = 0;
- cache->key.offset = group_size_blocks;
+ cache->key.offset = group_size;
btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+
memset(&cache->item, 0, sizeof(cache->item));
btrfs_set_block_group_used(&cache->item,
- btrfs_super_blocks_used(root->fs_info->disk_super));
+ btrfs_super_bytes_used(root->fs_info->disk_super));
ret = radix_tree_insert(&root->fs_info->block_group_radix,
- group_size_blocks - 1, (void *)cache);
+ group_size - 1, (void *)cache);
BUG_ON(ret);
- total_blocks = btrfs_super_total_blocks(root->fs_info->disk_super);
- cur_start = group_size_blocks;
- while(cur_start < total_blocks) {
+ total_bytes = btrfs_super_total_bytes(root->fs_info->disk_super);
+ cur_start = group_size;
+ while(cur_start < total_bytes) {
cache = malloc(sizeof(*cache));
cache->key.objectid = cur_start;
- cache->key.offset = group_size_blocks;
+ cache->key.offset = group_size;
btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
memset(&cache->item, 0, sizeof(cache->item));
if (nr % 3)
cache->item.flags |= BTRFS_BLOCK_GROUP_DATA;
ret = radix_tree_insert(&root->fs_info->block_group_radix,
- cur_start + group_size_blocks - 1,
+ cur_start + group_size - 1,
(void *)cache);
BUG_ON(ret);
- cur_start += group_size_blocks;
+ cur_start += group_size;
nr++;
}
/* then insert all the items */
cur_start = 0;
- while(cur_start < total_blocks) {
+ while(cur_start < total_bytes) {
cache = radix_tree_lookup(&root->fs_info->block_group_radix,
- cur_start + group_size_blocks - 1);
+ cur_start + group_size - 1);
BUG_ON(!cache);
ret = btrfs_insert_block_group(trans, root, &cache->key,
&cache->item);
BUG_ON(ret);
- cur_start += group_size_blocks;
+ cur_start += group_size;
}
return 0;
}
@@ -174,7 +176,8 @@ err:
return ret;
}
-int mkfs(int fd, char *pathname, u64 num_blocks, u32 blocksize)
+int mkfs(int fd, char *pathname, u64 num_bytes, u32 nodesize, u32 leafsize,
+ u32 sectorsize)
{
struct btrfs_super_block super;
struct btrfs_leaf *empty_leaf;
@@ -185,33 +188,37 @@ int mkfs(int fd, char *pathname, u64 num_blocks, u32 blocksize)
char *block;
int ret;
u32 itemoff;
- u32 start_block = BTRFS_SUPER_INFO_OFFSET / blocksize;
+ u32 start_block = BTRFS_SUPER_INFO_OFFSET;
+ u32 first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize;
btrfs_set_super_generation(&super, 1);
- btrfs_set_super_blocknr(&super, start_block);
- btrfs_set_super_root(&super, start_block + 1);
+ btrfs_set_super_bytenr(&super, start_block);
+ btrfs_set_super_root_level(&super, 0);
+ btrfs_set_super_root(&super, first_free);
strcpy((char *)(&super.magic), BTRFS_MAGIC);
-printf("blocksize is %d\n", blocksize);
- btrfs_set_super_sectorsize(&super, blocksize);
- btrfs_set_super_leafsize(&super, blocksize);
- btrfs_set_super_nodesize(&super, blocksize);
+printf("blocksize is %d\n", leafsize);
+ btrfs_set_super_sectorsize(&super, sectorsize);
+ btrfs_set_super_leafsize(&super, leafsize);
+ btrfs_set_super_nodesize(&super, nodesize);
- btrfs_set_super_total_blocks(&super, num_blocks);
- btrfs_set_super_blocks_used(&super, start_block + 4);
+ num_bytes = (num_bytes / sectorsize) * sectorsize;
+ btrfs_set_super_total_bytes(&super, num_bytes);
+ btrfs_set_super_bytes_used(&super, start_block + 3 * leafsize +
+ sectorsize);
uuid_generate(super.fsid);
- block = malloc(blocksize);
- memset(block, 0, blocksize);
- BUG_ON(sizeof(super) > blocksize);
+ block = malloc(sectorsize);
+ memset(block, 0, sectorsize);
+ BUG_ON(sizeof(super) > sectorsize);
memcpy(block, &super, sizeof(super));
- ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET);
- BUG_ON(ret != blocksize);
+ ret = pwrite(fd, block, sectorsize, BTRFS_SUPER_INFO_OFFSET);
+ BUG_ON(ret != sectorsize);
/* create the tree of root objects */
- empty_leaf = malloc(blocksize);
- memset(empty_leaf, 0, blocksize);
- btrfs_set_header_blocknr(&empty_leaf->header, start_block + 1);
+ empty_leaf = malloc(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_owner(&empty_leaf->header, BTRFS_ROOT_TREE_OBJECTID);
@@ -234,34 +241,35 @@ printf("blocksize is %d\n", blocksize);
btrfs_set_item_size(&item, sizeof(root_item));
btrfs_set_disk_key_type(&item.key, BTRFS_ROOT_ITEM_KEY);
- itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) - sizeof(root_item);
- btrfs_set_root_blocknr(&root_item, start_block + 2);
+ itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - sizeof(root_item);
+ btrfs_set_root_bytenr(&root_item, first_free + leafsize);
+ root_item.level = 0;
btrfs_set_item_offset(&item, itemoff);
btrfs_set_disk_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
memcpy(empty_leaf->items, &item, sizeof(item));
memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
&root_item, sizeof(root_item));
- btrfs_set_root_blocknr(&root_item, start_block + 3);
- btrfs_set_root_blocks_used(&root_item, 1);
+ btrfs_set_root_bytenr(&root_item, first_free + leafsize * 2);
+ btrfs_set_root_bytes_used(&root_item, 1);
itemoff = itemoff - sizeof(root_item);
btrfs_set_item_offset(&item, itemoff);
btrfs_set_disk_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
memcpy(empty_leaf->items + 1, &item, sizeof(item));
memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
&root_item, sizeof(root_item));
- ret = pwrite(fd, empty_leaf, blocksize, (start_block + 1) * blocksize);
+ ret = pwrite(fd, empty_leaf, leafsize, first_free);
/* create the items for the extent tree */
- btrfs_set_header_blocknr(&empty_leaf->header, start_block + 2);
+ btrfs_set_header_bytenr(&empty_leaf->header, first_free + leafsize);
btrfs_set_header_nritems(&empty_leaf->header, 4);
/* item1, reserve blocks 0-16 */
btrfs_set_disk_key_objectid(&item.key, 0);
- btrfs_set_disk_key_offset(&item.key, start_block + 1);
+ btrfs_set_disk_key_offset(&item.key, first_free);
btrfs_set_disk_key_type(&item.key, 0);
btrfs_set_disk_key_type(&item.key, BTRFS_EXTENT_ITEM_KEY);
- itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) -
+ itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) -
sizeof(struct btrfs_extent_item);
btrfs_set_item_offset(&item, itemoff);
btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
@@ -272,8 +280,8 @@ printf("blocksize is %d\n", blocksize);
&extent_item, btrfs_item_size(&item));
/* item2, give block 17 to the root */
- btrfs_set_disk_key_objectid(&item.key, start_block + 1);
- btrfs_set_disk_key_offset(&item.key, 1);
+ btrfs_set_disk_key_objectid(&item.key, first_free);
+ btrfs_set_disk_key_offset(&item.key, leafsize);
itemoff = itemoff - sizeof(struct btrfs_extent_item);
btrfs_set_item_offset(&item, itemoff);
memcpy(empty_leaf->items + 1, &item, sizeof(item));
@@ -281,8 +289,8 @@ printf("blocksize is %d\n", blocksize);
&extent_item, btrfs_item_size(&item));
/* item3, give block 18 to the extent root */
- btrfs_set_disk_key_objectid(&item.key, start_block + 2);
- btrfs_set_disk_key_offset(&item.key, 1);
+ btrfs_set_disk_key_objectid(&item.key, first_free + leafsize);
+ btrfs_set_disk_key_offset(&item.key, leafsize);
itemoff = itemoff - sizeof(struct btrfs_extent_item);
btrfs_set_item_offset(&item, itemoff);
memcpy(empty_leaf->items + 2, &item, sizeof(item));
@@ -290,22 +298,22 @@ printf("blocksize is %d\n", blocksize);
&extent_item, btrfs_item_size(&item));
/* item4, give block 19 to the FS root */
- btrfs_set_disk_key_objectid(&item.key, start_block + 3);
- btrfs_set_disk_key_offset(&item.key, 1);
+ btrfs_set_disk_key_objectid(&item.key, first_free + leafsize * 2);
+ btrfs_set_disk_key_offset(&item.key, leafsize);
itemoff = itemoff - sizeof(struct btrfs_extent_item);
btrfs_set_item_offset(&item, itemoff);
memcpy(empty_leaf->items + 3, &item, sizeof(item));
memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
&extent_item, btrfs_item_size(&item));
- ret = pwrite(fd, empty_leaf, blocksize, (start_block + 2) * blocksize);
- if (ret != blocksize)
+ ret = pwrite(fd, empty_leaf, leafsize, first_free + leafsize);
+ if (ret != leafsize)
return -1;
/* finally create the FS root */
- btrfs_set_header_blocknr(&empty_leaf->header, start_block + 3);
+ btrfs_set_header_bytenr(&empty_leaf->header, first_free + leafsize * 2);
btrfs_set_header_nritems(&empty_leaf->header, 0);
- ret = pwrite(fd, empty_leaf, blocksize, (start_block + 3) * blocksize);
- if (ret != blocksize)
+ ret = pwrite(fd, empty_leaf, leafsize, first_free + leafsize * 2);
+ if (ret != leafsize)
return -1;
return 0;
}
@@ -322,7 +330,14 @@ u64 device_size(int fd, struct stat *st)
if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
return size;
}
- return 0; }
+ return 0;
+}
+
+static void print_usage(void)
+{
+ fprintf(stderr, "usage: mkfs.btrfs [ -l leafsize ] [ -n nodesize] dev [ blocks ]\n");
+ exit(1);
+}
int main(int ac, char **av)
{
@@ -332,23 +347,50 @@ int main(int ac, char **av)
struct stat st;
int ret;
int i;
- char *buf = malloc(8192);
+ u32 leafsize = 8 * 1024;
+ u32 sectorsize = 4096;
+ u32 nodesize = 8 * 1024;
+ char *buf = malloc(sectorsize);
char *realpath_name;
radix_tree_init();
- if (ac >= 2) {
- file = av[1];
- if (ac == 3) {
- block_count = atoi(av[2]);
+ while(1) {
+ int c;
+ c = getopt(ac, av, "l:n:");
+ if (c < 0)
+ break;
+ switch(c) {
+ case 'l':
+ leafsize = atol(optarg);
+ break;
+ case 'n':
+ nodesize = atol(optarg);
+ break;
+ default:
+ print_usage();
+ }
+ }
+ if (leafsize < sectorsize || (leafsize & (sectorsize - 1))) {
+ fprintf(stderr, "Illegal leafsize %u\n", leafsize);
+ exit(1);
+ }
+ if (nodesize < sectorsize || (nodesize & (sectorsize - 1))) {
+ fprintf(stderr, "Illegal nodesize %u\n", nodesize);
+ exit(1);
+ }
+ ac = ac - optind;
+ if (ac >= 1) {
+ file = av[optind];
+ if (ac == 2) {
+ block_count = atol(av[optind + 1]);
if (!block_count) {
fprintf(stderr, "error finding block count\n");
exit(1);
}
}
} else {
- fprintf(stderr, "usage: mkfs.btrfs file [block count]\n");
- exit(1);
+ print_usage();
}
fd = open(file, O_RDWR);
if (fd < 0) {
@@ -366,22 +408,24 @@ int main(int ac, char **av)
fprintf(stderr, "unable to find %s size\n", file);
exit(1);
}
- block_count /= 8192;
+ block_count /= sectorsize;
}
if (block_count < 256) {
fprintf(stderr, "device %s is too small\n", file);
exit(1);
}
- memset(buf, 0, 8192);
+ block_count = block_count * sectorsize;
+ memset(buf, 0, sectorsize);
for(i = 0; i < 64; i++) {
- ret = write(fd, buf, 8192);
- if (ret != 8192) {
+ ret = write(fd, buf, sectorsize);
+ if (ret != sectorsize) {
fprintf(stderr, "unable to zero fill device\n");
exit(1);
}
}
realpath_name = realpath(file, NULL);
- ret = mkfs(fd, realpath_name, block_count, 8192);
+ ret = mkfs(fd, realpath_name, block_count, nodesize, leafsize,
+ sectorsize);
if (ret) {
fprintf(stderr, "error during mkfs %d\n", ret);
exit(1);
@@ -391,8 +435,9 @@ int main(int ac, char **av)
fprintf(stderr, "failed to setup the root directory\n");
exit(1);
}
- printf("fs created on %s blocksize %d blocks %llu\n",
- file, 8192, (unsigned long long)block_count);
+ printf("fs created on %s nodesize %u leafsize %u sectorsize %u bytes %llu\n",
+ file, nodesize, leafsize, sectorsize,
+ (unsigned long long)block_count);
return 0;
}
diff --git a/print-tree.c b/print-tree.c
index e1e0aaa4..90d55073 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -58,7 +58,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
u32 type;
printf("leaf %llu ptrs %d free space %d generation %llu owner %llu\n",
- (unsigned long long)btrfs_header_blocknr(&l->header), nr,
+ (unsigned long long)btrfs_header_bytenr(&l->header), nr,
btrfs_leaf_free_space(root, l),
(unsigned long long)btrfs_header_generation(&l->header),
(unsigned long long)btrfs_header_owner(&l->header));
@@ -93,8 +93,9 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
break;
case BTRFS_ROOT_ITEM_KEY:
ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
- printf("\t\troot data blocknr %llu dirid %llu refs %u\n",
- (unsigned long long)btrfs_root_blocknr(ri),
+ printf("\t\troot data bytenr %llu level %d dirid %llu refs %u\n",
+ (unsigned long long)btrfs_root_bytenr(ri),
+ ri->level,
(unsigned long long)btrfs_root_dirid(ri),
btrfs_root_refs(ri));
if (1 || btrfs_root_refs(ri) == 0) {
@@ -128,12 +129,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
btrfs_file_extent_inline_len(l->items + i));
break;
}
- printf("\t\textent data disk block %llu nr %llu\n",
- (unsigned long long)btrfs_file_extent_disk_blocknr(fi),
- (unsigned long long)btrfs_file_extent_disk_num_blocks(fi));
+ printf("\t\textent data disk byte %llu nr %llu\n",
+ (unsigned long long)btrfs_file_extent_disk_bytenr(fi),
+ (unsigned long long)btrfs_file_extent_disk_num_bytes(fi));
printf("\t\textent data offset %llu nr %llu\n",
(unsigned long long)btrfs_file_extent_offset(fi),
- (unsigned long long)btrfs_file_extent_num_blocks(fi));
+ (unsigned long long)btrfs_file_extent_num_bytes(fi));
break;
case BTRFS_BLOCK_GROUP_ITEM_KEY:
bi = btrfs_item_ptr(l, i,
@@ -155,6 +156,7 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
int i;
u32 nr;
struct btrfs_node *c;
+ u32 size;
if (!t)
return;
@@ -165,24 +167,28 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
return;
}
printf("node %llu level %d ptrs %d free %u generation %llu owner %llu\n",
- (unsigned long long)t->blocknr,
+ (unsigned long long)t->bytenr,
btrfs_header_level(&c->header), nr,
(u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr,
(unsigned long long)btrfs_header_generation(&c->header),
(unsigned long long)btrfs_header_owner(&c->header));
fflush(stdout);
+ size = btrfs_level_size(root, btrfs_header_level(&c->header) - 1);
for (i = 0; i < nr; i++) {
- printf("\tkey %d (%llu %x %llu) block %llu\n",
+ u64 blocknr = btrfs_node_blockptr(c, i);
+ printf("\tkey %d (%llu %x %llu) block %llu (%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)btrfs_node_blockptr(c, i));
+ (unsigned long long)blocknr,
+ (unsigned long long)blocknr / size);
fflush(stdout);
}
for (i = 0; i < nr; i++) {
struct btrfs_buffer *next_buf = read_tree_block(root,
- btrfs_node_blockptr(c, i));
+ btrfs_node_blockptr(c, i),
+ size);
struct btrfs_node *next = &next_buf->node;
if (btrfs_is_leaf(next) &&
btrfs_header_level(&c->header) != 1)