start of support for subvolumes

This commit is contained in:
Chris Mason 2007-04-06 15:39:12 -04:00 committed by David Woodhouse
parent d785b7d058
commit 8accdae27a
5 changed files with 100 additions and 51 deletions

28
ctree.h
View File

@ -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);

View File

@ -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);

View File

@ -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);

75
mkfs.c
View File

@ -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,29 +51,62 @@ 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);
if (ret)
goto error;
ret = close_ctree(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 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);
err:
return ret;
}
int mkfs(int fd, u64 num_blocks, u32 blocksize)
{
struct btrfs_super_block super;
@ -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);

View File

@ -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,