dd14ed4fea6c35f6f2077377674415cff5d0d916
[platform/upstream/btrfs-progs.git] / mkfs.c
1 #define _XOPEN_SOURCE 500
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include "kerncompat.h"
9 #include "radix-tree.h"
10 #include "ctree.h"
11 #include "disk-io.h"
12
13 int mkfs(int fd, u64 num_blocks, u16 blocksize)
14 {
15         struct btrfs_super_block super;
16         struct btrfs_leaf empty_leaf;
17         struct btrfs_root_item root_item;
18         struct btrfs_item item;
19         struct btrfs_extent_item extent_item;
20         char *block;
21         int ret;
22         u16 itemoff;
23
24         btrfs_set_super_blocknr(&super, 16);
25         btrfs_set_super_root(&super, 17);
26         strcpy((char *)(&super.magic), BTRFS_MAGIC);
27         btrfs_set_super_blocksize(&super, blocksize);
28         btrfs_set_super_total_blocks(&super, num_blocks);
29         btrfs_set_super_blocks_used(&super, 0);
30
31         block = malloc(blocksize);
32         memset(block, 0, blocksize);
33         BUG_ON(sizeof(super) > blocksize);
34         memcpy(block, &super, sizeof(super));
35         ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET(blocksize));
36         BUG_ON(ret != blocksize);
37
38         /* create the tree of root objects */
39         memset(&empty_leaf, 0, sizeof(empty_leaf));
40         btrfs_set_header_parentid(&empty_leaf.header, BTRFS_ROOT_TREE_OBJECTID);
41         btrfs_set_header_blocknr(&empty_leaf.header, 17);
42         btrfs_set_header_nritems(&empty_leaf.header, 2);
43
44         /* create the items for the root tree */
45         btrfs_set_root_blocknr(&root_item, 18);
46         btrfs_set_root_refs(&root_item, 1);
47         itemoff = LEAF_DATA_SIZE - sizeof(root_item);
48         btrfs_set_item_offset(&item, itemoff);
49         btrfs_set_item_size(&item, sizeof(root_item));
50         btrfs_set_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
51         btrfs_set_key_offset(&item.key, 0);
52         btrfs_set_key_flags(&item.key, 0);
53         memcpy(empty_leaf.items, &item, sizeof(item));
54         memcpy(empty_leaf.data + itemoff, &root_item, sizeof(root_item));
55
56         btrfs_set_root_blocknr(&root_item, 19);
57         itemoff = itemoff - sizeof(root_item);
58         btrfs_set_item_offset(&item, itemoff);
59         btrfs_set_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
60         memcpy(empty_leaf.items + 1, &item, sizeof(item));
61         memcpy(empty_leaf.data + itemoff, &root_item, sizeof(root_item));
62         ret = pwrite(fd, &empty_leaf, blocksize, 17 * blocksize);
63
64         /* create the items for the extent tree */
65         btrfs_set_header_parentid(&empty_leaf.header,
66                                   BTRFS_EXTENT_TREE_OBJECTID);
67         btrfs_set_header_blocknr(&empty_leaf.header, 18);
68         btrfs_set_header_nritems(&empty_leaf.header, 4);
69
70         /* item1, reserve blocks 0-16 */
71         btrfs_set_key_objectid(&item.key, 0);
72         btrfs_set_key_offset(&item.key, 17);
73         btrfs_set_key_flags(&item.key, 0);
74         itemoff = LEAF_DATA_SIZE - sizeof(struct btrfs_extent_item);
75         btrfs_set_item_offset(&item, itemoff);
76         btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
77         btrfs_set_extent_refs(&extent_item, 1);
78         btrfs_set_extent_owner(&extent_item, 0);
79         memcpy(empty_leaf.items, &item, sizeof(item));
80         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
81                 btrfs_item_size(&item));
82
83         /* item2, give block 17 to the root */
84         btrfs_set_key_objectid(&item.key, 17);
85         btrfs_set_key_offset(&item.key, 1);
86         itemoff = itemoff - sizeof(struct btrfs_extent_item);
87         btrfs_set_item_offset(&item, itemoff);
88         btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID);
89         memcpy(empty_leaf.items + 1, &item, sizeof(item));
90         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
91                 btrfs_item_size(&item));
92
93         /* item3, give block 18 to the extent root */
94         btrfs_set_key_objectid(&item.key, 18);
95         btrfs_set_key_offset(&item.key, 1);
96         itemoff = itemoff - sizeof(struct btrfs_extent_item);
97         btrfs_set_item_offset(&item, itemoff);
98         btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID);
99         memcpy(empty_leaf.items + 2, &item, sizeof(item));
100         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
101                 btrfs_item_size(&item));
102
103         /* item4, give block 19 to the FS root */
104         btrfs_set_key_objectid(&item.key, 19);
105         btrfs_set_key_offset(&item.key, 1);
106         itemoff = itemoff - sizeof(struct btrfs_extent_item);
107         btrfs_set_item_offset(&item, itemoff);
108         btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID);
109         memcpy(empty_leaf.items + 3, &item, sizeof(item));
110         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
111                 btrfs_item_size(&item));
112         ret = pwrite(fd, &empty_leaf, blocksize, 18 * blocksize);
113         if (ret != sizeof(empty_leaf))
114                 return -1;
115
116         /* finally create the FS root */
117         btrfs_set_header_parentid(&empty_leaf.header, BTRFS_FS_TREE_OBJECTID);
118         btrfs_set_header_blocknr(&empty_leaf.header, 19);
119         btrfs_set_header_nritems(&empty_leaf.header, 0);
120         ret = pwrite(fd, &empty_leaf, blocksize, 19 * blocksize);
121         if (ret != sizeof(empty_leaf))
122                 return -1;
123         return 0;
124 }
125
126 #if 0
127 int mkfs(int fd)
128 {
129         struct btrfs_root_info info[2];
130         struct btrfs_leaf empty_leaf;
131         struct btrfs_item item;
132         struct btrfs_extent_item extent_item;
133         int ret;
134
135         /* setup the super block area */
136         memset(info, 0, sizeof(info));
137         btrfs_set_root_blocknr(info, 16);
138         btrfs_set_root_objectid(info, 1);
139         btrfs_set_root_tree_root(info, 17);
140
141         btrfs_set_root_blocknr(info + 1, 16);
142         btrfs_set_root_objectid(info + 1, 2);
143         btrfs_set_root_tree_root(info + 1, 18);
144
145         ret = pwrite(fd, info, sizeof(info),
146                      BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE));
147         if (ret != sizeof(info))
148                 return -1;
149
150         /* create leaves for the tree root and extent root */
151         memset(&empty_leaf, 0, sizeof(empty_leaf));
152         btrfs_set_header_parentid(&empty_leaf.header, 1);
153         btrfs_set_header_blocknr(&empty_leaf.header, 17);
154         ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * BTRFS_BLOCKSIZE);
155         if (ret != sizeof(empty_leaf))
156                 return -1;
157
158         btrfs_set_header_parentid(&empty_leaf.header, 2);
159         btrfs_set_header_blocknr(&empty_leaf.header, 18);
160         btrfs_set_header_nritems(&empty_leaf.header, 3);
161
162         /* item1, reserve blocks 0-16 */
163         btrfs_set_key_objectid(&item.key, 0);
164         btrfs_set_key_offset(&item.key, 17);
165         btrfs_set_key_flags(&item.key, 0);
166         btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
167                               sizeof(struct btrfs_extent_item));
168         btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
169         btrfs_set_extent_refs(&extent_item, 1);
170         btrfs_set_extent_owner(&extent_item, 0);
171         memcpy(empty_leaf.items, &item, sizeof(item));
172         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
173                 btrfs_item_size(&item));
174
175         /* item2, give block 17 to the root */
176         btrfs_set_key_objectid(&item.key, 17);
177         btrfs_set_key_offset(&item.key, 1);
178         btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
179                               sizeof(struct btrfs_extent_item) * 2);
180         btrfs_set_extent_owner(&extent_item, 1);
181         memcpy(empty_leaf.items + 1, &item, sizeof(item));
182         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
183                 btrfs_item_size(&item));
184
185         /* item3, give block 18 for the extent root */
186         btrfs_set_key_objectid(&item.key, 18);
187         btrfs_set_key_offset(&item.key, 1);
188         btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
189                               sizeof(struct btrfs_extent_item) * 3);
190         btrfs_set_extent_owner(&extent_item, 2);
191         memcpy(empty_leaf.items + 2, &item, sizeof(item));
192         memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
193                 btrfs_item_size(&item));
194         ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * BTRFS_BLOCKSIZE);
195         if (ret != sizeof(empty_leaf))
196                 return -1;
197         return 0;
198 }
199 #endif