summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ctree.h28
-rw-r--r--dir-item.c14
-rw-r--r--dir-test.c14
-rw-r--r--mkfs.c73
-rw-r--r--print-tree.c20
5 files changed, 99 insertions, 50 deletions
diff --git a/ctree.h b/ctree.h
index d35db820..19e79270 100644
--- a/ctree.h
+++ b/ctree.h
@@ -180,13 +180,15 @@ struct btrfs_inline_data_item {
} __attribute__ ((__packed__));
struct btrfs_dir_item {
- __le64 objectid;
+ struct btrfs_disk_key location;
__le16 flags;
__le16 name_len;
u8 type;
} __attribute__ ((__packed__));
struct btrfs_root_item {
+ struct btrfs_inode_item inode;
+ __le64 root_dirid;
__le64 blocknr;
__le32 flags;
__le64 block_limit;
@@ -498,16 +500,6 @@ static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val)
item->size = cpu_to_le16(val);
}
-static inline u64 btrfs_dir_objectid(struct btrfs_dir_item *d)
-{
- return le64_to_cpu(d->objectid);
-}
-
-static inline void btrfs_set_dir_objectid(struct btrfs_dir_item *d, u64 val)
-{
- d->objectid = cpu_to_le64(val);
-}
-
static inline u16 btrfs_dir_flags(struct btrfs_dir_item *d)
{
return le16_to_cpu(d->flags);
@@ -718,6 +710,16 @@ static inline void btrfs_set_root_blocknr(struct btrfs_root_item *item, u64 val)
item->blocknr = cpu_to_le64(val);
}
+static inline u64 btrfs_root_dirid(struct btrfs_root_item *item)
+{
+ return le64_to_cpu(item->root_dirid);
+}
+
+static inline void btrfs_set_root_dirid(struct btrfs_root_item *item, u64 val)
+{
+ item->root_dirid = cpu_to_le64(val);
+}
+
static inline u32 btrfs_root_refs(struct btrfs_root_item *item)
{
return le32_to_cpu(item->refs);
@@ -899,8 +901,8 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct
btrfs_root_item *item, struct btrfs_key *key);
int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, char *name, int name_len, u64 dir, u64
- objectid, u8 type);
+ *root, char *name, int name_len, u64 dir,
+ struct btrfs_key *location, u8 type);
int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_path *path, u64 dir, char *name,
int name_len, int mod);
diff --git a/dir-item.c b/dir-item.c
index fff16348..7058b89f 100644
--- a/dir-item.c
+++ b/dir-item.c
@@ -28,8 +28,8 @@ int insert_with_overflow(struct btrfs_trans_handle *trans, struct btrfs_root
}
int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
- *root, char *name, int name_len, u64 dir, u64
- objectid, u8 type)
+ *root, char *name, int name_len, u64 dir,
+ struct btrfs_key *location, u8 type)
{
int ret = 0;
struct btrfs_path path;
@@ -56,23 +56,27 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
struct btrfs_dir_item);
- btrfs_set_dir_objectid(dir_item, objectid);
+ btrfs_cpu_key_to_disk(&dir_item->location, location);
btrfs_set_dir_type(dir_item, type);
btrfs_set_dir_flags(dir_item, 0);
btrfs_set_dir_name_len(dir_item, name_len);
name_ptr = (char *)(dir_item + 1);
memcpy(name_ptr, name, name_len);
+ /* FIXME, use some real flag for selecting the extra index */
+ if (root == root->fs_info->tree_root)
+ goto out;
+
btrfs_release_path(root, &path);
btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
- key.offset = objectid;
+ key.offset = location->objectid;
ret = insert_with_overflow(trans, root, &path, &key, data_size);
if (ret)
goto out;
dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
struct btrfs_dir_item);
- btrfs_set_dir_objectid(dir_item, objectid);
+ btrfs_cpu_key_to_disk(&dir_item->location, location);
btrfs_set_dir_type(dir_item, type);
btrfs_set_dir_flags(dir_item, 0);
btrfs_set_dir_name_len(dir_item, name_len);
diff --git a/dir-test.c b/dir-test.c
index 6117d225..078284ea 100644
--- a/dir-test.c
+++ b/dir-test.c
@@ -69,6 +69,7 @@ static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
inode_map.objectid = objectid;
inode_map.flags = 0;
+ btrfs_set_key_type(&inode_map, BTRFS_INODE_ITEM_KEY);
inode_map.offset = 0;
ret = btrfs_insert_inode_map(trans, root, objectid, &inode_map);
@@ -80,7 +81,7 @@ static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if (ret)
goto error;
ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
- objectid, 1);
+ &inode_map, 1);
if (ret)
goto error;
@@ -134,14 +135,19 @@ static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
int ret;
char buf[128];
unsigned long oid;
+ struct btrfs_key key;
ret = find_num(radix, &oid, 1);
if (ret < 0)
return 0;
sprintf(buf, "str-%lu", oid);
+ key.objectid = file_oid;
+ key.flags = 0;
+ btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
+ key.offset = 0;
ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
- file_oid, 1);
+ &key, 1);
if (ret != -EEXIST) {
printf("insert on %s gave us %d\n", buf, ret);
return 1;
@@ -163,7 +169,7 @@ static int del_dir_item(struct btrfs_trans_handle *trans,
/* find the inode number of the file */
di = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0],
struct btrfs_dir_item);
- file_objectid = btrfs_dir_objectid(di);
+ file_objectid = btrfs_disk_key_objectid(&di->location);
/* delete the directory item */
ret = btrfs_del_item(trans, root, path);
@@ -254,7 +260,7 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
if (!ret) {
di = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
struct btrfs_dir_item);
- objectid = btrfs_dir_objectid(di);
+ objectid = btrfs_disk_key_objectid(&di->location);
btrfs_release_path(root, &path);
btrfs_init_path(&path);
ret = btrfs_lookup_inode_map(trans, root, &path, objectid, 0);
diff --git a/mkfs.c b/mkfs.c
index 9337cc0c..f182a190 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -21,33 +21,25 @@
static inline int ioctl(int fd, int define, u64 *size) { return 0; }
#endif
-static int make_root_dir(int fd) {
- struct btrfs_root *root;
- struct btrfs_super_block super;
+static int __make_root_dir(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root)
+{
int ret;
char buf[8];
u64 objectid;
struct btrfs_key inode_map;
struct btrfs_inode_item inode_item;
- struct btrfs_trans_handle *trans;
-
- root = open_ctree_fd(fd, &super);
-
- if (!root) {
- fprintf(stderr, "ctree init failed\n");
- return -1;
- }
buf[0] = '.';
buf[1] = '.';
- trans = btrfs_start_transaction(root, 1);
ret = btrfs_find_free_objectid(trans, root, 1, &objectid);
if (ret)
goto error;
inode_map.objectid = objectid;
inode_map.flags = 0;
+ btrfs_set_key_type(&inode_map, BTRFS_INODE_ITEM_KEY);
inode_map.offset = 0;
ret = btrfs_insert_inode_map(trans, root, objectid, &inode_map);
@@ -59,26 +51,59 @@ static int make_root_dir(int fd) {
btrfs_set_inode_size(&inode_item, 3);
btrfs_set_inode_nlink(&inode_item, 1);
btrfs_set_inode_nblocks(&inode_item, 1);
- btrfs_set_inode_mode(&inode_item, S_IFDIR | 0755);
+ btrfs_set_inode_mode(&inode_item, S_IFDIR | 0555);
- btrfs_set_super_root_dir(&super, objectid);
+ if (root->fs_info->tree_root == root)
+ btrfs_set_super_root_dir(root->fs_info->disk_super, objectid);
ret = btrfs_insert_inode(trans, root, objectid, &inode_item);
if (ret)
goto error;
ret = btrfs_insert_dir_item(trans, root, buf, 1, objectid,
- objectid, 1);
+ &inode_map, 1);
if (ret)
goto error;
ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid,
- objectid, 1);
+ &inode_map, 1);
if (ret)
goto error;
- ret = btrfs_commit_transaction(trans, root, &super);
+ btrfs_set_root_dirid(&root->root_item, objectid);
+ ret = 0;
+error:
+ return ret;
+}
+
+static int make_root_dir(int fd) {
+ struct btrfs_root *root;
+ struct btrfs_super_block super;
+ struct btrfs_trans_handle *trans;
+ int ret;
+ struct btrfs_key location;
+
+ root = open_ctree_fd(fd, &super);
+
+ if (!root) {
+ fprintf(stderr, "ctree init failed\n");
+ return -1;
+ }
+ trans = btrfs_start_transaction(root, 1);
+ ret = __make_root_dir(trans, root->fs_info->tree_root);
if (ret)
- goto error;
+ goto err;
+ ret = __make_root_dir(trans, root);
+ if (ret)
+ goto err;
+ memcpy(&location, &root->fs_info->fs_root->root_key, sizeof(location));
+ location.offset = (u64)-1;
+ ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
+ "default", strlen("default"),
+ btrfs_super_root_dir(root->fs_info->disk_super),
+ &location, 1);
+ if (ret)
+ goto err;
+ btrfs_commit_transaction(trans, root, root->fs_info->disk_super);
ret = close_ctree(root, &super);
-error:
+err:
return ret;
}
@@ -89,6 +114,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
struct btrfs_root_item root_item;
struct btrfs_item item;
struct btrfs_extent_item extent_item;
+ struct btrfs_inode_item *inode_item;
char *block;
int ret;
u32 itemoff;
@@ -121,6 +147,15 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
sizeof(empty_leaf->header.fsid));
/* create the items for the root tree */
+ inode_item = &root_item.inode;
+ memset(inode_item, 0, sizeof(*inode_item));
+ btrfs_set_inode_generation(inode_item, 1);
+ btrfs_set_inode_size(inode_item, 3);
+ btrfs_set_inode_nlink(inode_item, 1);
+ btrfs_set_inode_nblocks(inode_item, 1);
+ btrfs_set_inode_mode(inode_item, S_IFDIR | 0755);
+
+ btrfs_set_root_dirid(&root_item, 0);
btrfs_set_root_blocknr(&root_item, start_block + 2);
btrfs_set_root_refs(&root_item, 1);
itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) - sizeof(root_item);
diff --git a/print-tree.c b/print-tree.c
index ca3c653c..0a6332d1 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -28,11 +28,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
for (i = 0 ; i < nr ; i++) {
item = l->items + i;
type = btrfs_disk_key_type(&item->key);
- printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n",
+ printf("\titem %d key (%Lu %Lu %u) itemoff %d itemsize %d\n",
i,
btrfs_disk_key_objectid(&item->key),
- btrfs_disk_key_flags(&item->key),
btrfs_disk_key_offset(&item->key),
+ btrfs_disk_key_flags(&item->key),
btrfs_item_offset(item),
btrfs_item_size(item));
switch (type) {
@@ -50,7 +50,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
case BTRFS_DIR_ITEM_KEY:
di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
printf("\t\tdir oid %Lu flags %u type %u\n",
- btrfs_dir_objectid(di),
+ btrfs_disk_key_objectid(&di->location),
btrfs_dir_flags(di),
btrfs_dir_type(di));
printf("\t\tname %.*s\n",
@@ -59,7 +59,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
case BTRFS_DIR_INDEX_KEY:
di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
printf("\t\tdir index %Lu flags %u type %u\n",
- btrfs_dir_objectid(di),
+ btrfs_disk_key_objectid(&di->location),
btrfs_dir_flags(di),
btrfs_dir_type(di));
printf("\t\tname %.*s\n",
@@ -67,8 +67,10 @@ 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 %Lu refs %u\n",
- btrfs_root_blocknr(ri), btrfs_root_refs(ri));
+ printf("\t\troot data blocknr %Lu dirid %Lu refs %u\n",
+ btrfs_root_blocknr(ri),
+ btrfs_root_dirid(ri),
+ btrfs_root_refs(ri));
break;
case BTRFS_EXTENT_ITEM_KEY:
ei = btrfs_item_ptr(l, i, struct btrfs_extent_item);
@@ -77,10 +79,10 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
break;
case BTRFS_INODE_MAP_ITEM_KEY:
mi = btrfs_item_ptr(l, i, struct btrfs_inode_map_item);
- printf("\t\tinode map key %Lu %u %Lu\n",
+ printf("\t\tinode map key %Lu %Lu %u\n",
btrfs_disk_key_objectid(&mi->key),
- btrfs_disk_key_flags(&mi->key),
- btrfs_disk_key_offset(&mi->key));
+ btrfs_disk_key_offset(&mi->key),
+ btrfs_disk_key_flags(&mi->key));
break;
case BTRFS_EXTENT_DATA_KEY:
fi = btrfs_item_ptr(l, i,