2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public
4 * License v2 as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * General Public License for more details.
11 * You should have received a copy of the GNU General Public
12 * License along with this program; if not, write to the
13 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14 * Boston, MA 021110-1307, USA.
18 #include <uuid/uuid.h>
22 #include "mkfs/common.h"
23 #include "convert/common.h"
26 * Reserve space from free_tree.
27 * The algorithm is very simple, find the first cache_extent with enough space
28 * and allocate from its beginning.
30 static int reserve_free_space(struct cache_tree *free_tree, u64 len,
33 struct cache_extent *cache;
36 ASSERT(ret_start != NULL);
37 cache = first_cache_extent(free_tree);
39 if (cache->size > len) {
41 *ret_start = cache->start;
44 if (cache->size == 0) {
45 remove_cache_extent(free_tree, cache);
52 cache = next_cache_extent(cache);
59 static inline int write_temp_super(int fd, struct btrfs_super_block *sb,
65 crc = btrfs_csum_data(NULL, (char *)sb + BTRFS_CSUM_SIZE, crc,
66 BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
67 btrfs_csum_final(crc, &sb->csum[0]);
68 ret = pwrite(fd, sb, BTRFS_SUPER_INFO_SIZE, sb_bytenr);
69 if (ret < BTRFS_SUPER_INFO_SIZE)
70 ret = (ret < 0 ? -errno : -EIO);
77 * Setup temporary superblock at cfg->super_bynter
78 * Needed info are extracted from cfg, and root_bytenr, chunk_bytenr
80 * For now sys chunk array will be empty and dev_item is empty too.
81 * They will be re-initialized at temp chunk tree setup.
83 * The superblock signature is not valid, denotes a partially created
84 * filesystem, needs to be finalized.
86 static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
87 u64 root_bytenr, u64 chunk_bytenr)
89 unsigned char chunk_uuid[BTRFS_UUID_SIZE];
90 char super_buf[BTRFS_SUPER_INFO_SIZE];
91 struct btrfs_super_block *super = (struct btrfs_super_block *)super_buf;
94 memset(super_buf, 0, BTRFS_SUPER_INFO_SIZE);
95 cfg->num_bytes = round_down(cfg->num_bytes, cfg->sectorsize);
98 if (uuid_parse(cfg->fs_uuid, super->fsid) != 0) {
99 error("cound not parse UUID: %s", cfg->fs_uuid);
103 if (!test_uuid_unique(cfg->fs_uuid)) {
104 error("non-unique UUID: %s", cfg->fs_uuid);
109 uuid_generate(super->fsid);
110 uuid_unparse(super->fsid, cfg->fs_uuid);
112 uuid_generate(chunk_uuid);
113 uuid_unparse(chunk_uuid, cfg->chunk_uuid);
115 btrfs_set_super_bytenr(super, cfg->super_bytenr);
116 btrfs_set_super_num_devices(super, 1);
117 btrfs_set_super_magic(super, BTRFS_MAGIC_PARTIAL);
118 btrfs_set_super_generation(super, 1);
119 btrfs_set_super_root(super, root_bytenr);
120 btrfs_set_super_chunk_root(super, chunk_bytenr);
121 btrfs_set_super_total_bytes(super, cfg->num_bytes);
123 * Temporary filesystem will only have 6 tree roots:
124 * chunk tree, root tree, extent_tree, device tree, fs tree
127 btrfs_set_super_bytes_used(super, 6 * cfg->nodesize);
128 btrfs_set_super_sectorsize(super, cfg->sectorsize);
129 btrfs_set_super_leafsize(super, cfg->nodesize);
130 btrfs_set_super_nodesize(super, cfg->nodesize);
131 btrfs_set_super_stripesize(super, cfg->stripesize);
132 btrfs_set_super_csum_type(super, BTRFS_CSUM_TYPE_CRC32);
133 btrfs_set_super_chunk_root(super, chunk_bytenr);
134 btrfs_set_super_cache_generation(super, -1);
135 btrfs_set_super_incompat_flags(super, cfg->features);
137 __strncpy_null(super->label, cfg->label, BTRFS_LABEL_SIZE - 1);
139 /* Sys chunk array will be re-initialized at chunk tree init time */
140 super->sys_chunk_array_size = 0;
142 ret = write_temp_super(fd, super, cfg->super_bytenr);
147 static int setup_temp_extent_buffer(struct extent_buffer *buf,
148 struct btrfs_mkfs_config *cfg,
149 u64 bytenr, u64 owner)
151 unsigned char fsid[BTRFS_FSID_SIZE];
152 unsigned char chunk_uuid[BTRFS_UUID_SIZE];
155 ret = uuid_parse(cfg->fs_uuid, fsid);
158 ret = uuid_parse(cfg->chunk_uuid, chunk_uuid);
162 memset(buf->data, 0, cfg->nodesize);
163 buf->len = cfg->nodesize;
164 btrfs_set_header_bytenr(buf, bytenr);
165 btrfs_set_header_generation(buf, 1);
166 btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV);
167 btrfs_set_header_owner(buf, owner);
168 btrfs_set_header_flags(buf, BTRFS_HEADER_FLAG_WRITTEN);
169 write_extent_buffer(buf, chunk_uuid, btrfs_header_chunk_tree_uuid(buf),
171 write_extent_buffer(buf, fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE);
175 static void insert_temp_root_item(struct extent_buffer *buf,
176 struct btrfs_mkfs_config *cfg,
177 int *slot, u32 *itemoff, u64 objectid,
180 struct btrfs_root_item root_item;
181 struct btrfs_inode_item *inode_item;
182 struct btrfs_disk_key disk_key;
184 btrfs_set_header_nritems(buf, *slot + 1);
185 (*itemoff) -= sizeof(root_item);
186 memset(&root_item, 0, sizeof(root_item));
187 inode_item = &root_item.inode;
188 btrfs_set_stack_inode_generation(inode_item, 1);
189 btrfs_set_stack_inode_size(inode_item, 3);
190 btrfs_set_stack_inode_nlink(inode_item, 1);
191 btrfs_set_stack_inode_nbytes(inode_item, cfg->nodesize);
192 btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755);
193 btrfs_set_root_refs(&root_item, 1);
194 btrfs_set_root_used(&root_item, cfg->nodesize);
195 btrfs_set_root_generation(&root_item, 1);
196 btrfs_set_root_bytenr(&root_item, bytenr);
198 memset(&disk_key, 0, sizeof(disk_key));
199 btrfs_set_disk_key_type(&disk_key, BTRFS_ROOT_ITEM_KEY);
200 btrfs_set_disk_key_objectid(&disk_key, objectid);
201 btrfs_set_disk_key_offset(&disk_key, 0);
203 btrfs_set_item_key(buf, &disk_key, *slot);
204 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
205 btrfs_set_item_size(buf, btrfs_item_nr(*slot), sizeof(root_item));
206 write_extent_buffer(buf, &root_item,
207 btrfs_item_ptr_offset(buf, *slot),
213 * Setup an extent buffer for tree block.
215 static inline int write_temp_extent_buffer(int fd, struct extent_buffer *buf,
220 csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
222 /* Temporary extent buffer is always mapped 1:1 on disk */
223 ret = pwrite(fd, buf->data, buf->len, bytenr);
225 ret = (ret < 0 ? ret : -EIO);
231 static int setup_temp_root_tree(int fd, struct btrfs_mkfs_config *cfg,
232 u64 root_bytenr, u64 extent_bytenr,
233 u64 dev_bytenr, u64 fs_bytenr, u64 csum_bytenr)
235 struct extent_buffer *buf = NULL;
236 u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
241 * Provided bytenr must in ascending order, or tree root will have a
244 if (!(root_bytenr < extent_bytenr && extent_bytenr < dev_bytenr &&
245 dev_bytenr < fs_bytenr && fs_bytenr < csum_bytenr)) {
246 error("bad tree bytenr order: "
247 "root < extent %llu < %llu, "
248 "extent < dev %llu < %llu, "
249 "dev < fs %llu < %llu, "
250 "fs < csum %llu < %llu",
251 (unsigned long long)root_bytenr,
252 (unsigned long long)extent_bytenr,
253 (unsigned long long)extent_bytenr,
254 (unsigned long long)dev_bytenr,
255 (unsigned long long)dev_bytenr,
256 (unsigned long long)fs_bytenr,
257 (unsigned long long)fs_bytenr,
258 (unsigned long long)csum_bytenr);
261 buf = malloc(sizeof(*buf) + cfg->nodesize);
265 ret = setup_temp_extent_buffer(buf, cfg, root_bytenr,
266 BTRFS_ROOT_TREE_OBJECTID);
270 insert_temp_root_item(buf, cfg, &slot, &itemoff,
271 BTRFS_EXTENT_TREE_OBJECTID, extent_bytenr);
272 insert_temp_root_item(buf, cfg, &slot, &itemoff,
273 BTRFS_DEV_TREE_OBJECTID, dev_bytenr);
274 insert_temp_root_item(buf, cfg, &slot, &itemoff,
275 BTRFS_FS_TREE_OBJECTID, fs_bytenr);
276 insert_temp_root_item(buf, cfg, &slot, &itemoff,
277 BTRFS_CSUM_TREE_OBJECTID, csum_bytenr);
279 ret = write_temp_extent_buffer(fd, buf, root_bytenr);
285 static int insert_temp_dev_item(int fd, struct extent_buffer *buf,
286 struct btrfs_mkfs_config *cfg,
287 int *slot, u32 *itemoff)
289 struct btrfs_disk_key disk_key;
290 struct btrfs_dev_item *dev_item;
291 char super_buf[BTRFS_SUPER_INFO_SIZE];
292 unsigned char dev_uuid[BTRFS_UUID_SIZE];
293 unsigned char fsid[BTRFS_FSID_SIZE];
294 struct btrfs_super_block *super = (struct btrfs_super_block *)super_buf;
297 ret = pread(fd, super_buf, BTRFS_SUPER_INFO_SIZE, cfg->super_bytenr);
298 if (ret < BTRFS_SUPER_INFO_SIZE) {
299 ret = (ret < 0 ? -errno : -EIO);
303 btrfs_set_header_nritems(buf, *slot + 1);
304 (*itemoff) -= sizeof(*dev_item);
305 /* setup device item 1, 0 is for replace case */
306 btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_ITEM_KEY);
307 btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_ITEMS_OBJECTID);
308 btrfs_set_disk_key_offset(&disk_key, 1);
309 btrfs_set_item_key(buf, &disk_key, *slot);
310 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
311 btrfs_set_item_size(buf, btrfs_item_nr(*slot), sizeof(*dev_item));
313 dev_item = btrfs_item_ptr(buf, *slot, struct btrfs_dev_item);
314 /* Generate device uuid */
315 uuid_generate(dev_uuid);
316 write_extent_buffer(buf, dev_uuid,
317 (unsigned long)btrfs_device_uuid(dev_item),
319 uuid_parse(cfg->fs_uuid, fsid);
320 write_extent_buffer(buf, fsid,
321 (unsigned long)btrfs_device_fsid(dev_item),
323 btrfs_set_device_id(buf, dev_item, 1);
324 btrfs_set_device_generation(buf, dev_item, 0);
325 btrfs_set_device_total_bytes(buf, dev_item, cfg->num_bytes);
327 * The number must match the initial SYSTEM and META chunk size
329 btrfs_set_device_bytes_used(buf, dev_item,
330 BTRFS_MKFS_SYSTEM_GROUP_SIZE +
331 BTRFS_CONVERT_META_GROUP_SIZE);
332 btrfs_set_device_io_align(buf, dev_item, cfg->sectorsize);
333 btrfs_set_device_io_width(buf, dev_item, cfg->sectorsize);
334 btrfs_set_device_sector_size(buf, dev_item, cfg->sectorsize);
335 btrfs_set_device_type(buf, dev_item, 0);
337 /* Super dev_item is not complete, copy the complete one to sb */
338 read_extent_buffer(buf, &super->dev_item, (unsigned long)dev_item,
340 ret = write_temp_super(fd, super, cfg->super_bytenr);
346 static int insert_temp_chunk_item(int fd, struct extent_buffer *buf,
347 struct btrfs_mkfs_config *cfg,
348 int *slot, u32 *itemoff, u64 start, u64 len,
351 struct btrfs_chunk *chunk;
352 struct btrfs_disk_key disk_key;
353 char super_buf[BTRFS_SUPER_INFO_SIZE];
354 struct btrfs_super_block *sb = (struct btrfs_super_block *)super_buf;
357 ret = pread(fd, super_buf, BTRFS_SUPER_INFO_SIZE,
359 if (ret < BTRFS_SUPER_INFO_SIZE) {
360 ret = (ret < 0 ? ret : -EIO);
364 btrfs_set_header_nritems(buf, *slot + 1);
365 (*itemoff) -= btrfs_chunk_item_size(1);
366 btrfs_set_disk_key_type(&disk_key, BTRFS_CHUNK_ITEM_KEY);
367 btrfs_set_disk_key_objectid(&disk_key, BTRFS_FIRST_CHUNK_TREE_OBJECTID);
368 btrfs_set_disk_key_offset(&disk_key, start);
369 btrfs_set_item_key(buf, &disk_key, *slot);
370 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
371 btrfs_set_item_size(buf, btrfs_item_nr(*slot),
372 btrfs_chunk_item_size(1));
374 chunk = btrfs_item_ptr(buf, *slot, struct btrfs_chunk);
375 btrfs_set_chunk_length(buf, chunk, len);
376 btrfs_set_chunk_owner(buf, chunk, BTRFS_EXTENT_TREE_OBJECTID);
377 btrfs_set_chunk_stripe_len(buf, chunk, BTRFS_STRIPE_LEN);
378 btrfs_set_chunk_type(buf, chunk, type);
379 btrfs_set_chunk_io_align(buf, chunk, cfg->sectorsize);
380 btrfs_set_chunk_io_width(buf, chunk, cfg->sectorsize);
381 btrfs_set_chunk_sector_size(buf, chunk, cfg->sectorsize);
382 btrfs_set_chunk_num_stripes(buf, chunk, 1);
383 /* TODO: Support DUP profile for system chunk */
384 btrfs_set_stripe_devid_nr(buf, chunk, 0, 1);
385 /* We are doing 1:1 mapping, so start is its dev offset */
386 btrfs_set_stripe_offset_nr(buf, chunk, 0, start);
387 write_extent_buffer(buf, &sb->dev_item.uuid,
388 (unsigned long)btrfs_stripe_dev_uuid_nr(chunk, 0),
393 * If it's system chunk, also copy it to super block.
395 if (type & BTRFS_BLOCK_GROUP_SYSTEM) {
399 cur = (char *)sb->sys_chunk_array
400 + btrfs_super_sys_array_size(sb);
401 memcpy(cur, &disk_key, sizeof(disk_key));
402 cur += sizeof(disk_key);
403 read_extent_buffer(buf, cur, (unsigned long int)chunk,
404 btrfs_chunk_item_size(1));
405 array_size = btrfs_super_sys_array_size(sb);
406 array_size += btrfs_chunk_item_size(1) +
408 btrfs_set_super_sys_array_size(sb, array_size);
410 ret = write_temp_super(fd, sb, cfg->super_bytenr);
415 static int setup_temp_chunk_tree(int fd, struct btrfs_mkfs_config *cfg,
416 u64 sys_chunk_start, u64 meta_chunk_start,
419 struct extent_buffer *buf = NULL;
420 u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
424 /* Must ensure SYS chunk starts before META chunk */
425 if (meta_chunk_start < sys_chunk_start) {
426 error("wrong chunk order: meta < system %llu < %llu",
427 (unsigned long long)meta_chunk_start,
428 (unsigned long long)sys_chunk_start);
431 buf = malloc(sizeof(*buf) + cfg->nodesize);
434 ret = setup_temp_extent_buffer(buf, cfg, chunk_bytenr,
435 BTRFS_CHUNK_TREE_OBJECTID);
439 ret = insert_temp_dev_item(fd, buf, cfg, &slot, &itemoff);
442 ret = insert_temp_chunk_item(fd, buf, cfg, &slot, &itemoff,
444 BTRFS_MKFS_SYSTEM_GROUP_SIZE,
445 BTRFS_BLOCK_GROUP_SYSTEM);
448 ret = insert_temp_chunk_item(fd, buf, cfg, &slot, &itemoff,
450 BTRFS_CONVERT_META_GROUP_SIZE,
451 BTRFS_BLOCK_GROUP_METADATA);
454 ret = write_temp_extent_buffer(fd, buf, chunk_bytenr);
461 static void insert_temp_dev_extent(struct extent_buffer *buf,
462 int *slot, u32 *itemoff, u64 start, u64 len)
464 struct btrfs_dev_extent *dev_extent;
465 struct btrfs_disk_key disk_key;
467 btrfs_set_header_nritems(buf, *slot + 1);
468 (*itemoff) -= sizeof(*dev_extent);
469 btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_EXTENT_KEY);
470 btrfs_set_disk_key_objectid(&disk_key, 1);
471 btrfs_set_disk_key_offset(&disk_key, start);
472 btrfs_set_item_key(buf, &disk_key, *slot);
473 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
474 btrfs_set_item_size(buf, btrfs_item_nr(*slot), sizeof(*dev_extent));
476 dev_extent = btrfs_item_ptr(buf, *slot, struct btrfs_dev_extent);
477 btrfs_set_dev_extent_chunk_objectid(buf, dev_extent,
478 BTRFS_FIRST_CHUNK_TREE_OBJECTID);
479 btrfs_set_dev_extent_length(buf, dev_extent, len);
480 btrfs_set_dev_extent_chunk_offset(buf, dev_extent, start);
481 btrfs_set_dev_extent_chunk_tree(buf, dev_extent,
482 BTRFS_CHUNK_TREE_OBJECTID);
486 static int setup_temp_dev_tree(int fd, struct btrfs_mkfs_config *cfg,
487 u64 sys_chunk_start, u64 meta_chunk_start,
490 struct extent_buffer *buf = NULL;
491 u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
495 /* Must ensure SYS chunk starts before META chunk */
496 if (meta_chunk_start < sys_chunk_start) {
497 error("wrong chunk order: meta < system %llu < %llu",
498 (unsigned long long)meta_chunk_start,
499 (unsigned long long)sys_chunk_start);
502 buf = malloc(sizeof(*buf) + cfg->nodesize);
505 ret = setup_temp_extent_buffer(buf, cfg, dev_bytenr,
506 BTRFS_DEV_TREE_OBJECTID);
509 insert_temp_dev_extent(buf, &slot, &itemoff, sys_chunk_start,
510 BTRFS_MKFS_SYSTEM_GROUP_SIZE);
511 insert_temp_dev_extent(buf, &slot, &itemoff, meta_chunk_start,
512 BTRFS_CONVERT_META_GROUP_SIZE);
513 ret = write_temp_extent_buffer(fd, buf, dev_bytenr);
519 static int setup_temp_fs_tree(int fd, struct btrfs_mkfs_config *cfg,
522 struct extent_buffer *buf = NULL;
525 buf = malloc(sizeof(*buf) + cfg->nodesize);
528 ret = setup_temp_extent_buffer(buf, cfg, fs_bytenr,
529 BTRFS_FS_TREE_OBJECTID);
533 * Temporary fs tree is completely empty.
535 ret = write_temp_extent_buffer(fd, buf, fs_bytenr);
541 static int setup_temp_csum_tree(int fd, struct btrfs_mkfs_config *cfg,
544 struct extent_buffer *buf = NULL;
547 buf = malloc(sizeof(*buf) + cfg->nodesize);
550 ret = setup_temp_extent_buffer(buf, cfg, csum_bytenr,
551 BTRFS_CSUM_TREE_OBJECTID);
555 * Temporary csum tree is completely empty.
557 ret = write_temp_extent_buffer(fd, buf, csum_bytenr);
564 * Insert one temporary extent item.
566 * NOTE: if skinny_metadata is not enabled, this function must be called
567 * after all other trees are initialized.
568 * Or fs without skinny-metadata will be screwed up.
570 static int insert_temp_extent_item(int fd, struct extent_buffer *buf,
571 struct btrfs_mkfs_config *cfg,
572 int *slot, u32 *itemoff, u64 bytenr,
575 struct extent_buffer *tmp;
576 struct btrfs_extent_item *ei;
577 struct btrfs_extent_inline_ref *iref;
578 struct btrfs_disk_key disk_key;
579 struct btrfs_disk_key tree_info_key;
580 struct btrfs_tree_block_info *info;
582 int skinny_metadata = cfg->features &
583 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA;
587 itemsize = sizeof(*ei) + sizeof(*iref);
589 itemsize = sizeof(*ei) + sizeof(*iref) +
590 sizeof(struct btrfs_tree_block_info);
592 btrfs_set_header_nritems(buf, *slot + 1);
593 *(itemoff) -= itemsize;
595 if (skinny_metadata) {
596 btrfs_set_disk_key_type(&disk_key, BTRFS_METADATA_ITEM_KEY);
597 btrfs_set_disk_key_offset(&disk_key, 0);
599 btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
600 btrfs_set_disk_key_offset(&disk_key, cfg->nodesize);
602 btrfs_set_disk_key_objectid(&disk_key, bytenr);
604 btrfs_set_item_key(buf, &disk_key, *slot);
605 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
606 btrfs_set_item_size(buf, btrfs_item_nr(*slot), itemsize);
608 ei = btrfs_item_ptr(buf, *slot, struct btrfs_extent_item);
609 btrfs_set_extent_refs(buf, ei, 1);
610 btrfs_set_extent_generation(buf, ei, 1);
611 btrfs_set_extent_flags(buf, ei, BTRFS_EXTENT_FLAG_TREE_BLOCK);
613 if (skinny_metadata) {
614 iref = (struct btrfs_extent_inline_ref *)(ei + 1);
616 info = (struct btrfs_tree_block_info *)(ei + 1);
617 iref = (struct btrfs_extent_inline_ref *)(info + 1);
619 btrfs_set_extent_inline_ref_type(buf, iref,
620 BTRFS_TREE_BLOCK_REF_KEY);
621 btrfs_set_extent_inline_ref_offset(buf, iref, ref_root);
628 * Lastly, check the tree block key by read the tree block
629 * Since we do 1:1 mapping for convert case, we can directly
630 * read the bytenr from disk
632 tmp = malloc(sizeof(*tmp) + cfg->nodesize);
635 ret = setup_temp_extent_buffer(tmp, cfg, bytenr, ref_root);
638 ret = pread(fd, tmp->data, cfg->nodesize, bytenr);
639 if (ret < cfg->nodesize) {
640 ret = (ret < 0 ? -errno : -EIO);
643 if (btrfs_header_nritems(tmp) == 0) {
644 btrfs_set_disk_key_type(&tree_info_key, 0);
645 btrfs_set_disk_key_objectid(&tree_info_key, 0);
646 btrfs_set_disk_key_offset(&tree_info_key, 0);
648 btrfs_item_key(tmp, &tree_info_key, 0);
650 btrfs_set_tree_block_key(buf, info, &tree_info_key);
657 static void insert_temp_block_group(struct extent_buffer *buf,
658 struct btrfs_mkfs_config *cfg,
659 int *slot, u32 *itemoff,
660 u64 bytenr, u64 len, u64 used, u64 flag)
662 struct btrfs_block_group_item bgi;
663 struct btrfs_disk_key disk_key;
665 btrfs_set_header_nritems(buf, *slot + 1);
666 (*itemoff) -= sizeof(bgi);
667 btrfs_set_disk_key_type(&disk_key, BTRFS_BLOCK_GROUP_ITEM_KEY);
668 btrfs_set_disk_key_objectid(&disk_key, bytenr);
669 btrfs_set_disk_key_offset(&disk_key, len);
670 btrfs_set_item_key(buf, &disk_key, *slot);
671 btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
672 btrfs_set_item_size(buf, btrfs_item_nr(*slot), sizeof(bgi));
674 btrfs_set_block_group_flags(&bgi, flag);
675 btrfs_set_block_group_used(&bgi, used);
676 btrfs_set_block_group_chunk_objectid(&bgi,
677 BTRFS_FIRST_CHUNK_TREE_OBJECTID);
678 write_extent_buffer(buf, &bgi, btrfs_item_ptr_offset(buf, *slot),
683 static int setup_temp_extent_tree(int fd, struct btrfs_mkfs_config *cfg,
684 u64 chunk_bytenr, u64 root_bytenr,
685 u64 extent_bytenr, u64 dev_bytenr,
686 u64 fs_bytenr, u64 csum_bytenr)
688 struct extent_buffer *buf = NULL;
689 u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
694 * We must ensure provided bytenr are in ascending order,
695 * or extent tree key order will be broken.
697 if (!(chunk_bytenr < root_bytenr && root_bytenr < extent_bytenr &&
698 extent_bytenr < dev_bytenr && dev_bytenr < fs_bytenr &&
699 fs_bytenr < csum_bytenr)) {
700 error("bad tree bytenr order: "
701 "chunk < root %llu < %llu, "
702 "root < extent %llu < %llu, "
703 "extent < dev %llu < %llu, "
704 "dev < fs %llu < %llu, "
705 "fs < csum %llu < %llu",
706 (unsigned long long)chunk_bytenr,
707 (unsigned long long)root_bytenr,
708 (unsigned long long)root_bytenr,
709 (unsigned long long)extent_bytenr,
710 (unsigned long long)extent_bytenr,
711 (unsigned long long)dev_bytenr,
712 (unsigned long long)dev_bytenr,
713 (unsigned long long)fs_bytenr,
714 (unsigned long long)fs_bytenr,
715 (unsigned long long)csum_bytenr);
718 buf = malloc(sizeof(*buf) + cfg->nodesize);
722 ret = setup_temp_extent_buffer(buf, cfg, extent_bytenr,
723 BTRFS_EXTENT_TREE_OBJECTID);
727 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
728 chunk_bytenr, BTRFS_CHUNK_TREE_OBJECTID);
732 insert_temp_block_group(buf, cfg, &slot, &itemoff, chunk_bytenr,
733 BTRFS_MKFS_SYSTEM_GROUP_SIZE, cfg->nodesize,
734 BTRFS_BLOCK_GROUP_SYSTEM);
736 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
737 root_bytenr, BTRFS_ROOT_TREE_OBJECTID);
741 /* 5 tree block used, root, extent, dev, fs and csum*/
742 insert_temp_block_group(buf, cfg, &slot, &itemoff, root_bytenr,
743 BTRFS_CONVERT_META_GROUP_SIZE, cfg->nodesize * 5,
744 BTRFS_BLOCK_GROUP_METADATA);
746 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
747 extent_bytenr, BTRFS_EXTENT_TREE_OBJECTID);
750 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
751 dev_bytenr, BTRFS_DEV_TREE_OBJECTID);
754 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
755 fs_bytenr, BTRFS_FS_TREE_OBJECTID);
758 ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
759 csum_bytenr, BTRFS_CSUM_TREE_OBJECTID);
763 ret = write_temp_extent_buffer(fd, buf, extent_bytenr);
770 * Improved version of make_btrfs().
773 * 1) Do chunk allocation to avoid used data
774 * And after this function, extent type matches chunk type
775 * 2) Better structured code
776 * No super long hand written codes to initialized all tree blocks
777 * Split into small blocks and reuse codes.
778 * TODO: Reuse tree operation facilities by introducing new flags
780 int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
781 struct btrfs_convert_context *cctx)
783 struct cache_tree *free = &cctx->free;
784 struct cache_tree *used = &cctx->used;
786 u64 meta_chunk_start;
787 /* chunk tree bytenr, in system chunk */
789 /* metadata trees bytenr, in metadata chunk */
797 /* Shouldn't happen */
798 BUG_ON(cache_tree_empty(used));
801 * reserve space for temporary superblock first
802 * Here we allocate a little larger space, to keep later
803 * free space will be STRIPE_LEN aligned
805 ret = reserve_free_space(free, BTRFS_STRIPE_LEN,
811 * Then reserve system chunk space
812 * TODO: Change system group size depending on cctx->total_bytes.
813 * If using current 4M, it can only handle less than one TB for
814 * worst case and then run out of sys space.
816 ret = reserve_free_space(free, BTRFS_MKFS_SYSTEM_GROUP_SIZE,
820 ret = reserve_free_space(free, BTRFS_CONVERT_META_GROUP_SIZE,
826 * Allocated meta/sys chunks will be mapped 1:1 with device offset.
828 * Inside the allocated metadata chunk, the layout will be:
829 * | offset | contents |
830 * -------------------------------------
832 * | +nodesize | extent root |
833 * | +nodesize * 2 | device root |
834 * | +nodesize * 3 | fs tree |
835 * | +nodesize * 4 | csum tree |
836 * -------------------------------------
837 * Inside the allocated system chunk, the layout will be:
838 * | offset | contents |
839 * -------------------------------------
840 * | +0 | chunk root |
841 * -------------------------------------
843 chunk_bytenr = sys_chunk_start;
844 root_bytenr = meta_chunk_start;
845 extent_bytenr = meta_chunk_start + cfg->nodesize;
846 dev_bytenr = meta_chunk_start + cfg->nodesize * 2;
847 fs_bytenr = meta_chunk_start + cfg->nodesize * 3;
848 csum_bytenr = meta_chunk_start + cfg->nodesize * 4;
850 ret = setup_temp_super(fd, cfg, root_bytenr, chunk_bytenr);
854 ret = setup_temp_root_tree(fd, cfg, root_bytenr, extent_bytenr,
855 dev_bytenr, fs_bytenr, csum_bytenr);
858 ret = setup_temp_chunk_tree(fd, cfg, sys_chunk_start, meta_chunk_start,
862 ret = setup_temp_dev_tree(fd, cfg, sys_chunk_start, meta_chunk_start,
866 ret = setup_temp_fs_tree(fd, cfg, fs_bytenr);
869 ret = setup_temp_csum_tree(fd, cfg, csum_bytenr);
873 * Setup extent tree last, since it may need to read tree block key
874 * for non-skinny metadata case.
876 ret = setup_temp_extent_tree(fd, cfg, chunk_bytenr, root_bytenr,
877 extent_bytenr, dev_bytenr, fs_bytenr,