create a root dir in mkfs
authorChris Mason <chris.mason@oracle.com>
Wed, 21 Mar 2007 15:13:29 +0000 (11:13 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Wed, 21 Mar 2007 15:13:29 +0000 (11:13 -0400)
ctree.h
dir-item.c
disk-io.c
disk-io.h
mkfs.c
print-tree.c

diff --git a/ctree.h b/ctree.h
index 1a4d1d6..c9361d8 100644 (file)
--- a/ctree.h
+++ b/ctree.h
@@ -75,6 +75,7 @@ struct btrfs_super_block {
        __le64 root;
        __le64 total_blocks;
        __le64 blocks_used;
+       __le64 root_dir_objectid;
 } __attribute__ ((__packed__));
 
 /*
@@ -693,6 +694,17 @@ static inline void btrfs_set_super_blocksize(struct btrfs_super_block *s,
        s->blocksize = cpu_to_le32(val);
 }
 
+static inline u64 btrfs_super_root_dir(struct btrfs_super_block *s)
+{
+       return le64_to_cpu(s->root_dir_objectid);
+}
+
+static inline void btrfs_set_super_root_dir(struct btrfs_super_block *s, u64
+                                           val)
+{
+       s->root_dir_objectid = cpu_to_le64(val);
+}
+
 static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
 {
        return (u8 *)l->items;
index 949c4e5..ec3e488 100644 (file)
@@ -21,7 +21,12 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
        key.objectid = dir;
        key.flags = 0;
        btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
-       ret = btrfs_name_hash(name, name_len, &key.offset);
+       if (name_len == 1 && *name == '.')
+               key.offset = 1;
+       else if (name_len == 2 && name[0] == '.' && name[1] == '.')
+               key.offset = 2;
+       else
+               ret = btrfs_name_hash(name, name_len, &key.offset);
        BUG_ON(ret);
        btrfs_init_path(&path);
        data_size = sizeof(*dir_item) + name_len;
index 0322c55..05637f9 100644 (file)
--- a/disk-io.c
+++ b/disk-io.c
@@ -267,19 +267,24 @@ static int find_and_setup_root(struct btrfs_super_block *super,
 
 struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
 {
+       int fp;
+
+       fp = open(filename, O_CREAT | O_RDWR, 0600);
+       if (fp < 0) {
+               return NULL;
+       }
+       return open_ctree_fd(fp, super);
+}
+
+struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super)
+{
        struct btrfs_root *root = malloc(sizeof(struct btrfs_root));
        struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root));
        struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root));
        struct btrfs_root *inode_root = malloc(sizeof(struct btrfs_root));
        struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info));
-       int fp;
        int ret;
 
-       fp = open(filename, O_CREAT | O_RDWR, 0600);
-       if (fp < 0) {
-               free(root);
-               return NULL;
-       }
        INIT_RADIX_TREE(&fs_info->cache_radix, GFP_KERNEL);
        INIT_RADIX_TREE(&fs_info->pinned_radix, GFP_KERNEL);
        INIT_LIST_HEAD(&fs_info->trans);
index 24a9e77..d888cf5 100644 (file)
--- a/disk-io.h
+++ b/disk-io.h
@@ -24,6 +24,7 @@ int clean_tree_block(struct btrfs_trans_handle *trans,
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root
                             *root, struct btrfs_super_block *s);
 struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
+struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super);
 int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s);
 void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf);
 int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root *root,
diff --git a/mkfs.c b/mkfs.c
index f7efc8a..f6a6b77 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
 #include "radix-tree.h"
 #include "ctree.h"
 #include "disk-io.h"
+#include "transaction.h"
 
 #ifdef __CHECKER__
 #define BLKGETSIZE64 0
 static inline int ioctl(int fd, int define, u64 *size) { return 0; }
 #endif
 
-#if 0
-#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
-#   define BLKGETSIZE64 _IOR(0x12, 114, __u64)
-#endif
-#endif
+static int make_root_dir(int fd) {
+       struct btrfs_root *root;
+       struct btrfs_super_block super;
+       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;
+       inode_map.offset = 0;
+
+       ret = btrfs_insert_inode_map(trans, root, objectid, &inode_map);
+       if (ret)
+               goto error;
+
+       memset(&inode_item, 0, sizeof(inode_item));
+       btrfs_set_inode_generation(&inode_item, root->fs_info->generation);
+       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 | 0711);
+
+       btrfs_set_super_root_dir(&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);
+       if (ret)
+               goto error;
+       ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid,
+                                   objectid, 1);
+       if (ret)
+               goto error;
+       ret = btrfs_commit_transaction(trans, root, &super);
+       if (ret)
+               goto error;
+       ret = close_ctree(root, &super);
+error:
+       return ret;
+}
 
 int mkfs(int fd, u64 num_blocks, u32 blocksize)
 {
@@ -200,6 +256,9 @@ int main(int ac, char **av)
        int ret;
        int i;
        char *buf = malloc(4096);
+
+       radix_tree_init();
+
        if (ac >= 2) {
                file = av[1];
                if (ac == 3) {
@@ -248,6 +307,11 @@ int main(int ac, char **av)
                fprintf(stderr, "error during mkfs %d\n", ret);
                exit(1);
        }
+       ret = make_root_dir(fd);
+       if (ret) {
+               fprintf(stderr, "failed to setup the root directory\n");
+               exit(1);
+       }
        printf("fs created on %s blocksize %d blocks %Lu\n",
               file, 4096, block_count);
        return 0;
index f53b99d..caa07f5 100644 (file)
@@ -34,9 +34,10 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
                switch (type) {
                case BTRFS_INODE_ITEM_KEY:
                        ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
-                       printf("\t\tinode generation %Lu size %Lu\n",
+                       printf("\t\tinode generation %Lu size %Lu mode %o\n",
                               btrfs_inode_generation(ii),
-                              btrfs_inode_size(ii));
+                              btrfs_inode_size(ii),
+                              btrfs_inode_mode(ii));
                        break;
                case BTRFS_DIR_ITEM_KEY:
                        di = btrfs_item_ptr(l, i, struct btrfs_dir_item);