Commit | Line | Data |
---|---|---|
06ed4b31 CM |
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 | ||
3768f368 CM |
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 | |
06ed4b31 CM |
127 | int mkfs(int fd) |
128 | { | |
234b63a0 CM |
129 | struct btrfs_root_info info[2]; |
130 | struct btrfs_leaf empty_leaf; | |
0783fcfc | 131 | struct btrfs_item item; |
234b63a0 | 132 | struct btrfs_extent_item extent_item; |
06ed4b31 CM |
133 | int ret; |
134 | ||
cfaa7295 | 135 | /* setup the super block area */ |
06ed4b31 | 136 | memset(info, 0, sizeof(info)); |
3768f368 CM |
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); | |
06ed4b31 | 144 | |
06ed4b31 | 145 | ret = pwrite(fd, info, sizeof(info), |
234b63a0 | 146 | BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE)); |
06ed4b31 CM |
147 | if (ret != sizeof(info)) |
148 | return -1; | |
cfaa7295 CM |
149 | |
150 | /* create leaves for the tree root and extent root */ | |
06ed4b31 | 151 | memset(&empty_leaf, 0, sizeof(empty_leaf)); |
7518a238 CM |
152 | btrfs_set_header_parentid(&empty_leaf.header, 1); |
153 | btrfs_set_header_blocknr(&empty_leaf.header, 17); | |
234b63a0 | 154 | ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * BTRFS_BLOCKSIZE); |
06ed4b31 CM |
155 | if (ret != sizeof(empty_leaf)) |
156 | return -1; | |
157 | ||
7518a238 CM |
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); | |
9a8dd150 CM |
161 | |
162 | /* item1, reserve blocks 0-16 */ | |
0783fcfc CM |
163 | btrfs_set_key_objectid(&item.key, 0); |
164 | btrfs_set_key_offset(&item.key, 17); | |
165 | btrfs_set_key_flags(&item.key, 0); | |
234b63a0 CM |
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)); | |
cf27e1ee CM |
169 | btrfs_set_extent_refs(&extent_item, 1); |
170 | btrfs_set_extent_owner(&extent_item, 0); | |
06ed4b31 | 171 | memcpy(empty_leaf.items, &item, sizeof(item)); |
0783fcfc CM |
172 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
173 | btrfs_item_size(&item)); | |
9a8dd150 CM |
174 | |
175 | /* item2, give block 17 to the root */ | |
0783fcfc CM |
176 | btrfs_set_key_objectid(&item.key, 17); |
177 | btrfs_set_key_offset(&item.key, 1); | |
234b63a0 CM |
178 | btrfs_set_item_offset(&item, LEAF_DATA_SIZE - |
179 | sizeof(struct btrfs_extent_item) * 2); | |
cf27e1ee | 180 | btrfs_set_extent_owner(&extent_item, 1); |
06ed4b31 | 181 | memcpy(empty_leaf.items + 1, &item, sizeof(item)); |
0783fcfc CM |
182 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
183 | btrfs_item_size(&item)); | |
9a8dd150 CM |
184 | |
185 | /* item3, give block 18 for the extent root */ | |
0783fcfc CM |
186 | btrfs_set_key_objectid(&item.key, 18); |
187 | btrfs_set_key_offset(&item.key, 1); | |
234b63a0 CM |
188 | btrfs_set_item_offset(&item, LEAF_DATA_SIZE - |
189 | sizeof(struct btrfs_extent_item) * 3); | |
cf27e1ee | 190 | btrfs_set_extent_owner(&extent_item, 2); |
9a8dd150 | 191 | memcpy(empty_leaf.items + 2, &item, sizeof(item)); |
0783fcfc CM |
192 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
193 | btrfs_item_size(&item)); | |
234b63a0 | 194 | ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * BTRFS_BLOCKSIZE); |
06ed4b31 CM |
195 | if (ret != sizeof(empty_leaf)) |
196 | return -1; | |
197 | return 0; | |
198 | } | |
3768f368 | 199 | #endif |