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"
25 #define BTRFS_CONVERT_META_GROUP_SIZE SZ_32M
28 * Reserve space from free_tree.
29 * The algorithm is very simple, find the first cache_extent with enough space
30 * and allocate from its beginning.
32 static int reserve_free_space(struct cache_tree
*free_tree
, u64 len
,
35 struct cache_extent
*cache
;
38 ASSERT(ret_start
!= NULL
);
39 cache
= first_cache_extent(free_tree
);
41 if (cache
->size
> len
) {
43 *ret_start
= cache
->start
;
46 if (cache
->size
== 0) {
47 remove_cache_extent(free_tree
, cache
);
54 cache
= next_cache_extent(cache
);
61 static inline int write_temp_super(int fd
, struct btrfs_super_block
*sb
,
67 crc
= btrfs_csum_data((char *)sb
+ BTRFS_CSUM_SIZE
, crc
,
68 BTRFS_SUPER_INFO_SIZE
- BTRFS_CSUM_SIZE
);
69 btrfs_csum_final(crc
, &sb
->csum
[0]);
70 ret
= pwrite(fd
, sb
, BTRFS_SUPER_INFO_SIZE
, sb_bytenr
);
71 if (ret
< BTRFS_SUPER_INFO_SIZE
)
72 ret
= (ret
< 0 ? -errno
: -EIO
);
79 * Setup temporary superblock at cfg->super_bynter
80 * Needed info are extracted from cfg, and root_bytenr, chunk_bytenr
82 * For now sys chunk array will be empty and dev_item is empty too.
83 * They will be re-initialized at temp chunk tree setup.
85 * The superblock signature is not valid, denotes a partially created
86 * filesystem, needs to be finalized.
88 static int setup_temp_super(int fd
, struct btrfs_mkfs_config
*cfg
,
89 u64 root_bytenr
, u64 chunk_bytenr
)
91 unsigned char chunk_uuid
[BTRFS_UUID_SIZE
];
92 char super_buf
[BTRFS_SUPER_INFO_SIZE
];
93 struct btrfs_super_block
*super
= (struct btrfs_super_block
*)super_buf
;
96 memset(super_buf
, 0, BTRFS_SUPER_INFO_SIZE
);
97 cfg
->num_bytes
= round_down(cfg
->num_bytes
, cfg
->sectorsize
);
100 if (uuid_parse(cfg
->fs_uuid
, super
->fsid
) != 0) {
101 error("cound not parse UUID: %s", cfg
->fs_uuid
);
105 if (!test_uuid_unique(cfg
->fs_uuid
)) {
106 error("non-unique UUID: %s", cfg
->fs_uuid
);
111 uuid_generate(super
->fsid
);
112 uuid_unparse(super
->fsid
, cfg
->fs_uuid
);
114 uuid_generate(chunk_uuid
);
115 uuid_unparse(chunk_uuid
, cfg
->chunk_uuid
);
117 btrfs_set_super_bytenr(super
, cfg
->super_bytenr
);
118 btrfs_set_super_num_devices(super
, 1);
119 btrfs_set_super_magic(super
, BTRFS_MAGIC_TEMPORARY
);
120 btrfs_set_super_generation(super
, 1);
121 btrfs_set_super_root(super
, root_bytenr
);
122 btrfs_set_super_chunk_root(super
, chunk_bytenr
);
123 btrfs_set_super_total_bytes(super
, cfg
->num_bytes
);
125 * Temporary filesystem will only have 6 tree roots:
126 * chunk tree, root tree, extent_tree, device tree, fs tree
129 btrfs_set_super_bytes_used(super
, 6 * cfg
->nodesize
);
130 btrfs_set_super_sectorsize(super
, cfg
->sectorsize
);
131 super
->__unused_leafsize
= cpu_to_le32(cfg
->nodesize
);
132 btrfs_set_super_nodesize(super
, cfg
->nodesize
);
133 btrfs_set_super_stripesize(super
, cfg
->stripesize
);
134 btrfs_set_super_csum_type(super
, BTRFS_CSUM_TYPE_CRC32
);
135 btrfs_set_super_chunk_root(super
, chunk_bytenr
);
136 btrfs_set_super_cache_generation(super
, -1);
137 btrfs_set_super_incompat_flags(super
, cfg
->features
);
139 __strncpy_null(super
->label
, cfg
->label
, BTRFS_LABEL_SIZE
- 1);
141 /* Sys chunk array will be re-initialized at chunk tree init time */
142 super
->sys_chunk_array_size
= 0;
144 ret
= write_temp_super(fd
, super
, cfg
->super_bytenr
);
149 static int setup_temp_extent_buffer(struct extent_buffer
*buf
,
150 struct btrfs_mkfs_config
*cfg
,
151 u64 bytenr
, u64 owner
)
153 unsigned char fsid
[BTRFS_FSID_SIZE
];
154 unsigned char chunk_uuid
[BTRFS_UUID_SIZE
];
157 ret
= uuid_parse(cfg
->fs_uuid
, fsid
);
160 ret
= uuid_parse(cfg
->chunk_uuid
, chunk_uuid
);
164 memset(buf
->data
, 0, cfg
->nodesize
);
165 buf
->len
= cfg
->nodesize
;
166 btrfs_set_header_bytenr(buf
, bytenr
);
167 btrfs_set_header_generation(buf
, 1);
168 btrfs_set_header_backref_rev(buf
, BTRFS_MIXED_BACKREF_REV
);
169 btrfs_set_header_owner(buf
, owner
);
170 btrfs_set_header_flag(buf
, BTRFS_HEADER_FLAG_WRITTEN
);
171 write_extent_buffer(buf
, chunk_uuid
, btrfs_header_chunk_tree_uuid(buf
),
173 write_extent_buffer(buf
, fsid
, btrfs_header_fsid(), BTRFS_FSID_SIZE
);
177 static void insert_temp_root_item(struct extent_buffer
*buf
,
178 struct btrfs_mkfs_config
*cfg
,
179 int *slot
, u32
*itemoff
, u64 objectid
,
182 struct btrfs_root_item root_item
;
183 struct btrfs_inode_item
*inode_item
;
184 struct btrfs_disk_key disk_key
;
186 btrfs_set_header_nritems(buf
, *slot
+ 1);
187 (*itemoff
) -= sizeof(root_item
);
188 memset(&root_item
, 0, sizeof(root_item
));
189 inode_item
= &root_item
.inode
;
190 btrfs_set_stack_inode_generation(inode_item
, 1);
191 btrfs_set_stack_inode_size(inode_item
, 3);
192 btrfs_set_stack_inode_nlink(inode_item
, 1);
193 btrfs_set_stack_inode_nbytes(inode_item
, cfg
->nodesize
);
194 btrfs_set_stack_inode_mode(inode_item
, S_IFDIR
| 0755);
195 btrfs_set_root_refs(&root_item
, 1);
196 btrfs_set_root_used(&root_item
, cfg
->nodesize
);
197 btrfs_set_root_generation(&root_item
, 1);
198 btrfs_set_root_bytenr(&root_item
, bytenr
);
200 memset(&disk_key
, 0, sizeof(disk_key
));
201 btrfs_set_disk_key_type(&disk_key
, BTRFS_ROOT_ITEM_KEY
);
202 btrfs_set_disk_key_objectid(&disk_key
, objectid
);
203 btrfs_set_disk_key_offset(&disk_key
, 0);
205 btrfs_set_item_key(buf
, &disk_key
, *slot
);
206 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
207 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
), sizeof(root_item
));
208 write_extent_buffer(buf
, &root_item
,
209 btrfs_item_ptr_offset(buf
, *slot
),
215 * Setup an extent buffer for tree block.
217 static inline int write_temp_extent_buffer(int fd
, struct extent_buffer
*buf
,
222 csum_tree_block_size(buf
, btrfs_csum_sizes
[BTRFS_CSUM_TYPE_CRC32
], 0);
224 /* Temporary extent buffer is always mapped 1:1 on disk */
225 ret
= pwrite(fd
, buf
->data
, buf
->len
, bytenr
);
227 ret
= (ret
< 0 ? ret
: -EIO
);
233 static int setup_temp_root_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
234 u64 root_bytenr
, u64 extent_bytenr
,
235 u64 dev_bytenr
, u64 fs_bytenr
, u64 csum_bytenr
)
237 struct extent_buffer
*buf
= NULL
;
238 u32 itemoff
= __BTRFS_LEAF_DATA_SIZE(cfg
->nodesize
);
243 * Provided bytenr must in ascending order, or tree root will have a
246 if (!(root_bytenr
< extent_bytenr
&& extent_bytenr
< dev_bytenr
&&
247 dev_bytenr
< fs_bytenr
&& fs_bytenr
< csum_bytenr
)) {
248 error("bad tree bytenr order: "
249 "root < extent %llu < %llu, "
250 "extent < dev %llu < %llu, "
251 "dev < fs %llu < %llu, "
252 "fs < csum %llu < %llu",
253 (unsigned long long)root_bytenr
,
254 (unsigned long long)extent_bytenr
,
255 (unsigned long long)extent_bytenr
,
256 (unsigned long long)dev_bytenr
,
257 (unsigned long long)dev_bytenr
,
258 (unsigned long long)fs_bytenr
,
259 (unsigned long long)fs_bytenr
,
260 (unsigned long long)csum_bytenr
);
263 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
267 ret
= setup_temp_extent_buffer(buf
, cfg
, root_bytenr
,
268 BTRFS_ROOT_TREE_OBJECTID
);
272 insert_temp_root_item(buf
, cfg
, &slot
, &itemoff
,
273 BTRFS_EXTENT_TREE_OBJECTID
, extent_bytenr
);
274 insert_temp_root_item(buf
, cfg
, &slot
, &itemoff
,
275 BTRFS_DEV_TREE_OBJECTID
, dev_bytenr
);
276 insert_temp_root_item(buf
, cfg
, &slot
, &itemoff
,
277 BTRFS_FS_TREE_OBJECTID
, fs_bytenr
);
278 insert_temp_root_item(buf
, cfg
, &slot
, &itemoff
,
279 BTRFS_CSUM_TREE_OBJECTID
, csum_bytenr
);
281 ret
= write_temp_extent_buffer(fd
, buf
, root_bytenr
);
287 static int insert_temp_dev_item(int fd
, struct extent_buffer
*buf
,
288 struct btrfs_mkfs_config
*cfg
,
289 int *slot
, u32
*itemoff
)
291 struct btrfs_disk_key disk_key
;
292 struct btrfs_dev_item
*dev_item
;
293 char super_buf
[BTRFS_SUPER_INFO_SIZE
];
294 unsigned char dev_uuid
[BTRFS_UUID_SIZE
];
295 unsigned char fsid
[BTRFS_FSID_SIZE
];
296 struct btrfs_super_block
*super
= (struct btrfs_super_block
*)super_buf
;
299 ret
= pread(fd
, super_buf
, BTRFS_SUPER_INFO_SIZE
, cfg
->super_bytenr
);
300 if (ret
< BTRFS_SUPER_INFO_SIZE
) {
301 ret
= (ret
< 0 ? -errno
: -EIO
);
305 btrfs_set_header_nritems(buf
, *slot
+ 1);
306 (*itemoff
) -= sizeof(*dev_item
);
307 /* setup device item 1, 0 is for replace case */
308 btrfs_set_disk_key_type(&disk_key
, BTRFS_DEV_ITEM_KEY
);
309 btrfs_set_disk_key_objectid(&disk_key
, BTRFS_DEV_ITEMS_OBJECTID
);
310 btrfs_set_disk_key_offset(&disk_key
, 1);
311 btrfs_set_item_key(buf
, &disk_key
, *slot
);
312 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
313 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
), sizeof(*dev_item
));
315 dev_item
= btrfs_item_ptr(buf
, *slot
, struct btrfs_dev_item
);
316 /* Generate device uuid */
317 uuid_generate(dev_uuid
);
318 write_extent_buffer(buf
, dev_uuid
,
319 (unsigned long)btrfs_device_uuid(dev_item
),
321 uuid_parse(cfg
->fs_uuid
, fsid
);
322 write_extent_buffer(buf
, fsid
,
323 (unsigned long)btrfs_device_fsid(dev_item
),
325 btrfs_set_device_id(buf
, dev_item
, 1);
326 btrfs_set_device_generation(buf
, dev_item
, 0);
327 btrfs_set_device_total_bytes(buf
, dev_item
, cfg
->num_bytes
);
329 * The number must match the initial SYSTEM and META chunk size
331 btrfs_set_device_bytes_used(buf
, dev_item
,
332 BTRFS_MKFS_SYSTEM_GROUP_SIZE
+
333 BTRFS_CONVERT_META_GROUP_SIZE
);
334 btrfs_set_device_io_align(buf
, dev_item
, cfg
->sectorsize
);
335 btrfs_set_device_io_width(buf
, dev_item
, cfg
->sectorsize
);
336 btrfs_set_device_sector_size(buf
, dev_item
, cfg
->sectorsize
);
337 btrfs_set_device_type(buf
, dev_item
, 0);
339 /* Super dev_item is not complete, copy the complete one to sb */
340 read_extent_buffer(buf
, &super
->dev_item
, (unsigned long)dev_item
,
342 ret
= write_temp_super(fd
, super
, cfg
->super_bytenr
);
348 static int insert_temp_chunk_item(int fd
, struct extent_buffer
*buf
,
349 struct btrfs_mkfs_config
*cfg
,
350 int *slot
, u32
*itemoff
, u64 start
, u64 len
,
353 struct btrfs_chunk
*chunk
;
354 struct btrfs_disk_key disk_key
;
355 char super_buf
[BTRFS_SUPER_INFO_SIZE
];
356 struct btrfs_super_block
*sb
= (struct btrfs_super_block
*)super_buf
;
359 ret
= pread(fd
, super_buf
, BTRFS_SUPER_INFO_SIZE
,
361 if (ret
< BTRFS_SUPER_INFO_SIZE
) {
362 ret
= (ret
< 0 ? ret
: -EIO
);
366 btrfs_set_header_nritems(buf
, *slot
+ 1);
367 (*itemoff
) -= btrfs_chunk_item_size(1);
368 btrfs_set_disk_key_type(&disk_key
, BTRFS_CHUNK_ITEM_KEY
);
369 btrfs_set_disk_key_objectid(&disk_key
, BTRFS_FIRST_CHUNK_TREE_OBJECTID
);
370 btrfs_set_disk_key_offset(&disk_key
, start
);
371 btrfs_set_item_key(buf
, &disk_key
, *slot
);
372 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
373 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
),
374 btrfs_chunk_item_size(1));
376 chunk
= btrfs_item_ptr(buf
, *slot
, struct btrfs_chunk
);
377 btrfs_set_chunk_length(buf
, chunk
, len
);
378 btrfs_set_chunk_owner(buf
, chunk
, BTRFS_EXTENT_TREE_OBJECTID
);
379 btrfs_set_chunk_stripe_len(buf
, chunk
, BTRFS_STRIPE_LEN
);
380 btrfs_set_chunk_type(buf
, chunk
, type
);
381 btrfs_set_chunk_io_align(buf
, chunk
, cfg
->sectorsize
);
382 btrfs_set_chunk_io_width(buf
, chunk
, cfg
->sectorsize
);
383 btrfs_set_chunk_sector_size(buf
, chunk
, cfg
->sectorsize
);
384 btrfs_set_chunk_num_stripes(buf
, chunk
, 1);
385 /* TODO: Support DUP profile for system chunk */
386 btrfs_set_stripe_devid_nr(buf
, chunk
, 0, 1);
387 /* We are doing 1:1 mapping, so start is its dev offset */
388 btrfs_set_stripe_offset_nr(buf
, chunk
, 0, start
);
389 write_extent_buffer(buf
, &sb
->dev_item
.uuid
,
390 (unsigned long)btrfs_stripe_dev_uuid_nr(chunk
, 0),
395 * If it's system chunk, also copy it to super block.
397 if (type
& BTRFS_BLOCK_GROUP_SYSTEM
) {
401 cur
= (char *)sb
->sys_chunk_array
402 + btrfs_super_sys_array_size(sb
);
403 memcpy(cur
, &disk_key
, sizeof(disk_key
));
404 cur
+= sizeof(disk_key
);
405 read_extent_buffer(buf
, cur
, (unsigned long int)chunk
,
406 btrfs_chunk_item_size(1));
407 array_size
= btrfs_super_sys_array_size(sb
);
408 array_size
+= btrfs_chunk_item_size(1) +
410 btrfs_set_super_sys_array_size(sb
, array_size
);
412 ret
= write_temp_super(fd
, sb
, cfg
->super_bytenr
);
417 static int setup_temp_chunk_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
418 u64 sys_chunk_start
, u64 meta_chunk_start
,
421 struct extent_buffer
*buf
= NULL
;
422 u32 itemoff
= __BTRFS_LEAF_DATA_SIZE(cfg
->nodesize
);
426 /* Must ensure SYS chunk starts before META chunk */
427 if (meta_chunk_start
< sys_chunk_start
) {
428 error("wrong chunk order: meta < system %llu < %llu",
429 (unsigned long long)meta_chunk_start
,
430 (unsigned long long)sys_chunk_start
);
433 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
436 ret
= setup_temp_extent_buffer(buf
, cfg
, chunk_bytenr
,
437 BTRFS_CHUNK_TREE_OBJECTID
);
441 ret
= insert_temp_dev_item(fd
, buf
, cfg
, &slot
, &itemoff
);
444 ret
= insert_temp_chunk_item(fd
, buf
, cfg
, &slot
, &itemoff
,
446 BTRFS_MKFS_SYSTEM_GROUP_SIZE
,
447 BTRFS_BLOCK_GROUP_SYSTEM
);
450 ret
= insert_temp_chunk_item(fd
, buf
, cfg
, &slot
, &itemoff
,
452 BTRFS_CONVERT_META_GROUP_SIZE
,
453 BTRFS_BLOCK_GROUP_METADATA
);
456 ret
= write_temp_extent_buffer(fd
, buf
, chunk_bytenr
);
463 static void insert_temp_dev_extent(struct extent_buffer
*buf
,
464 int *slot
, u32
*itemoff
, u64 start
, u64 len
)
466 struct btrfs_dev_extent
*dev_extent
;
467 struct btrfs_disk_key disk_key
;
469 btrfs_set_header_nritems(buf
, *slot
+ 1);
470 (*itemoff
) -= sizeof(*dev_extent
);
471 btrfs_set_disk_key_type(&disk_key
, BTRFS_DEV_EXTENT_KEY
);
472 btrfs_set_disk_key_objectid(&disk_key
, 1);
473 btrfs_set_disk_key_offset(&disk_key
, start
);
474 btrfs_set_item_key(buf
, &disk_key
, *slot
);
475 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
476 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
), sizeof(*dev_extent
));
478 dev_extent
= btrfs_item_ptr(buf
, *slot
, struct btrfs_dev_extent
);
479 btrfs_set_dev_extent_chunk_objectid(buf
, dev_extent
,
480 BTRFS_FIRST_CHUNK_TREE_OBJECTID
);
481 btrfs_set_dev_extent_length(buf
, dev_extent
, len
);
482 btrfs_set_dev_extent_chunk_offset(buf
, dev_extent
, start
);
483 btrfs_set_dev_extent_chunk_tree(buf
, dev_extent
,
484 BTRFS_CHUNK_TREE_OBJECTID
);
488 static int setup_temp_dev_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
489 u64 sys_chunk_start
, u64 meta_chunk_start
,
492 struct extent_buffer
*buf
= NULL
;
493 u32 itemoff
= __BTRFS_LEAF_DATA_SIZE(cfg
->nodesize
);
497 /* Must ensure SYS chunk starts before META chunk */
498 if (meta_chunk_start
< sys_chunk_start
) {
499 error("wrong chunk order: meta < system %llu < %llu",
500 (unsigned long long)meta_chunk_start
,
501 (unsigned long long)sys_chunk_start
);
504 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
507 ret
= setup_temp_extent_buffer(buf
, cfg
, dev_bytenr
,
508 BTRFS_DEV_TREE_OBJECTID
);
511 insert_temp_dev_extent(buf
, &slot
, &itemoff
, sys_chunk_start
,
512 BTRFS_MKFS_SYSTEM_GROUP_SIZE
);
513 insert_temp_dev_extent(buf
, &slot
, &itemoff
, meta_chunk_start
,
514 BTRFS_CONVERT_META_GROUP_SIZE
);
515 ret
= write_temp_extent_buffer(fd
, buf
, dev_bytenr
);
521 static int setup_temp_fs_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
524 struct extent_buffer
*buf
= NULL
;
527 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
530 ret
= setup_temp_extent_buffer(buf
, cfg
, fs_bytenr
,
531 BTRFS_FS_TREE_OBJECTID
);
535 * Temporary fs tree is completely empty.
537 ret
= write_temp_extent_buffer(fd
, buf
, fs_bytenr
);
543 static int setup_temp_csum_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
546 struct extent_buffer
*buf
= NULL
;
549 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
552 ret
= setup_temp_extent_buffer(buf
, cfg
, csum_bytenr
,
553 BTRFS_CSUM_TREE_OBJECTID
);
557 * Temporary csum tree is completely empty.
559 ret
= write_temp_extent_buffer(fd
, buf
, csum_bytenr
);
566 * Insert one temporary extent item.
568 * NOTE: if skinny_metadata is not enabled, this function must be called
569 * after all other trees are initialized.
570 * Or fs without skinny-metadata will be screwed up.
572 static int insert_temp_extent_item(int fd
, struct extent_buffer
*buf
,
573 struct btrfs_mkfs_config
*cfg
,
574 int *slot
, u32
*itemoff
, u64 bytenr
,
577 struct extent_buffer
*tmp
;
578 struct btrfs_extent_item
*ei
;
579 struct btrfs_extent_inline_ref
*iref
;
580 struct btrfs_disk_key disk_key
;
581 struct btrfs_disk_key tree_info_key
;
582 struct btrfs_tree_block_info
*info
;
584 int skinny_metadata
= cfg
->features
&
585 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA
;
589 itemsize
= sizeof(*ei
) + sizeof(*iref
);
591 itemsize
= sizeof(*ei
) + sizeof(*iref
) +
592 sizeof(struct btrfs_tree_block_info
);
594 btrfs_set_header_nritems(buf
, *slot
+ 1);
595 *(itemoff
) -= itemsize
;
597 if (skinny_metadata
) {
598 btrfs_set_disk_key_type(&disk_key
, BTRFS_METADATA_ITEM_KEY
);
599 btrfs_set_disk_key_offset(&disk_key
, 0);
601 btrfs_set_disk_key_type(&disk_key
, BTRFS_EXTENT_ITEM_KEY
);
602 btrfs_set_disk_key_offset(&disk_key
, cfg
->nodesize
);
604 btrfs_set_disk_key_objectid(&disk_key
, bytenr
);
606 btrfs_set_item_key(buf
, &disk_key
, *slot
);
607 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
608 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
), itemsize
);
610 ei
= btrfs_item_ptr(buf
, *slot
, struct btrfs_extent_item
);
611 btrfs_set_extent_refs(buf
, ei
, 1);
612 btrfs_set_extent_generation(buf
, ei
, 1);
613 btrfs_set_extent_flags(buf
, ei
, BTRFS_EXTENT_FLAG_TREE_BLOCK
);
615 if (skinny_metadata
) {
616 iref
= (struct btrfs_extent_inline_ref
*)(ei
+ 1);
618 info
= (struct btrfs_tree_block_info
*)(ei
+ 1);
619 iref
= (struct btrfs_extent_inline_ref
*)(info
+ 1);
621 btrfs_set_extent_inline_ref_type(buf
, iref
,
622 BTRFS_TREE_BLOCK_REF_KEY
);
623 btrfs_set_extent_inline_ref_offset(buf
, iref
, ref_root
);
630 * Lastly, check the tree block key by read the tree block
631 * Since we do 1:1 mapping for convert case, we can directly
632 * read the bytenr from disk
634 tmp
= malloc(sizeof(*tmp
) + cfg
->nodesize
);
637 ret
= setup_temp_extent_buffer(tmp
, cfg
, bytenr
, ref_root
);
640 ret
= pread(fd
, tmp
->data
, cfg
->nodesize
, bytenr
);
641 if (ret
< cfg
->nodesize
) {
642 ret
= (ret
< 0 ? -errno
: -EIO
);
645 if (btrfs_header_nritems(tmp
) == 0) {
646 btrfs_set_disk_key_type(&tree_info_key
, 0);
647 btrfs_set_disk_key_objectid(&tree_info_key
, 0);
648 btrfs_set_disk_key_offset(&tree_info_key
, 0);
650 btrfs_item_key(tmp
, &tree_info_key
, 0);
652 btrfs_set_tree_block_key(buf
, info
, &tree_info_key
);
659 static void insert_temp_block_group(struct extent_buffer
*buf
,
660 struct btrfs_mkfs_config
*cfg
,
661 int *slot
, u32
*itemoff
,
662 u64 bytenr
, u64 len
, u64 used
, u64 flag
)
664 struct btrfs_block_group_item bgi
;
665 struct btrfs_disk_key disk_key
;
667 btrfs_set_header_nritems(buf
, *slot
+ 1);
668 (*itemoff
) -= sizeof(bgi
);
669 btrfs_set_disk_key_type(&disk_key
, BTRFS_BLOCK_GROUP_ITEM_KEY
);
670 btrfs_set_disk_key_objectid(&disk_key
, bytenr
);
671 btrfs_set_disk_key_offset(&disk_key
, len
);
672 btrfs_set_item_key(buf
, &disk_key
, *slot
);
673 btrfs_set_item_offset(buf
, btrfs_item_nr(*slot
), *itemoff
);
674 btrfs_set_item_size(buf
, btrfs_item_nr(*slot
), sizeof(bgi
));
676 btrfs_set_block_group_flags(&bgi
, flag
);
677 btrfs_set_block_group_used(&bgi
, used
);
678 btrfs_set_block_group_chunk_objectid(&bgi
,
679 BTRFS_FIRST_CHUNK_TREE_OBJECTID
);
680 write_extent_buffer(buf
, &bgi
, btrfs_item_ptr_offset(buf
, *slot
),
685 static int setup_temp_extent_tree(int fd
, struct btrfs_mkfs_config
*cfg
,
686 u64 chunk_bytenr
, u64 root_bytenr
,
687 u64 extent_bytenr
, u64 dev_bytenr
,
688 u64 fs_bytenr
, u64 csum_bytenr
)
690 struct extent_buffer
*buf
= NULL
;
691 u32 itemoff
= __BTRFS_LEAF_DATA_SIZE(cfg
->nodesize
);
696 * We must ensure provided bytenr are in ascending order,
697 * or extent tree key order will be broken.
699 if (!(chunk_bytenr
< root_bytenr
&& root_bytenr
< extent_bytenr
&&
700 extent_bytenr
< dev_bytenr
&& dev_bytenr
< fs_bytenr
&&
701 fs_bytenr
< csum_bytenr
)) {
702 error("bad tree bytenr order: "
703 "chunk < root %llu < %llu, "
704 "root < extent %llu < %llu, "
705 "extent < dev %llu < %llu, "
706 "dev < fs %llu < %llu, "
707 "fs < csum %llu < %llu",
708 (unsigned long long)chunk_bytenr
,
709 (unsigned long long)root_bytenr
,
710 (unsigned long long)root_bytenr
,
711 (unsigned long long)extent_bytenr
,
712 (unsigned long long)extent_bytenr
,
713 (unsigned long long)dev_bytenr
,
714 (unsigned long long)dev_bytenr
,
715 (unsigned long long)fs_bytenr
,
716 (unsigned long long)fs_bytenr
,
717 (unsigned long long)csum_bytenr
);
720 buf
= malloc(sizeof(*buf
) + cfg
->nodesize
);
724 ret
= setup_temp_extent_buffer(buf
, cfg
, extent_bytenr
,
725 BTRFS_EXTENT_TREE_OBJECTID
);
729 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
730 chunk_bytenr
, BTRFS_CHUNK_TREE_OBJECTID
);
734 insert_temp_block_group(buf
, cfg
, &slot
, &itemoff
, chunk_bytenr
,
735 BTRFS_MKFS_SYSTEM_GROUP_SIZE
, cfg
->nodesize
,
736 BTRFS_BLOCK_GROUP_SYSTEM
);
738 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
739 root_bytenr
, BTRFS_ROOT_TREE_OBJECTID
);
743 /* 5 tree block used, root, extent, dev, fs and csum*/
744 insert_temp_block_group(buf
, cfg
, &slot
, &itemoff
, root_bytenr
,
745 BTRFS_CONVERT_META_GROUP_SIZE
, cfg
->nodesize
* 5,
746 BTRFS_BLOCK_GROUP_METADATA
);
748 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
749 extent_bytenr
, BTRFS_EXTENT_TREE_OBJECTID
);
752 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
753 dev_bytenr
, BTRFS_DEV_TREE_OBJECTID
);
756 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
757 fs_bytenr
, BTRFS_FS_TREE_OBJECTID
);
760 ret
= insert_temp_extent_item(fd
, buf
, cfg
, &slot
, &itemoff
,
761 csum_bytenr
, BTRFS_CSUM_TREE_OBJECTID
);
765 ret
= write_temp_extent_buffer(fd
, buf
, extent_bytenr
);
772 * Improved version of make_btrfs().
775 * 1) Do chunk allocation to avoid used data
776 * And after this function, extent type matches chunk type
777 * 2) Better structured code
778 * No super long hand written codes to initialized all tree blocks
779 * Split into small blocks and reuse codes.
780 * TODO: Reuse tree operation facilities by introducing new flags
782 int make_convert_btrfs(int fd
, struct btrfs_mkfs_config
*cfg
,
783 struct btrfs_convert_context
*cctx
)
785 struct cache_tree
*free_space
= &cctx
->free_space
;
786 struct cache_tree
*used_space
= &cctx
->used_space
;
788 u64 meta_chunk_start
;
789 /* chunk tree bytenr, in system chunk */
791 /* metadata trees bytenr, in metadata chunk */
799 /* Source filesystem must be opened, checked and analyzed in advance */
800 ASSERT(!cache_tree_empty(used_space
));
803 * reserve space for temporary superblock first
804 * Here we allocate a little larger space, to keep later
805 * free space will be STRIPE_LEN aligned
807 ret
= reserve_free_space(free_space
, BTRFS_STRIPE_LEN
,
813 * Then reserve system chunk space
814 * TODO: Change system group size depending on cctx->total_bytes.
815 * If using current 4M, it can only handle less than one TB for
816 * worst case and then run out of sys space.
818 ret
= reserve_free_space(free_space
, BTRFS_MKFS_SYSTEM_GROUP_SIZE
,
822 ret
= reserve_free_space(free_space
, BTRFS_CONVERT_META_GROUP_SIZE
,
828 * Allocated meta/sys chunks will be mapped 1:1 with device offset.
830 * Inside the allocated metadata chunk, the layout will be:
831 * | offset | contents |
832 * -------------------------------------
834 * | +nodesize | extent root |
835 * | +nodesize * 2 | device root |
836 * | +nodesize * 3 | fs tree |
837 * | +nodesize * 4 | csum tree |
838 * -------------------------------------
839 * Inside the allocated system chunk, the layout will be:
840 * | offset | contents |
841 * -------------------------------------
842 * | +0 | chunk root |
843 * -------------------------------------
845 chunk_bytenr
= sys_chunk_start
;
846 root_bytenr
= meta_chunk_start
;
847 extent_bytenr
= meta_chunk_start
+ cfg
->nodesize
;
848 dev_bytenr
= meta_chunk_start
+ cfg
->nodesize
* 2;
849 fs_bytenr
= meta_chunk_start
+ cfg
->nodesize
* 3;
850 csum_bytenr
= meta_chunk_start
+ cfg
->nodesize
* 4;
852 ret
= setup_temp_super(fd
, cfg
, root_bytenr
, chunk_bytenr
);
856 ret
= setup_temp_root_tree(fd
, cfg
, root_bytenr
, extent_bytenr
,
857 dev_bytenr
, fs_bytenr
, csum_bytenr
);
860 ret
= setup_temp_chunk_tree(fd
, cfg
, sys_chunk_start
, meta_chunk_start
,
864 ret
= setup_temp_dev_tree(fd
, cfg
, sys_chunk_start
, meta_chunk_start
,
868 ret
= setup_temp_fs_tree(fd
, cfg
, fs_bytenr
);
871 ret
= setup_temp_csum_tree(fd
, cfg
, csum_bytenr
);
875 * Setup extent tree last, since it may need to read tree block key
876 * for non-skinny metadata case.
878 ret
= setup_temp_extent_tree(fd
, cfg
, chunk_bytenr
, root_bytenr
,
879 extent_bytenr
, dev_bytenr
, fs_bytenr
,