btrfs-progs: convert: move common api implementation to own file
[platform/upstream/btrfs-progs.git] / convert / common.c
1 /*
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.
5  *
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.
10  *
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.
15  */
16
17 #include <unistd.h>
18 #include <uuid/uuid.h>
19 #include "disk-io.h"
20 #include "volumes.h"
21 #include "utils.h"
22 #include "mkfs/common.h"
23 #include "convert/common.h"
24
25 /*
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.
29  */
30 static int reserve_free_space(struct cache_tree *free_tree, u64 len,
31                               u64 *ret_start)
32 {
33         struct cache_extent *cache;
34         int found = 0;
35
36         ASSERT(ret_start != NULL);
37         cache = first_cache_extent(free_tree);
38         while (cache) {
39                 if (cache->size > len) {
40                         found = 1;
41                         *ret_start = cache->start;
42
43                         cache->size -= len;
44                         if (cache->size == 0) {
45                                 remove_cache_extent(free_tree, cache);
46                                 free(cache);
47                         } else {
48                                 cache->start += len;
49                         }
50                         break;
51                 }
52                 cache = next_cache_extent(cache);
53         }
54         if (!found)
55                 return -ENOSPC;
56         return 0;
57 }
58
59 static inline int write_temp_super(int fd, struct btrfs_super_block *sb,
60                                   u64 sb_bytenr)
61 {
62        u32 crc = ~(u32)0;
63        int ret;
64
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);
71        else
72                ret = 0;
73        return ret;
74 }
75
76 /*
77  * Setup temporary superblock at cfg->super_bynter
78  * Needed info are extracted from cfg, and root_bytenr, chunk_bytenr
79  *
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.
82  *
83  * The superblock signature is not valid, denotes a partially created
84  * filesystem, needs to be finalized.
85  */
86 static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
87                             u64 root_bytenr, u64 chunk_bytenr)
88 {
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;
92         int ret;
93
94         memset(super_buf, 0, BTRFS_SUPER_INFO_SIZE);
95         cfg->num_bytes = round_down(cfg->num_bytes, cfg->sectorsize);
96
97         if (*cfg->fs_uuid) {
98                 if (uuid_parse(cfg->fs_uuid, super->fsid) != 0) {
99                         error("cound not parse UUID: %s", cfg->fs_uuid);
100                         ret = -EINVAL;
101                         goto out;
102                 }
103                 if (!test_uuid_unique(cfg->fs_uuid)) {
104                         error("non-unique UUID: %s", cfg->fs_uuid);
105                         ret = -EINVAL;
106                         goto out;
107                 }
108         } else {
109                 uuid_generate(super->fsid);
110                 uuid_unparse(super->fsid, cfg->fs_uuid);
111         }
112         uuid_generate(chunk_uuid);
113         uuid_unparse(chunk_uuid, cfg->chunk_uuid);
114
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);
122         /*
123          * Temporary filesystem will only have 6 tree roots:
124          * chunk tree, root tree, extent_tree, device tree, fs tree
125          * and csum tree.
126          */
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);
136         if (cfg->label)
137                 __strncpy_null(super->label, cfg->label, BTRFS_LABEL_SIZE - 1);
138
139         /* Sys chunk array will be re-initialized at chunk tree init time */
140         super->sys_chunk_array_size = 0;
141
142         ret = write_temp_super(fd, super, cfg->super_bytenr);
143 out:
144         return ret;
145 }
146
147 static int setup_temp_extent_buffer(struct extent_buffer *buf,
148                                     struct btrfs_mkfs_config *cfg,
149                                     u64 bytenr, u64 owner)
150 {
151         unsigned char fsid[BTRFS_FSID_SIZE];
152         unsigned char chunk_uuid[BTRFS_UUID_SIZE];
153         int ret;
154
155         ret = uuid_parse(cfg->fs_uuid, fsid);
156         if (ret)
157                 return -EINVAL;
158         ret = uuid_parse(cfg->chunk_uuid, chunk_uuid);
159         if (ret)
160                 return -EINVAL;
161
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),
170                             BTRFS_UUID_SIZE);
171         write_extent_buffer(buf, fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE);
172         return 0;
173 }
174
175 static void insert_temp_root_item(struct extent_buffer *buf,
176                                   struct btrfs_mkfs_config *cfg,
177                                   int *slot, u32 *itemoff, u64 objectid,
178                                   u64 bytenr)
179 {
180         struct btrfs_root_item root_item;
181         struct btrfs_inode_item *inode_item;
182         struct btrfs_disk_key disk_key;
183
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);
197
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);
202
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),
208                             sizeof(root_item));
209         (*slot)++;
210 }
211
212 /*
213  * Setup an extent buffer for tree block.
214  */
215 static inline int write_temp_extent_buffer(int fd, struct extent_buffer *buf,
216                                            u64 bytenr)
217 {
218         int ret;
219
220         csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
221
222         /* Temporary extent buffer is always mapped 1:1 on disk */
223         ret = pwrite(fd, buf->data, buf->len, bytenr);
224         if (ret < buf->len)
225                 ret = (ret < 0 ? ret : -EIO);
226         else
227                 ret = 0;
228         return ret;
229 }
230
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)
234 {
235         struct extent_buffer *buf = NULL;
236         u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
237         int slot = 0;
238         int ret;
239
240         /*
241          * Provided bytenr must in ascending order, or tree root will have a
242          * bad key order.
243          */
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);
259                 return -EINVAL;
260         }
261         buf = malloc(sizeof(*buf) + cfg->nodesize);
262         if (!buf)
263                 return -ENOMEM;
264
265         ret = setup_temp_extent_buffer(buf, cfg, root_bytenr,
266                                        BTRFS_ROOT_TREE_OBJECTID);
267         if (ret < 0)
268                 goto out;
269
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);
278
279         ret = write_temp_extent_buffer(fd, buf, root_bytenr);
280 out:
281         free(buf);
282         return ret;
283 }
284
285 static int insert_temp_dev_item(int fd, struct extent_buffer *buf,
286                                 struct btrfs_mkfs_config *cfg,
287                                 int *slot, u32 *itemoff)
288 {
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;
295         int ret;
296
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);
300                 goto out;
301         }
302
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));
312
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),
318                         BTRFS_UUID_SIZE);
319         uuid_parse(cfg->fs_uuid, fsid);
320         write_extent_buffer(buf, fsid,
321                         (unsigned long)btrfs_device_fsid(dev_item),
322                         BTRFS_FSID_SIZE);
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);
326         /*
327          * The number must match the initial SYSTEM and META chunk size
328          */
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);
336
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,
339                            sizeof(*dev_item));
340         ret = write_temp_super(fd, super, cfg->super_bytenr);
341         (*slot)++;
342 out:
343         return ret;
344 }
345
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,
349                                   u64 type)
350 {
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;
355         int ret = 0;
356
357         ret = pread(fd, super_buf, BTRFS_SUPER_INFO_SIZE,
358                     cfg->super_bytenr);
359         if (ret < BTRFS_SUPER_INFO_SIZE) {
360                 ret = (ret < 0 ? ret : -EIO);
361                 return ret;
362         }
363
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));
373
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),
389                             BTRFS_UUID_SIZE);
390         (*slot)++;
391
392         /*
393          * If it's system chunk, also copy it to super block.
394          */
395         if (type & BTRFS_BLOCK_GROUP_SYSTEM) {
396                 char *cur;
397                 u32 array_size;
398
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) +
407                                             sizeof(disk_key);
408                 btrfs_set_super_sys_array_size(sb, array_size);
409
410                 ret = write_temp_super(fd, sb, cfg->super_bytenr);
411         }
412         return ret;
413 }
414
415 static int setup_temp_chunk_tree(int fd, struct btrfs_mkfs_config *cfg,
416                                  u64 sys_chunk_start, u64 meta_chunk_start,
417                                  u64 chunk_bytenr)
418 {
419         struct extent_buffer *buf = NULL;
420         u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
421         int slot = 0;
422         int ret;
423
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);
429                 return -EINVAL;
430         }
431         buf = malloc(sizeof(*buf) + cfg->nodesize);
432         if (!buf)
433                 return -ENOMEM;
434         ret = setup_temp_extent_buffer(buf, cfg, chunk_bytenr,
435                                        BTRFS_CHUNK_TREE_OBJECTID);
436         if (ret < 0)
437                 goto out;
438
439         ret = insert_temp_dev_item(fd, buf, cfg, &slot, &itemoff);
440         if (ret < 0)
441                 goto out;
442         ret = insert_temp_chunk_item(fd, buf, cfg, &slot, &itemoff,
443                                      sys_chunk_start,
444                                      BTRFS_MKFS_SYSTEM_GROUP_SIZE,
445                                      BTRFS_BLOCK_GROUP_SYSTEM);
446         if (ret < 0)
447                 goto out;
448         ret = insert_temp_chunk_item(fd, buf, cfg, &slot, &itemoff,
449                                      meta_chunk_start,
450                                      BTRFS_CONVERT_META_GROUP_SIZE,
451                                      BTRFS_BLOCK_GROUP_METADATA);
452         if (ret < 0)
453                 goto out;
454         ret = write_temp_extent_buffer(fd, buf, chunk_bytenr);
455
456 out:
457         free(buf);
458         return ret;
459 }
460
461 static void insert_temp_dev_extent(struct extent_buffer *buf,
462                                    int *slot, u32 *itemoff, u64 start, u64 len)
463 {
464         struct btrfs_dev_extent *dev_extent;
465         struct btrfs_disk_key disk_key;
466
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));
475
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);
483         (*slot)++;
484 }
485
486 static int setup_temp_dev_tree(int fd, struct btrfs_mkfs_config *cfg,
487                                u64 sys_chunk_start, u64 meta_chunk_start,
488                                u64 dev_bytenr)
489 {
490         struct extent_buffer *buf = NULL;
491         u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
492         int slot = 0;
493         int ret;
494
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);
500                 return -EINVAL;
501         }
502         buf = malloc(sizeof(*buf) + cfg->nodesize);
503         if (!buf)
504                 return -ENOMEM;
505         ret = setup_temp_extent_buffer(buf, cfg, dev_bytenr,
506                                        BTRFS_DEV_TREE_OBJECTID);
507         if (ret < 0)
508                 goto out;
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);
514 out:
515         free(buf);
516         return ret;
517 }
518
519 static int setup_temp_fs_tree(int fd, struct btrfs_mkfs_config *cfg,
520                               u64 fs_bytenr)
521 {
522         struct extent_buffer *buf = NULL;
523         int ret;
524
525         buf = malloc(sizeof(*buf) + cfg->nodesize);
526         if (!buf)
527                 return -ENOMEM;
528         ret = setup_temp_extent_buffer(buf, cfg, fs_bytenr,
529                                        BTRFS_FS_TREE_OBJECTID);
530         if (ret < 0)
531                 goto out;
532         /*
533          * Temporary fs tree is completely empty.
534          */
535         ret = write_temp_extent_buffer(fd, buf, fs_bytenr);
536 out:
537         free(buf);
538         return ret;
539 }
540
541 static int setup_temp_csum_tree(int fd, struct btrfs_mkfs_config *cfg,
542                                 u64 csum_bytenr)
543 {
544         struct extent_buffer *buf = NULL;
545         int ret;
546
547         buf = malloc(sizeof(*buf) + cfg->nodesize);
548         if (!buf)
549                 return -ENOMEM;
550         ret = setup_temp_extent_buffer(buf, cfg, csum_bytenr,
551                                        BTRFS_CSUM_TREE_OBJECTID);
552         if (ret < 0)
553                 goto out;
554         /*
555          * Temporary csum tree is completely empty.
556          */
557         ret = write_temp_extent_buffer(fd, buf, csum_bytenr);
558 out:
559         free(buf);
560         return ret;
561 }
562
563 /*
564  * Insert one temporary extent item.
565  *
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.
569  */
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,
573                                    u64 ref_root)
574 {
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;
581         int itemsize;
582         int skinny_metadata = cfg->features &
583                               BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA;
584         int ret;
585
586         if (skinny_metadata)
587                 itemsize = sizeof(*ei) + sizeof(*iref);
588         else
589                 itemsize = sizeof(*ei) + sizeof(*iref) +
590                            sizeof(struct btrfs_tree_block_info);
591
592         btrfs_set_header_nritems(buf, *slot + 1);
593         *(itemoff) -= itemsize;
594
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);
598         } else {
599                 btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
600                 btrfs_set_disk_key_offset(&disk_key, cfg->nodesize);
601         }
602         btrfs_set_disk_key_objectid(&disk_key, bytenr);
603
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);
607
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);
612
613         if (skinny_metadata) {
614                 iref = (struct btrfs_extent_inline_ref *)(ei + 1);
615         } else {
616                 info = (struct btrfs_tree_block_info *)(ei + 1);
617                 iref = (struct btrfs_extent_inline_ref *)(info + 1);
618         }
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);
622
623         (*slot)++;
624         if (skinny_metadata)
625                 return 0;
626
627         /*
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
631          */
632         tmp = malloc(sizeof(*tmp) + cfg->nodesize);
633         if (!tmp)
634                 return -ENOMEM;
635         ret = setup_temp_extent_buffer(tmp, cfg, bytenr, ref_root);
636         if (ret < 0)
637                 goto out;
638         ret = pread(fd, tmp->data, cfg->nodesize, bytenr);
639         if (ret < cfg->nodesize) {
640                 ret = (ret < 0 ? -errno : -EIO);
641                 goto out;
642         }
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);
647         } else {
648                 btrfs_item_key(tmp, &tree_info_key, 0);
649         }
650         btrfs_set_tree_block_key(buf, info, &tree_info_key);
651
652 out:
653         free(tmp);
654         return ret;
655 }
656
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)
661 {
662         struct btrfs_block_group_item bgi;
663         struct btrfs_disk_key disk_key;
664
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));
673
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),
679                             sizeof(bgi));
680         (*slot)++;
681 }
682
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)
687 {
688         struct extent_buffer *buf = NULL;
689         u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
690         int slot = 0;
691         int ret;
692
693         /*
694          * We must ensure provided bytenr are in ascending order,
695          * or extent tree key order will be broken.
696          */
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);
716                 return -EINVAL;
717         }
718         buf = malloc(sizeof(*buf) + cfg->nodesize);
719         if (!buf)
720                 return -ENOMEM;
721
722         ret = setup_temp_extent_buffer(buf, cfg, extent_bytenr,
723                                        BTRFS_EXTENT_TREE_OBJECTID);
724         if (ret < 0)
725                 goto out;
726
727         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
728                         chunk_bytenr, BTRFS_CHUNK_TREE_OBJECTID);
729         if (ret < 0)
730                 goto out;
731
732         insert_temp_block_group(buf, cfg, &slot, &itemoff, chunk_bytenr,
733                         BTRFS_MKFS_SYSTEM_GROUP_SIZE, cfg->nodesize,
734                         BTRFS_BLOCK_GROUP_SYSTEM);
735
736         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
737                         root_bytenr, BTRFS_ROOT_TREE_OBJECTID);
738         if (ret < 0)
739                 goto out;
740
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);
745
746         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
747                         extent_bytenr, BTRFS_EXTENT_TREE_OBJECTID);
748         if (ret < 0)
749                 goto out;
750         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
751                         dev_bytenr, BTRFS_DEV_TREE_OBJECTID);
752         if (ret < 0)
753                 goto out;
754         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
755                         fs_bytenr, BTRFS_FS_TREE_OBJECTID);
756         if (ret < 0)
757                 goto out;
758         ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
759                         csum_bytenr, BTRFS_CSUM_TREE_OBJECTID);
760         if (ret < 0)
761                 goto out;
762
763         ret = write_temp_extent_buffer(fd, buf, extent_bytenr);
764 out:
765         free(buf);
766         return ret;
767 }
768
769 /*
770  * Improved version of make_btrfs().
771  *
772  * This one will
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
779  */
780 int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
781                               struct btrfs_convert_context *cctx)
782 {
783         struct cache_tree *free = &cctx->free;
784         struct cache_tree *used = &cctx->used;
785         u64 sys_chunk_start;
786         u64 meta_chunk_start;
787         /* chunk tree bytenr, in system chunk */
788         u64 chunk_bytenr;
789         /* metadata trees bytenr, in metadata chunk */
790         u64 root_bytenr;
791         u64 extent_bytenr;
792         u64 dev_bytenr;
793         u64 fs_bytenr;
794         u64 csum_bytenr;
795         int ret;
796
797         /* Shouldn't happen */
798         BUG_ON(cache_tree_empty(used));
799
800         /*
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
804          */
805         ret = reserve_free_space(free, BTRFS_STRIPE_LEN,
806                                  &cfg->super_bytenr);
807         if (ret < 0)
808                 goto out;
809
810         /*
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.
815          */
816         ret = reserve_free_space(free, BTRFS_MKFS_SYSTEM_GROUP_SIZE,
817                                  &sys_chunk_start);
818         if (ret < 0)
819                 goto out;
820         ret = reserve_free_space(free, BTRFS_CONVERT_META_GROUP_SIZE,
821                                  &meta_chunk_start);
822         if (ret < 0)
823                 goto out;
824
825         /*
826          * Allocated meta/sys chunks will be mapped 1:1 with device offset.
827          *
828          * Inside the allocated metadata chunk, the layout will be:
829          *  | offset            | contents      |
830          *  -------------------------------------
831          *  | +0                | tree root     |
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          *  -------------------------------------
842          */
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;
849
850         ret = setup_temp_super(fd, cfg, root_bytenr, chunk_bytenr);
851         if (ret < 0)
852                 goto out;
853
854         ret = setup_temp_root_tree(fd, cfg, root_bytenr, extent_bytenr,
855                                    dev_bytenr, fs_bytenr, csum_bytenr);
856         if (ret < 0)
857                 goto out;
858         ret = setup_temp_chunk_tree(fd, cfg, sys_chunk_start, meta_chunk_start,
859                                     chunk_bytenr);
860         if (ret < 0)
861                 goto out;
862         ret = setup_temp_dev_tree(fd, cfg, sys_chunk_start, meta_chunk_start,
863                                   dev_bytenr);
864         if (ret < 0)
865                 goto out;
866         ret = setup_temp_fs_tree(fd, cfg, fs_bytenr);
867         if (ret < 0)
868                 goto out;
869         ret = setup_temp_csum_tree(fd, cfg, csum_bytenr);
870         if (ret < 0)
871                 goto out;
872         /*
873          * Setup extent tree last, since it may need to read tree block key
874          * for non-skinny metadata case.
875          */
876         ret = setup_temp_extent_tree(fd, cfg, chunk_bytenr, root_bytenr,
877                                      extent_bytenr, dev_bytenr, fs_bytenr,
878                                      csum_bytenr);
879 out:
880         return ret;
881 }
882