2 * Copyright (C) 2008 Oracle. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
22 #include <sys/types.h>
30 #include "kerncompat.h"
34 #include "transaction.h"
37 #include "extent_io.h"
39 #include "image/metadump.h"
40 #include "image/sanitize.h"
42 #define MAX_WORKER_THREADS (32)
45 struct list_head list;
46 struct list_head ordered;
54 struct metadump_struct {
55 struct btrfs_root *root;
59 struct meta_cluster cluster;
60 char meta_cluster_bytes[BLOCK_SIZE];
63 pthread_t threads[MAX_WORKER_THREADS];
65 pthread_mutex_t mutex;
67 struct rb_root name_tree;
69 struct list_head list;
70 struct list_head ordered;
80 enum sanitize_mode sanitize_names;
85 struct mdrestore_struct {
89 pthread_t threads[MAX_WORKER_THREADS];
91 pthread_mutex_t mutex;
94 struct rb_root chunk_tree;
95 struct rb_root physical_tree;
96 struct list_head list;
97 struct list_head overlapping_chunks;
102 u64 last_physical_offset;
103 u8 uuid[BTRFS_UUID_SIZE];
104 u8 fsid[BTRFS_FSID_SIZE];
112 int clear_space_cache;
113 struct btrfs_fs_info *info;
116 static int search_for_chunk_blocks(struct mdrestore_struct *mdres,
117 u64 search, u64 cluster_bytenr);
118 static struct extent_buffer *alloc_dummy_eb(u64 bytenr, u32 size);
120 static void csum_block(u8 *buf, size_t len)
122 u8 result[BTRFS_CRC32_SIZE];
124 crc = crc32c(crc, buf + BTRFS_CSUM_SIZE, len - BTRFS_CSUM_SIZE);
125 btrfs_csum_final(crc, result);
126 memcpy(buf, result, BTRFS_CRC32_SIZE);
129 static int has_name(struct btrfs_key *key)
132 case BTRFS_DIR_ITEM_KEY:
133 case BTRFS_DIR_INDEX_KEY:
134 case BTRFS_INODE_REF_KEY:
135 case BTRFS_INODE_EXTREF_KEY:
136 case BTRFS_XATTR_ITEM_KEY:
145 static char *generate_garbage(u32 name_len)
147 char *buf = malloc(name_len);
153 for (i = 0; i < name_len; i++) {
154 char c = rand_range(94) + 33;
164 static int name_cmp(struct rb_node *a, struct rb_node *b, int fuzz)
166 struct name *entry = rb_entry(a, struct name, n);
167 struct name *ins = rb_entry(b, struct name, n);
170 len = min(ins->len, entry->len);
171 return memcmp(ins->val, entry->val, len);
174 static int chunk_cmp(struct rb_node *a, struct rb_node *b, int fuzz)
176 struct fs_chunk *entry = rb_entry(a, struct fs_chunk, l);
177 struct fs_chunk *ins = rb_entry(b, struct fs_chunk, l);
179 if (fuzz && ins->logical >= entry->logical &&
180 ins->logical < entry->logical + entry->bytes)
183 if (ins->logical < entry->logical)
185 else if (ins->logical > entry->logical)
190 static int physical_cmp(struct rb_node *a, struct rb_node *b, int fuzz)
192 struct fs_chunk *entry = rb_entry(a, struct fs_chunk, p);
193 struct fs_chunk *ins = rb_entry(b, struct fs_chunk, p);
195 if (fuzz && ins->physical >= entry->physical &&
196 ins->physical < entry->physical + entry->bytes)
199 if (fuzz && entry->physical >= ins->physical &&
200 entry->physical < ins->physical + ins->bytes)
203 if (ins->physical < entry->physical)
205 else if (ins->physical > entry->physical)
210 static void tree_insert(struct rb_root *root, struct rb_node *ins,
211 int (*cmp)(struct rb_node *a, struct rb_node *b,
214 struct rb_node ** p = &root->rb_node;
215 struct rb_node * parent = NULL;
221 dir = cmp(*p, ins, 1);
230 rb_link_node(ins, parent, p);
231 rb_insert_color(ins, root);
234 static struct rb_node *tree_search(struct rb_root *root,
235 struct rb_node *search,
236 int (*cmp)(struct rb_node *a,
237 struct rb_node *b, int fuzz),
240 struct rb_node *n = root->rb_node;
244 dir = cmp(n, search, fuzz);
256 static u64 logical_to_physical(struct mdrestore_struct *mdres, u64 logical,
257 u64 *size, u64 *physical_dup)
259 struct fs_chunk *fs_chunk;
260 struct rb_node *entry;
261 struct fs_chunk search;
264 if (logical == BTRFS_SUPER_INFO_OFFSET)
267 search.logical = logical;
268 entry = tree_search(&mdres->chunk_tree, &search.l, chunk_cmp, 1);
270 if (mdres->in != stdin)
271 warning("cannot find a chunk, using logical");
274 fs_chunk = rb_entry(entry, struct fs_chunk, l);
275 if (fs_chunk->logical > logical || fs_chunk->logical + fs_chunk->bytes < logical)
277 offset = search.logical - fs_chunk->logical;
280 /* Only in dup case, physical_dup is not equal to 0 */
281 if (fs_chunk->physical_dup)
282 *physical_dup = fs_chunk->physical_dup + offset;
287 *size = min(*size, fs_chunk->bytes + fs_chunk->logical - logical);
288 return fs_chunk->physical + offset;
292 * Reverse CRC-32C table
294 static const u32 crc32c_rev_table[256] = {
295 0x00000000L,0x05EC76F1L,0x0BD8EDE2L,0x0E349B13L,
296 0x17B1DBC4L,0x125DAD35L,0x1C693626L,0x198540D7L,
297 0x2F63B788L,0x2A8FC179L,0x24BB5A6AL,0x21572C9BL,
298 0x38D26C4CL,0x3D3E1ABDL,0x330A81AEL,0x36E6F75FL,
299 0x5EC76F10L,0x5B2B19E1L,0x551F82F2L,0x50F3F403L,
300 0x4976B4D4L,0x4C9AC225L,0x42AE5936L,0x47422FC7L,
301 0x71A4D898L,0x7448AE69L,0x7A7C357AL,0x7F90438BL,
302 0x6615035CL,0x63F975ADL,0x6DCDEEBEL,0x6821984FL,
303 0xBD8EDE20L,0xB862A8D1L,0xB65633C2L,0xB3BA4533L,
304 0xAA3F05E4L,0xAFD37315L,0xA1E7E806L,0xA40B9EF7L,
305 0x92ED69A8L,0x97011F59L,0x9935844AL,0x9CD9F2BBL,
306 0x855CB26CL,0x80B0C49DL,0x8E845F8EL,0x8B68297FL,
307 0xE349B130L,0xE6A5C7C1L,0xE8915CD2L,0xED7D2A23L,
308 0xF4F86AF4L,0xF1141C05L,0xFF208716L,0xFACCF1E7L,
309 0xCC2A06B8L,0xC9C67049L,0xC7F2EB5AL,0xC21E9DABL,
310 0xDB9BDD7CL,0xDE77AB8DL,0xD043309EL,0xD5AF466FL,
311 0x7EF1CAB1L,0x7B1DBC40L,0x75292753L,0x70C551A2L,
312 0x69401175L,0x6CAC6784L,0x6298FC97L,0x67748A66L,
313 0x51927D39L,0x547E0BC8L,0x5A4A90DBL,0x5FA6E62AL,
314 0x4623A6FDL,0x43CFD00CL,0x4DFB4B1FL,0x48173DEEL,
315 0x2036A5A1L,0x25DAD350L,0x2BEE4843L,0x2E023EB2L,
316 0x37877E65L,0x326B0894L,0x3C5F9387L,0x39B3E576L,
317 0x0F551229L,0x0AB964D8L,0x048DFFCBL,0x0161893AL,
318 0x18E4C9EDL,0x1D08BF1CL,0x133C240FL,0x16D052FEL,
319 0xC37F1491L,0xC6936260L,0xC8A7F973L,0xCD4B8F82L,
320 0xD4CECF55L,0xD122B9A4L,0xDF1622B7L,0xDAFA5446L,
321 0xEC1CA319L,0xE9F0D5E8L,0xE7C44EFBL,0xE228380AL,
322 0xFBAD78DDL,0xFE410E2CL,0xF075953FL,0xF599E3CEL,
323 0x9DB87B81L,0x98540D70L,0x96609663L,0x938CE092L,
324 0x8A09A045L,0x8FE5D6B4L,0x81D14DA7L,0x843D3B56L,
325 0xB2DBCC09L,0xB737BAF8L,0xB90321EBL,0xBCEF571AL,
326 0xA56A17CDL,0xA086613CL,0xAEB2FA2FL,0xAB5E8CDEL,
327 0xFDE39562L,0xF80FE393L,0xF63B7880L,0xF3D70E71L,
328 0xEA524EA6L,0xEFBE3857L,0xE18AA344L,0xE466D5B5L,
329 0xD28022EAL,0xD76C541BL,0xD958CF08L,0xDCB4B9F9L,
330 0xC531F92EL,0xC0DD8FDFL,0xCEE914CCL,0xCB05623DL,
331 0xA324FA72L,0xA6C88C83L,0xA8FC1790L,0xAD106161L,
332 0xB49521B6L,0xB1795747L,0xBF4DCC54L,0xBAA1BAA5L,
333 0x8C474DFAL,0x89AB3B0BL,0x879FA018L,0x8273D6E9L,
334 0x9BF6963EL,0x9E1AE0CFL,0x902E7BDCL,0x95C20D2DL,
335 0x406D4B42L,0x45813DB3L,0x4BB5A6A0L,0x4E59D051L,
336 0x57DC9086L,0x5230E677L,0x5C047D64L,0x59E80B95L,
337 0x6F0EFCCAL,0x6AE28A3BL,0x64D61128L,0x613A67D9L,
338 0x78BF270EL,0x7D5351FFL,0x7367CAECL,0x768BBC1DL,
339 0x1EAA2452L,0x1B4652A3L,0x1572C9B0L,0x109EBF41L,
340 0x091BFF96L,0x0CF78967L,0x02C31274L,0x072F6485L,
341 0x31C993DAL,0x3425E52BL,0x3A117E38L,0x3FFD08C9L,
342 0x2678481EL,0x23943EEFL,0x2DA0A5FCL,0x284CD30DL,
343 0x83125FD3L,0x86FE2922L,0x88CAB231L,0x8D26C4C0L,
344 0x94A38417L,0x914FF2E6L,0x9F7B69F5L,0x9A971F04L,
345 0xAC71E85BL,0xA99D9EAAL,0xA7A905B9L,0xA2457348L,
346 0xBBC0339FL,0xBE2C456EL,0xB018DE7DL,0xB5F4A88CL,
347 0xDDD530C3L,0xD8394632L,0xD60DDD21L,0xD3E1ABD0L,
348 0xCA64EB07L,0xCF889DF6L,0xC1BC06E5L,0xC4507014L,
349 0xF2B6874BL,0xF75AF1BAL,0xF96E6AA9L,0xFC821C58L,
350 0xE5075C8FL,0xE0EB2A7EL,0xEEDFB16DL,0xEB33C79CL,
351 0x3E9C81F3L,0x3B70F702L,0x35446C11L,0x30A81AE0L,
352 0x292D5A37L,0x2CC12CC6L,0x22F5B7D5L,0x2719C124L,
353 0x11FF367BL,0x1413408AL,0x1A27DB99L,0x1FCBAD68L,
354 0x064EEDBFL,0x03A29B4EL,0x0D96005DL,0x087A76ACL,
355 0x605BEEE3L,0x65B79812L,0x6B830301L,0x6E6F75F0L,
356 0x77EA3527L,0x720643D6L,0x7C32D8C5L,0x79DEAE34L,
357 0x4F38596BL,0x4AD42F9AL,0x44E0B489L,0x410CC278L,
358 0x588982AFL,0x5D65F45EL,0x53516F4DL,0x56BD19BCL
362 * Calculate a 4-byte suffix to match desired CRC32C
364 * @current_crc: CRC32C checksum of all bytes before the suffix
365 * @desired_crc: the checksum that we want to get after adding the suffix
367 * Outputs: @suffix: pointer to where the suffix will be written (4-bytes)
369 static void find_collision_calc_suffix(unsigned long current_crc,
370 unsigned long desired_crc,
375 for(i = 3; i >= 0; i--) {
376 desired_crc = (desired_crc << 8)
377 ^ crc32c_rev_table[desired_crc >> 24 & 0xFF]
378 ^ ((current_crc >> i * 8) & 0xFF);
380 for (i = 0; i < 4; i++)
381 suffix[i] = (desired_crc >> i * 8) & 0xFF;
385 * Check if suffix is valid according to our file name conventions
387 static int find_collision_is_suffix_valid(const char *suffix)
392 for (i = 0; i < 4; i++) {
394 if (c < ' ' || c > 126 || c == '/')
400 static int find_collision_reverse_crc32c(struct name *val, u32 name_len)
402 unsigned long checksum;
403 unsigned long current_checksum;
407 /* There are no same length collisions of 4 or less bytes */
410 checksum = crc32c(~1, val->val, name_len);
412 memset(val->sub, ' ', name_len);
415 current_checksum = crc32c(~1, val->sub, name_len);
416 find_collision_calc_suffix(current_checksum,
418 val->sub + name_len);
419 if (find_collision_is_suffix_valid(val->sub + name_len) &&
420 memcmp(val->sub, val->val, val->len)) {
425 if (val->sub[i] == 126) {
430 } while (val->sub[i] == 126);
435 if (val->sub[i] == '/')
437 memset(val->sub, ' ', i);
442 if (val->sub[i] == '/')
449 static char *find_collision(struct rb_root *name_tree, char *name,
453 struct rb_node *entry;
460 entry = tree_search(name_tree, &tmp.n, name_cmp, 0);
462 val = rb_entry(entry, struct name, n);
467 val = malloc(sizeof(struct name));
469 error("cannot sanitize name, not enough memory");
474 memset(val, 0, sizeof(*val));
478 val->sub = malloc(name_len);
480 error("cannot sanitize name, not enough memory");
486 found = find_collision_reverse_crc32c(val, name_len);
490 "cannot find a hash collision for '%.*s', generating garbage, it won't match indexes",
492 for (i = 0; i < name_len; i++) {
493 char c = rand_range(94) + 33;
501 tree_insert(name_tree, &val->n, name_cmp);
505 static void sanitize_dir_item(struct metadump_struct *md, struct extent_buffer *eb,
508 struct btrfs_dir_item *dir_item;
511 unsigned long name_ptr;
516 int free_garbage = (md->sanitize_names == SANITIZE_NAMES);
518 dir_item = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
519 total_len = btrfs_item_size_nr(eb, slot);
520 while (cur < total_len) {
521 this_len = sizeof(*dir_item) +
522 btrfs_dir_name_len(eb, dir_item) +
523 btrfs_dir_data_len(eb, dir_item);
524 name_ptr = (unsigned long)(dir_item + 1);
525 name_len = btrfs_dir_name_len(eb, dir_item);
527 if (md->sanitize_names == SANITIZE_COLLISIONS) {
528 buf = malloc(name_len);
530 error("cannot sanitize name, not enough memory");
533 read_extent_buffer(eb, buf, name_ptr, name_len);
534 garbage = find_collision(&md->name_tree, buf, name_len);
536 garbage = generate_garbage(name_len);
539 error("cannot sanitize name, not enough memory");
542 write_extent_buffer(eb, garbage, name_ptr, name_len);
544 dir_item = (struct btrfs_dir_item *)((char *)dir_item +
551 static void sanitize_inode_ref(struct metadump_struct *md,
552 struct extent_buffer *eb, int slot, int ext)
554 struct btrfs_inode_extref *extref;
555 struct btrfs_inode_ref *ref;
558 unsigned long name_ptr;
562 int free_garbage = (md->sanitize_names == SANITIZE_NAMES);
564 item_size = btrfs_item_size_nr(eb, slot);
565 ptr = btrfs_item_ptr_offset(eb, slot);
566 while (cur_offset < item_size) {
568 extref = (struct btrfs_inode_extref *)(ptr +
570 name_ptr = (unsigned long)(&extref->name);
571 len = btrfs_inode_extref_name_len(eb, extref);
572 cur_offset += sizeof(*extref);
574 ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
575 len = btrfs_inode_ref_name_len(eb, ref);
576 name_ptr = (unsigned long)(ref + 1);
577 cur_offset += sizeof(*ref);
581 if (md->sanitize_names == SANITIZE_COLLISIONS) {
584 error("cannot sanitize name, not enough memory");
587 read_extent_buffer(eb, buf, name_ptr, len);
588 garbage = find_collision(&md->name_tree, buf, len);
590 garbage = generate_garbage(len);
594 error("cannot sanitize name, not enough memory");
597 write_extent_buffer(eb, garbage, name_ptr, len);
603 static void sanitize_xattr(struct extent_buffer *eb, int slot)
605 struct btrfs_dir_item *dir_item;
606 unsigned long data_ptr;
609 dir_item = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
610 data_len = btrfs_dir_data_len(eb, dir_item);
612 data_ptr = (unsigned long)((char *)(dir_item + 1) +
613 btrfs_dir_name_len(eb, dir_item));
614 memset_extent_buffer(eb, 0, data_ptr, data_len);
617 static void sanitize_name(struct metadump_struct *md, u8 *dst,
618 struct extent_buffer *src, struct btrfs_key *key,
621 struct extent_buffer *eb;
623 eb = alloc_dummy_eb(src->start, src->len);
625 error("cannot sanitize name, not enough memory");
629 memcpy(eb->data, src->data, src->len);
632 case BTRFS_DIR_ITEM_KEY:
633 case BTRFS_DIR_INDEX_KEY:
634 sanitize_dir_item(md, eb, slot);
636 case BTRFS_INODE_REF_KEY:
637 sanitize_inode_ref(md, eb, slot, 0);
639 case BTRFS_INODE_EXTREF_KEY:
640 sanitize_inode_ref(md, eb, slot, 1);
642 case BTRFS_XATTR_ITEM_KEY:
643 sanitize_xattr(eb, slot);
649 memcpy(dst, eb->data, eb->len);
654 * zero inline extents and csum items
656 static void zero_items(struct metadump_struct *md, u8 *dst,
657 struct extent_buffer *src)
659 struct btrfs_file_extent_item *fi;
660 struct btrfs_item *item;
661 struct btrfs_key key;
662 u32 nritems = btrfs_header_nritems(src);
667 for (i = 0; i < nritems; i++) {
668 item = btrfs_item_nr(i);
669 btrfs_item_key_to_cpu(src, &key, i);
670 if (key.type == BTRFS_CSUM_ITEM_KEY) {
671 size = btrfs_item_size_nr(src, i);
672 memset(dst + btrfs_leaf_data(src) +
673 btrfs_item_offset_nr(src, i), 0, size);
677 if (md->sanitize_names && has_name(&key)) {
678 sanitize_name(md, dst, src, &key, i);
682 if (key.type != BTRFS_EXTENT_DATA_KEY)
685 fi = btrfs_item_ptr(src, i, struct btrfs_file_extent_item);
686 extent_type = btrfs_file_extent_type(src, fi);
687 if (extent_type != BTRFS_FILE_EXTENT_INLINE)
690 ptr = btrfs_file_extent_inline_start(fi);
691 size = btrfs_file_extent_inline_item_len(src, item);
692 memset(dst + ptr, 0, size);
697 * copy buffer and zero useless data in the buffer
699 static void copy_buffer(struct metadump_struct *md, u8 *dst,
700 struct extent_buffer *src)
706 memcpy(dst, src->data, src->len);
707 if (src->start == BTRFS_SUPER_INFO_OFFSET)
710 level = btrfs_header_level(src);
711 nritems = btrfs_header_nritems(src);
714 size = sizeof(struct btrfs_header);
715 memset(dst + size, 0, src->len - size);
716 } else if (level == 0) {
717 size = btrfs_leaf_data(src) +
718 btrfs_item_offset_nr(src, nritems - 1) -
719 btrfs_item_nr_offset(nritems);
720 memset(dst + btrfs_item_nr_offset(nritems), 0, size);
721 zero_items(md, dst, src);
723 size = offsetof(struct btrfs_node, ptrs) +
724 sizeof(struct btrfs_key_ptr) * nritems;
725 memset(dst + size, 0, src->len - size);
727 csum_block(dst, src->len);
730 static void *dump_worker(void *data)
732 struct metadump_struct *md = (struct metadump_struct *)data;
733 struct async_work *async;
737 pthread_mutex_lock(&md->mutex);
738 while (list_empty(&md->list)) {
740 pthread_mutex_unlock(&md->mutex);
743 pthread_cond_wait(&md->cond, &md->mutex);
745 async = list_entry(md->list.next, struct async_work, list);
746 list_del_init(&async->list);
747 pthread_mutex_unlock(&md->mutex);
749 if (md->compress_level > 0) {
750 u8 *orig = async->buffer;
752 async->bufsize = compressBound(async->size);
753 async->buffer = malloc(async->bufsize);
754 if (!async->buffer) {
755 error("not enough memory for async buffer");
756 pthread_mutex_lock(&md->mutex);
759 pthread_mutex_unlock(&md->mutex);
763 ret = compress2(async->buffer,
764 (unsigned long *)&async->bufsize,
765 orig, async->size, md->compress_level);
773 pthread_mutex_lock(&md->mutex);
775 pthread_mutex_unlock(&md->mutex);
781 static void meta_cluster_init(struct metadump_struct *md, u64 start)
783 struct meta_cluster_header *header;
787 header = &md->cluster.header;
788 header->magic = cpu_to_le64(HEADER_MAGIC);
789 header->bytenr = cpu_to_le64(start);
790 header->nritems = cpu_to_le32(0);
791 header->compress = md->compress_level > 0 ?
792 COMPRESS_ZLIB : COMPRESS_NONE;
795 static void metadump_destroy(struct metadump_struct *md, int num_threads)
800 pthread_mutex_lock(&md->mutex);
802 pthread_cond_broadcast(&md->cond);
803 pthread_mutex_unlock(&md->mutex);
805 for (i = 0; i < num_threads; i++)
806 pthread_join(md->threads[i], NULL);
808 pthread_cond_destroy(&md->cond);
809 pthread_mutex_destroy(&md->mutex);
811 while ((n = rb_first(&md->name_tree))) {
814 name = rb_entry(n, struct name, n);
815 rb_erase(n, &md->name_tree);
822 static int metadump_init(struct metadump_struct *md, struct btrfs_root *root,
823 FILE *out, int num_threads, int compress_level,
824 enum sanitize_mode sanitize_names)
828 memset(md, 0, sizeof(*md));
829 INIT_LIST_HEAD(&md->list);
830 INIT_LIST_HEAD(&md->ordered);
833 md->pending_start = (u64)-1;
834 md->compress_level = compress_level;
835 md->sanitize_names = sanitize_names;
836 if (sanitize_names == SANITIZE_COLLISIONS)
837 crc32c_optimization_init();
839 md->name_tree.rb_node = NULL;
840 md->num_threads = num_threads;
841 pthread_cond_init(&md->cond, NULL);
842 pthread_mutex_init(&md->mutex, NULL);
843 meta_cluster_init(md, 0);
848 for (i = 0; i < num_threads; i++) {
849 ret = pthread_create(md->threads + i, NULL, dump_worker, md);
855 metadump_destroy(md, i + 1);
860 static int write_zero(FILE *out, size_t size)
862 static char zero[BLOCK_SIZE];
863 return fwrite(zero, size, 1, out);
866 static int write_buffers(struct metadump_struct *md, u64 *next)
868 struct meta_cluster_header *header = &md->cluster.header;
869 struct meta_cluster_item *item;
870 struct async_work *async;
876 if (list_empty(&md->ordered))
879 /* wait until all buffers are compressed */
880 while (!err && md->num_items > md->num_ready) {
881 struct timespec ts = {
885 pthread_mutex_unlock(&md->mutex);
886 nanosleep(&ts, NULL);
887 pthread_mutex_lock(&md->mutex);
892 error("one of the threads failed: %s", strerror(-err));
896 /* setup and write index block */
897 list_for_each_entry(async, &md->ordered, ordered) {
898 item = &md->cluster.items[nritems];
899 item->bytenr = cpu_to_le64(async->start);
900 item->size = cpu_to_le32(async->bufsize);
903 header->nritems = cpu_to_le32(nritems);
905 ret = fwrite(&md->cluster, BLOCK_SIZE, 1, md->out);
907 error("unable to write out cluster: %s", strerror(errno));
912 bytenr += le64_to_cpu(header->bytenr) + BLOCK_SIZE;
913 while (!list_empty(&md->ordered)) {
914 async = list_entry(md->ordered.next, struct async_work,
916 list_del_init(&async->ordered);
918 bytenr += async->bufsize;
920 ret = fwrite(async->buffer, async->bufsize, 1,
923 error("unable to write out cluster: %s",
933 /* zero unused space in the last block */
934 if (!err && bytenr & BLOCK_MASK) {
935 size_t size = BLOCK_SIZE - (bytenr & BLOCK_MASK);
938 ret = write_zero(md->out, size);
940 error("unable to zero out buffer: %s",
950 static int read_data_extent(struct metadump_struct *md,
951 struct async_work *async)
953 struct btrfs_root *root = md->root;
954 struct btrfs_fs_info *fs_info = root->fs_info;
955 u64 bytes_left = async->size;
956 u64 logical = async->start;
963 num_copies = btrfs_num_copies(root->fs_info, logical, bytes_left);
965 /* Try our best to read data, just like read_tree_block() */
966 for (cur_mirror = 0; cur_mirror < num_copies; cur_mirror++) {
968 read_len = bytes_left;
969 ret = read_extent_data(fs_info,
970 (char *)(async->buffer + offset),
971 logical, &read_len, cur_mirror);
976 bytes_left -= read_len;
984 static int get_dev_fd(struct btrfs_root *root)
986 struct btrfs_device *dev;
988 dev = list_first_entry(&root->fs_info->fs_devices->devices,
989 struct btrfs_device, dev_list);
993 static int flush_pending(struct metadump_struct *md, int done)
995 struct async_work *async = NULL;
996 struct extent_buffer *eb;
1002 if (md->pending_size) {
1003 async = calloc(1, sizeof(*async));
1007 async->start = md->pending_start;
1008 async->size = md->pending_size;
1009 async->bufsize = async->size;
1010 async->buffer = malloc(async->bufsize);
1011 if (!async->buffer) {
1016 start = async->start;
1020 ret = read_data_extent(md, async);
1022 free(async->buffer);
1029 * Balance can make the mapping not cover the super block, so
1030 * just copy directly from one of the devices.
1032 if (start == BTRFS_SUPER_INFO_OFFSET) {
1033 int fd = get_dev_fd(md->root);
1035 ret = pread64(fd, async->buffer, size, start);
1037 free(async->buffer);
1039 error("unable to read superblock at %llu: %s",
1040 (unsigned long long)start,
1048 while (!md->data && size > 0) {
1049 u64 this_read = min((u64)md->root->fs_info->nodesize,
1052 eb = read_tree_block(md->root->fs_info, start, 0);
1053 if (!extent_buffer_uptodate(eb)) {
1054 free(async->buffer);
1056 error("unable to read metadata block %llu",
1057 (unsigned long long)start);
1060 copy_buffer(md, async->buffer + offset, eb);
1061 free_extent_buffer(eb);
1063 offset += this_read;
1067 md->pending_start = (u64)-1;
1068 md->pending_size = 0;
1073 pthread_mutex_lock(&md->mutex);
1075 list_add_tail(&async->ordered, &md->ordered);
1077 if (md->compress_level > 0) {
1078 list_add_tail(&async->list, &md->list);
1079 pthread_cond_signal(&md->cond);
1084 if (md->num_items >= ITEMS_PER_CLUSTER || done) {
1085 ret = write_buffers(md, &start);
1087 error("unable to write buffers: %s", strerror(-ret));
1089 meta_cluster_init(md, start);
1091 pthread_mutex_unlock(&md->mutex);
1095 static int add_extent(u64 start, u64 size, struct metadump_struct *md,
1099 if (md->data != data ||
1100 md->pending_size + size > MAX_PENDING_SIZE ||
1101 md->pending_start + md->pending_size != start) {
1102 ret = flush_pending(md, 0);
1105 md->pending_start = start;
1107 readahead_tree_block(md->root->fs_info, start, 0);
1108 md->pending_size += size;
1113 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
1114 static int is_tree_block(struct btrfs_root *extent_root,
1115 struct btrfs_path *path, u64 bytenr)
1117 struct extent_buffer *leaf;
1118 struct btrfs_key key;
1122 leaf = path->nodes[0];
1124 struct btrfs_extent_ref_v0 *ref_item;
1126 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
1127 ret = btrfs_next_leaf(extent_root, path);
1132 leaf = path->nodes[0];
1134 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
1135 if (key.objectid != bytenr)
1137 if (key.type != BTRFS_EXTENT_REF_V0_KEY)
1139 ref_item = btrfs_item_ptr(leaf, path->slots[0],
1140 struct btrfs_extent_ref_v0);
1141 ref_objectid = btrfs_ref_objectid_v0(leaf, ref_item);
1142 if (ref_objectid < BTRFS_FIRST_FREE_OBJECTID)
1150 static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb,
1151 struct metadump_struct *metadump, int root_tree)
1153 struct extent_buffer *tmp;
1154 struct btrfs_root_item *ri;
1155 struct btrfs_key key;
1156 struct btrfs_fs_info *fs_info = root->fs_info;
1163 ret = add_extent(btrfs_header_bytenr(eb), fs_info->nodesize,
1166 error("unable to add metadata block %llu: %d",
1167 btrfs_header_bytenr(eb), ret);
1171 if (btrfs_header_level(eb) == 0 && !root_tree)
1174 level = btrfs_header_level(eb);
1175 nritems = btrfs_header_nritems(eb);
1176 for (i = 0; i < nritems; i++) {
1178 btrfs_item_key_to_cpu(eb, &key, i);
1179 if (key.type != BTRFS_ROOT_ITEM_KEY)
1181 ri = btrfs_item_ptr(eb, i, struct btrfs_root_item);
1182 bytenr = btrfs_disk_root_bytenr(eb, ri);
1183 tmp = read_tree_block(fs_info, bytenr, 0);
1184 if (!extent_buffer_uptodate(tmp)) {
1185 error("unable to read log root block");
1188 ret = copy_tree_blocks(root, tmp, metadump, 0);
1189 free_extent_buffer(tmp);
1193 bytenr = btrfs_node_blockptr(eb, i);
1194 tmp = read_tree_block(fs_info, bytenr, 0);
1195 if (!extent_buffer_uptodate(tmp)) {
1196 error("unable to read log root block");
1199 ret = copy_tree_blocks(root, tmp, metadump, root_tree);
1200 free_extent_buffer(tmp);
1209 static int copy_log_trees(struct btrfs_root *root,
1210 struct metadump_struct *metadump)
1212 u64 blocknr = btrfs_super_log_root(root->fs_info->super_copy);
1217 if (!root->fs_info->log_root_tree ||
1218 !root->fs_info->log_root_tree->node) {
1219 error("unable to copy tree log, it has not been setup");
1223 return copy_tree_blocks(root, root->fs_info->log_root_tree->node,
1227 static int copy_space_cache(struct btrfs_root *root,
1228 struct metadump_struct *metadump,
1229 struct btrfs_path *path)
1231 struct extent_buffer *leaf;
1232 struct btrfs_file_extent_item *fi;
1233 struct btrfs_key key;
1234 u64 bytenr, num_bytes;
1237 root = root->fs_info->tree_root;
1240 key.type = BTRFS_EXTENT_DATA_KEY;
1243 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
1245 error("free space inode not found: %d", ret);
1249 leaf = path->nodes[0];
1252 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
1253 ret = btrfs_next_leaf(root, path);
1255 error("cannot go to next leaf %d", ret);
1260 leaf = path->nodes[0];
1263 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
1264 if (key.type != BTRFS_EXTENT_DATA_KEY) {
1269 fi = btrfs_item_ptr(leaf, path->slots[0],
1270 struct btrfs_file_extent_item);
1271 if (btrfs_file_extent_type(leaf, fi) !=
1272 BTRFS_FILE_EXTENT_REG) {
1277 bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
1278 num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
1279 ret = add_extent(bytenr, num_bytes, metadump, 1);
1281 error("unable to add space cache blocks %d", ret);
1282 btrfs_release_path(path);
1291 static int copy_from_extent_tree(struct metadump_struct *metadump,
1292 struct btrfs_path *path)
1294 struct btrfs_root *extent_root;
1295 struct extent_buffer *leaf;
1296 struct btrfs_extent_item *ei;
1297 struct btrfs_key key;
1302 extent_root = metadump->root->fs_info->extent_root;
1303 bytenr = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE;
1304 key.objectid = bytenr;
1305 key.type = BTRFS_EXTENT_ITEM_KEY;
1308 ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
1310 error("extent root not found: %d", ret);
1315 leaf = path->nodes[0];
1318 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
1319 ret = btrfs_next_leaf(extent_root, path);
1321 error("cannot go to next leaf %d", ret);
1328 leaf = path->nodes[0];
1331 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
1332 if (key.objectid < bytenr ||
1333 (key.type != BTRFS_EXTENT_ITEM_KEY &&
1334 key.type != BTRFS_METADATA_ITEM_KEY)) {
1339 bytenr = key.objectid;
1340 if (key.type == BTRFS_METADATA_ITEM_KEY) {
1341 num_bytes = extent_root->fs_info->nodesize;
1343 num_bytes = key.offset;
1346 if (num_bytes == 0) {
1347 error("extent length 0 at bytenr %llu key type %d",
1348 (unsigned long long)bytenr, key.type);
1353 if (btrfs_item_size_nr(leaf, path->slots[0]) > sizeof(*ei)) {
1354 ei = btrfs_item_ptr(leaf, path->slots[0],
1355 struct btrfs_extent_item);
1356 if (btrfs_extent_flags(leaf, ei) &
1357 BTRFS_EXTENT_FLAG_TREE_BLOCK) {
1358 ret = add_extent(bytenr, num_bytes, metadump,
1361 error("unable to add block %llu: %d",
1362 (unsigned long long)bytenr, ret);
1367 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
1368 ret = is_tree_block(extent_root, path, bytenr);
1370 error("failed to check tree block %llu: %d",
1371 (unsigned long long)bytenr, ret);
1376 ret = add_extent(bytenr, num_bytes, metadump,
1379 error("unable to add block %llu: %d",
1380 (unsigned long long)bytenr, ret);
1387 "either extent tree is corrupted or you haven't built with V0 support");
1392 bytenr += num_bytes;
1395 btrfs_release_path(path);
1400 static int create_metadump(const char *input, FILE *out, int num_threads,
1401 int compress_level, enum sanitize_mode sanitize,
1404 struct btrfs_root *root;
1405 struct btrfs_path path;
1406 struct metadump_struct metadump;
1410 root = open_ctree(input, 0, 0);
1412 error("open ctree failed");
1416 ret = metadump_init(&metadump, root, out, num_threads,
1417 compress_level, sanitize);
1419 error("failed to initialize metadump: %d", ret);
1424 ret = add_extent(BTRFS_SUPER_INFO_OFFSET, BTRFS_SUPER_INFO_SIZE,
1427 error("unable to add metadata: %d", ret);
1432 btrfs_init_path(&path);
1435 ret = copy_tree_blocks(root, root->fs_info->chunk_root->node,
1442 ret = copy_tree_blocks(root, root->fs_info->tree_root->node,
1449 ret = copy_from_extent_tree(&metadump, &path);
1456 ret = copy_log_trees(root, &metadump);
1462 ret = copy_space_cache(root, &metadump, &path);
1464 ret = flush_pending(&metadump, 1);
1468 error("failed to flush pending data: %d", ret);
1471 metadump_destroy(&metadump, num_threads);
1473 btrfs_release_path(&path);
1474 ret = close_ctree(root);
1475 return err ? err : ret;
1478 static void update_super_old(u8 *buffer)
1480 struct btrfs_super_block *super = (struct btrfs_super_block *)buffer;
1481 struct btrfs_chunk *chunk;
1482 struct btrfs_disk_key *key;
1483 u32 sectorsize = btrfs_super_sectorsize(super);
1484 u64 flags = btrfs_super_flags(super);
1486 flags |= BTRFS_SUPER_FLAG_METADUMP;
1487 btrfs_set_super_flags(super, flags);
1489 key = (struct btrfs_disk_key *)(super->sys_chunk_array);
1490 chunk = (struct btrfs_chunk *)(super->sys_chunk_array +
1491 sizeof(struct btrfs_disk_key));
1493 btrfs_set_disk_key_objectid(key, BTRFS_FIRST_CHUNK_TREE_OBJECTID);
1494 btrfs_set_disk_key_type(key, BTRFS_CHUNK_ITEM_KEY);
1495 btrfs_set_disk_key_offset(key, 0);
1497 btrfs_set_stack_chunk_length(chunk, (u64)-1);
1498 btrfs_set_stack_chunk_owner(chunk, BTRFS_EXTENT_TREE_OBJECTID);
1499 btrfs_set_stack_chunk_stripe_len(chunk, BTRFS_STRIPE_LEN);
1500 btrfs_set_stack_chunk_type(chunk, BTRFS_BLOCK_GROUP_SYSTEM);
1501 btrfs_set_stack_chunk_io_align(chunk, sectorsize);
1502 btrfs_set_stack_chunk_io_width(chunk, sectorsize);
1503 btrfs_set_stack_chunk_sector_size(chunk, sectorsize);
1504 btrfs_set_stack_chunk_num_stripes(chunk, 1);
1505 btrfs_set_stack_chunk_sub_stripes(chunk, 0);
1506 chunk->stripe.devid = super->dev_item.devid;
1507 btrfs_set_stack_stripe_offset(&chunk->stripe, 0);
1508 memcpy(chunk->stripe.dev_uuid, super->dev_item.uuid, BTRFS_UUID_SIZE);
1509 btrfs_set_super_sys_array_size(super, sizeof(*key) + sizeof(*chunk));
1510 csum_block(buffer, BTRFS_SUPER_INFO_SIZE);
1513 static int update_super(struct mdrestore_struct *mdres, u8 *buffer)
1515 struct btrfs_super_block *super = (struct btrfs_super_block *)buffer;
1516 struct btrfs_chunk *chunk;
1517 struct btrfs_disk_key *disk_key;
1518 struct btrfs_key key;
1519 u64 flags = btrfs_super_flags(super);
1520 u32 new_array_size = 0;
1523 u8 *ptr, *write_ptr;
1524 int old_num_stripes;
1526 write_ptr = ptr = super->sys_chunk_array;
1527 array_size = btrfs_super_sys_array_size(super);
1529 while (cur < array_size) {
1530 disk_key = (struct btrfs_disk_key *)ptr;
1531 btrfs_disk_key_to_cpu(&key, disk_key);
1533 new_array_size += sizeof(*disk_key);
1534 memmove(write_ptr, ptr, sizeof(*disk_key));
1536 write_ptr += sizeof(*disk_key);
1537 ptr += sizeof(*disk_key);
1538 cur += sizeof(*disk_key);
1540 if (key.type == BTRFS_CHUNK_ITEM_KEY) {
1541 u64 type, physical, physical_dup, size = 0;
1543 chunk = (struct btrfs_chunk *)ptr;
1544 old_num_stripes = btrfs_stack_chunk_num_stripes(chunk);
1545 chunk = (struct btrfs_chunk *)write_ptr;
1547 memmove(write_ptr, ptr, sizeof(*chunk));
1548 btrfs_set_stack_chunk_sub_stripes(chunk, 0);
1549 type = btrfs_stack_chunk_type(chunk);
1550 if (type & BTRFS_BLOCK_GROUP_DUP) {
1551 new_array_size += sizeof(struct btrfs_stripe);
1552 write_ptr += sizeof(struct btrfs_stripe);
1554 btrfs_set_stack_chunk_num_stripes(chunk, 1);
1555 btrfs_set_stack_chunk_type(chunk,
1556 BTRFS_BLOCK_GROUP_SYSTEM);
1558 chunk->stripe.devid = super->dev_item.devid;
1559 physical = logical_to_physical(mdres, key.offset,
1560 &size, &physical_dup);
1561 if (size != (u64)-1)
1562 btrfs_set_stack_stripe_offset(&chunk->stripe,
1564 memcpy(chunk->stripe.dev_uuid, super->dev_item.uuid,
1566 new_array_size += sizeof(*chunk);
1568 error("bogus key in the sys array %d", key.type);
1571 write_ptr += sizeof(*chunk);
1572 ptr += btrfs_chunk_item_size(old_num_stripes);
1573 cur += btrfs_chunk_item_size(old_num_stripes);
1576 if (mdres->clear_space_cache)
1577 btrfs_set_super_cache_generation(super, 0);
1579 flags |= BTRFS_SUPER_FLAG_METADUMP_V2;
1580 btrfs_set_super_flags(super, flags);
1581 btrfs_set_super_sys_array_size(super, new_array_size);
1582 btrfs_set_super_num_devices(super, 1);
1583 csum_block(buffer, BTRFS_SUPER_INFO_SIZE);
1588 static struct extent_buffer *alloc_dummy_eb(u64 bytenr, u32 size)
1590 struct extent_buffer *eb;
1592 eb = calloc(1, sizeof(struct extent_buffer) + size);
1601 static void truncate_item(struct extent_buffer *eb, int slot, u32 new_size)
1603 struct btrfs_item *item;
1611 old_size = btrfs_item_size_nr(eb, slot);
1612 if (old_size == new_size)
1615 nritems = btrfs_header_nritems(eb);
1616 data_end = btrfs_item_offset_nr(eb, nritems - 1);
1618 old_data_start = btrfs_item_offset_nr(eb, slot);
1619 size_diff = old_size - new_size;
1621 for (i = slot; i < nritems; i++) {
1623 item = btrfs_item_nr(i);
1624 ioff = btrfs_item_offset(eb, item);
1625 btrfs_set_item_offset(eb, item, ioff + size_diff);
1628 memmove_extent_buffer(eb, btrfs_leaf_data(eb) + data_end + size_diff,
1629 btrfs_leaf_data(eb) + data_end,
1630 old_data_start + new_size - data_end);
1631 item = btrfs_item_nr(slot);
1632 btrfs_set_item_size(eb, item, new_size);
1635 static int fixup_chunk_tree_block(struct mdrestore_struct *mdres,
1636 struct async_work *async, u8 *buffer,
1639 struct extent_buffer *eb;
1640 size_t size_left = size;
1641 u64 bytenr = async->start;
1644 if (size_left % mdres->nodesize)
1647 eb = alloc_dummy_eb(bytenr, mdres->nodesize);
1653 memcpy(eb->data, buffer, mdres->nodesize);
1655 if (btrfs_header_bytenr(eb) != bytenr)
1657 if (memcmp(mdres->fsid,
1658 eb->data + offsetof(struct btrfs_header, fsid),
1662 if (btrfs_header_owner(eb) != BTRFS_CHUNK_TREE_OBJECTID)
1665 if (btrfs_header_level(eb) != 0)
1668 for (i = 0; i < btrfs_header_nritems(eb); i++) {
1669 struct btrfs_chunk *chunk;
1670 struct btrfs_key key;
1671 u64 type, physical, physical_dup, size = (u64)-1;
1673 btrfs_item_key_to_cpu(eb, &key, i);
1674 if (key.type != BTRFS_CHUNK_ITEM_KEY)
1678 physical = logical_to_physical(mdres, key.offset,
1679 &size, &physical_dup);
1682 truncate_item(eb, i, sizeof(*chunk));
1683 chunk = btrfs_item_ptr(eb, i, struct btrfs_chunk);
1686 /* Zero out the RAID profile */
1687 type = btrfs_chunk_type(eb, chunk);
1688 type &= (BTRFS_BLOCK_GROUP_DATA |
1689 BTRFS_BLOCK_GROUP_SYSTEM |
1690 BTRFS_BLOCK_GROUP_METADATA |
1691 BTRFS_BLOCK_GROUP_DUP);
1692 btrfs_set_chunk_type(eb, chunk, type);
1695 btrfs_set_chunk_num_stripes(eb, chunk, 1);
1696 btrfs_set_chunk_sub_stripes(eb, chunk, 0);
1697 btrfs_set_stripe_devid_nr(eb, chunk, 0, mdres->devid);
1698 if (size != (u64)-1)
1699 btrfs_set_stripe_offset_nr(eb, chunk, 0,
1701 /* update stripe 2 offset */
1703 btrfs_set_stripe_offset_nr(eb, chunk, 1,
1706 write_extent_buffer(eb, mdres->uuid,
1707 (unsigned long)btrfs_stripe_dev_uuid_nr(
1711 memcpy(buffer, eb->data, eb->len);
1712 csum_block(buffer, eb->len);
1714 size_left -= mdres->nodesize;
1715 buffer += mdres->nodesize;
1716 bytenr += mdres->nodesize;
1723 static void write_backup_supers(int fd, u8 *buf)
1725 struct btrfs_super_block *super = (struct btrfs_super_block *)buf;
1732 if (fstat(fd, &st)) {
1734 "cannot stat restore point, won't be able to write backup supers: %s",
1739 size = btrfs_device_size(fd, &st);
1741 for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1742 bytenr = btrfs_sb_offset(i);
1743 if (bytenr + BTRFS_SUPER_INFO_SIZE > size)
1745 btrfs_set_super_bytenr(super, bytenr);
1746 csum_block(buf, BTRFS_SUPER_INFO_SIZE);
1747 ret = pwrite64(fd, buf, BTRFS_SUPER_INFO_SIZE, bytenr);
1748 if (ret < BTRFS_SUPER_INFO_SIZE) {
1751 "problem writing out backup super block %d: %s",
1752 i, strerror(errno));
1754 error("short write writing out backup super block");
1760 static void *restore_worker(void *data)
1762 struct mdrestore_struct *mdres = (struct mdrestore_struct *)data;
1763 struct async_work *async;
1769 int compress_size = MAX_PENDING_SIZE * 4;
1771 outfd = fileno(mdres->out);
1772 buffer = malloc(compress_size);
1774 error("not enough memory for restore worker buffer");
1775 pthread_mutex_lock(&mdres->mutex);
1777 mdres->error = -ENOMEM;
1778 pthread_mutex_unlock(&mdres->mutex);
1783 u64 bytenr, physical_dup;
1787 pthread_mutex_lock(&mdres->mutex);
1788 while (!mdres->nodesize || list_empty(&mdres->list)) {
1790 pthread_mutex_unlock(&mdres->mutex);
1793 pthread_cond_wait(&mdres->cond, &mdres->mutex);
1795 async = list_entry(mdres->list.next, struct async_work, list);
1796 list_del_init(&async->list);
1798 if (mdres->compress_method == COMPRESS_ZLIB) {
1799 size = compress_size;
1800 pthread_mutex_unlock(&mdres->mutex);
1801 ret = uncompress(buffer, (unsigned long *)&size,
1802 async->buffer, async->bufsize);
1803 pthread_mutex_lock(&mdres->mutex);
1805 error("decompression failed with %d", ret);
1810 outbuf = async->buffer;
1811 size = async->bufsize;
1814 if (!mdres->multi_devices) {
1815 if (async->start == BTRFS_SUPER_INFO_OFFSET) {
1816 if (mdres->old_restore) {
1817 update_super_old(outbuf);
1819 ret = update_super(mdres, outbuf);
1823 } else if (!mdres->old_restore) {
1824 ret = fixup_chunk_tree_block(mdres, async, outbuf, size);
1830 if (!mdres->fixup_offset) {
1832 u64 chunk_size = size;
1834 if (!mdres->multi_devices && !mdres->old_restore)
1835 bytenr = logical_to_physical(mdres,
1836 async->start + offset,
1840 bytenr = async->start + offset;
1842 ret = pwrite64(outfd, outbuf+offset, chunk_size,
1844 if (ret != chunk_size)
1848 ret = pwrite64(outfd, outbuf+offset,
1851 if (ret != chunk_size)
1855 offset += chunk_size;
1860 error("unable to write to device: %s",
1864 error("short write");
1868 } else if (async->start != BTRFS_SUPER_INFO_OFFSET) {
1869 ret = write_data_to_disk(mdres->info, outbuf, async->start, size, 0);
1871 error("failed to write data");
1877 /* backup super blocks are already there at fixup_offset stage */
1878 if (!mdres->multi_devices && async->start == BTRFS_SUPER_INFO_OFFSET)
1879 write_backup_supers(outfd, outbuf);
1881 if (err && !mdres->error)
1884 pthread_mutex_unlock(&mdres->mutex);
1886 free(async->buffer);
1894 static void mdrestore_destroy(struct mdrestore_struct *mdres, int num_threads)
1899 while ((n = rb_first(&mdres->chunk_tree))) {
1900 struct fs_chunk *entry;
1902 entry = rb_entry(n, struct fs_chunk, l);
1903 rb_erase(n, &mdres->chunk_tree);
1904 rb_erase(&entry->p, &mdres->physical_tree);
1907 pthread_mutex_lock(&mdres->mutex);
1909 pthread_cond_broadcast(&mdres->cond);
1910 pthread_mutex_unlock(&mdres->mutex);
1912 for (i = 0; i < num_threads; i++)
1913 pthread_join(mdres->threads[i], NULL);
1915 pthread_cond_destroy(&mdres->cond);
1916 pthread_mutex_destroy(&mdres->mutex);
1919 static int mdrestore_init(struct mdrestore_struct *mdres,
1920 FILE *in, FILE *out, int old_restore,
1921 int num_threads, int fixup_offset,
1922 struct btrfs_fs_info *info, int multi_devices)
1926 memset(mdres, 0, sizeof(*mdres));
1927 pthread_cond_init(&mdres->cond, NULL);
1928 pthread_mutex_init(&mdres->mutex, NULL);
1929 INIT_LIST_HEAD(&mdres->list);
1930 INIT_LIST_HEAD(&mdres->overlapping_chunks);
1933 mdres->old_restore = old_restore;
1934 mdres->chunk_tree.rb_node = NULL;
1935 mdres->fixup_offset = fixup_offset;
1937 mdres->multi_devices = multi_devices;
1938 mdres->clear_space_cache = 0;
1939 mdres->last_physical_offset = 0;
1940 mdres->alloced_chunks = 0;
1945 mdres->num_threads = num_threads;
1946 for (i = 0; i < num_threads; i++) {
1947 ret = pthread_create(&mdres->threads[i], NULL, restore_worker,
1950 /* pthread_create returns errno directly */
1956 mdrestore_destroy(mdres, i + 1);
1960 static int fill_mdres_info(struct mdrestore_struct *mdres,
1961 struct async_work *async)
1963 struct btrfs_super_block *super;
1968 /* We've already been initialized */
1969 if (mdres->nodesize)
1972 if (mdres->compress_method == COMPRESS_ZLIB) {
1973 size_t size = MAX_PENDING_SIZE * 2;
1975 buffer = malloc(MAX_PENDING_SIZE * 2);
1978 ret = uncompress(buffer, (unsigned long *)&size,
1979 async->buffer, async->bufsize);
1981 error("decompression failed with %d", ret);
1987 outbuf = async->buffer;
1990 super = (struct btrfs_super_block *)outbuf;
1991 mdres->nodesize = btrfs_super_nodesize(super);
1992 memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE);
1993 memcpy(mdres->uuid, super->dev_item.uuid,
1995 mdres->devid = le64_to_cpu(super->dev_item.devid);
2000 static int add_cluster(struct meta_cluster *cluster,
2001 struct mdrestore_struct *mdres, u64 *next)
2003 struct meta_cluster_item *item;
2004 struct meta_cluster_header *header = &cluster->header;
2005 struct async_work *async;
2010 pthread_mutex_lock(&mdres->mutex);
2011 mdres->compress_method = header->compress;
2012 pthread_mutex_unlock(&mdres->mutex);
2014 bytenr = le64_to_cpu(header->bytenr) + BLOCK_SIZE;
2015 nritems = le32_to_cpu(header->nritems);
2016 for (i = 0; i < nritems; i++) {
2017 item = &cluster->items[i];
2018 async = calloc(1, sizeof(*async));
2020 error("not enough memory for async data");
2023 async->start = le64_to_cpu(item->bytenr);
2024 async->bufsize = le32_to_cpu(item->size);
2025 async->buffer = malloc(async->bufsize);
2026 if (!async->buffer) {
2027 error("not enough memory for async buffer");
2031 ret = fread(async->buffer, async->bufsize, 1, mdres->in);
2033 error("unable to read buffer: %s", strerror(errno));
2034 free(async->buffer);
2038 bytenr += async->bufsize;
2040 pthread_mutex_lock(&mdres->mutex);
2041 if (async->start == BTRFS_SUPER_INFO_OFFSET) {
2042 ret = fill_mdres_info(mdres, async);
2044 error("unable to set up restore state");
2045 pthread_mutex_unlock(&mdres->mutex);
2046 free(async->buffer);
2051 list_add_tail(&async->list, &mdres->list);
2053 pthread_cond_signal(&mdres->cond);
2054 pthread_mutex_unlock(&mdres->mutex);
2056 if (bytenr & BLOCK_MASK) {
2057 char buffer[BLOCK_MASK];
2058 size_t size = BLOCK_SIZE - (bytenr & BLOCK_MASK);
2061 ret = fread(buffer, size, 1, mdres->in);
2063 error("failed to read buffer: %s", strerror(errno));
2071 static int wait_for_worker(struct mdrestore_struct *mdres)
2075 pthread_mutex_lock(&mdres->mutex);
2077 while (!ret && mdres->num_items > 0) {
2078 struct timespec ts = {
2080 .tv_nsec = 10000000,
2082 pthread_mutex_unlock(&mdres->mutex);
2083 nanosleep(&ts, NULL);
2084 pthread_mutex_lock(&mdres->mutex);
2087 pthread_mutex_unlock(&mdres->mutex);
2091 static int read_chunk_block(struct mdrestore_struct *mdres, u8 *buffer,
2092 u64 bytenr, u64 item_bytenr, u32 bufsize,
2095 struct extent_buffer *eb;
2099 eb = alloc_dummy_eb(bytenr, mdres->nodesize);
2105 while (item_bytenr != bytenr) {
2106 buffer += mdres->nodesize;
2107 item_bytenr += mdres->nodesize;
2110 memcpy(eb->data, buffer, mdres->nodesize);
2111 if (btrfs_header_bytenr(eb) != bytenr) {
2112 error("eb bytenr does not match found bytenr: %llu != %llu",
2113 (unsigned long long)btrfs_header_bytenr(eb),
2114 (unsigned long long)bytenr);
2119 if (memcmp(mdres->fsid, eb->data + offsetof(struct btrfs_header, fsid),
2121 error("filesystem UUID of eb %llu does not match",
2122 (unsigned long long)bytenr);
2127 if (btrfs_header_owner(eb) != BTRFS_CHUNK_TREE_OBJECTID) {
2128 error("wrong eb %llu owner %llu",
2129 (unsigned long long)bytenr,
2130 (unsigned long long)btrfs_header_owner(eb));
2135 for (i = 0; i < btrfs_header_nritems(eb); i++) {
2136 struct btrfs_chunk *chunk;
2137 struct fs_chunk *fs_chunk;
2138 struct btrfs_key key;
2141 if (btrfs_header_level(eb)) {
2142 u64 blockptr = btrfs_node_blockptr(eb, i);
2144 ret = search_for_chunk_blocks(mdres, blockptr,
2151 /* Yay a leaf! We loves leafs! */
2152 btrfs_item_key_to_cpu(eb, &key, i);
2153 if (key.type != BTRFS_CHUNK_ITEM_KEY)
2156 fs_chunk = malloc(sizeof(struct fs_chunk));
2158 error("not enough memory to allocate chunk");
2162 memset(fs_chunk, 0, sizeof(*fs_chunk));
2163 chunk = btrfs_item_ptr(eb, i, struct btrfs_chunk);
2165 fs_chunk->logical = key.offset;
2166 fs_chunk->physical = btrfs_stripe_offset_nr(eb, chunk, 0);
2167 fs_chunk->bytes = btrfs_chunk_length(eb, chunk);
2168 INIT_LIST_HEAD(&fs_chunk->list);
2169 if (tree_search(&mdres->physical_tree, &fs_chunk->p,
2170 physical_cmp, 1) != NULL)
2171 list_add(&fs_chunk->list, &mdres->overlapping_chunks);
2173 tree_insert(&mdres->physical_tree, &fs_chunk->p,
2176 type = btrfs_chunk_type(eb, chunk);
2177 if (type & BTRFS_BLOCK_GROUP_DUP) {
2178 fs_chunk->physical_dup =
2179 btrfs_stripe_offset_nr(eb, chunk, 1);
2182 if (fs_chunk->physical_dup + fs_chunk->bytes >
2183 mdres->last_physical_offset)
2184 mdres->last_physical_offset = fs_chunk->physical_dup +
2186 else if (fs_chunk->physical + fs_chunk->bytes >
2187 mdres->last_physical_offset)
2188 mdres->last_physical_offset = fs_chunk->physical +
2190 mdres->alloced_chunks += fs_chunk->bytes;
2191 /* in dup case, fs_chunk->bytes should add twice */
2192 if (fs_chunk->physical_dup)
2193 mdres->alloced_chunks += fs_chunk->bytes;
2194 tree_insert(&mdres->chunk_tree, &fs_chunk->l, chunk_cmp);
2201 /* If you have to ask you aren't worthy */
2202 static int search_for_chunk_blocks(struct mdrestore_struct *mdres,
2203 u64 search, u64 cluster_bytenr)
2205 struct meta_cluster *cluster;
2206 struct meta_cluster_header *header;
2207 struct meta_cluster_item *item;
2208 u64 current_cluster = cluster_bytenr, bytenr;
2210 u32 bufsize, nritems, i;
2211 u32 max_size = MAX_PENDING_SIZE * 2;
2212 u8 *buffer, *tmp = NULL;
2215 cluster = malloc(BLOCK_SIZE);
2217 error("not enough memory for cluster");
2221 buffer = malloc(max_size);
2223 error("not enough memory for buffer");
2228 if (mdres->compress_method == COMPRESS_ZLIB) {
2229 tmp = malloc(max_size);
2231 error("not enough memory for buffer");
2238 bytenr = current_cluster;
2240 if (fseek(mdres->in, current_cluster, SEEK_SET)) {
2241 error("seek failed: %s", strerror(errno));
2246 ret = fread(cluster, BLOCK_SIZE, 1, mdres->in);
2248 if (cluster_bytenr != 0) {
2250 current_cluster = 0;
2255 "unknown state after reading cluster at %llu, probably corrupted data",
2259 } else if (ret < 0) {
2260 error("unable to read image at %llu: %s",
2261 (unsigned long long)cluster_bytenr,
2267 header = &cluster->header;
2268 if (le64_to_cpu(header->magic) != HEADER_MAGIC ||
2269 le64_to_cpu(header->bytenr) != current_cluster) {
2270 error("bad header in metadump image");
2275 bytenr += BLOCK_SIZE;
2276 nritems = le32_to_cpu(header->nritems);
2277 for (i = 0; i < nritems; i++) {
2280 item = &cluster->items[i];
2281 bufsize = le32_to_cpu(item->size);
2282 item_bytenr = le64_to_cpu(item->bytenr);
2284 if (bufsize > max_size) {
2285 error("item %u too big: %u > %u", i, bufsize,
2291 if (mdres->compress_method == COMPRESS_ZLIB) {
2292 ret = fread(tmp, bufsize, 1, mdres->in);
2294 error("read error: %s", strerror(errno));
2300 ret = uncompress(buffer,
2301 (unsigned long *)&size, tmp,
2304 error("decompression failed with %d",
2310 ret = fread(buffer, bufsize, 1, mdres->in);
2312 error("read error: %s",
2321 if (item_bytenr <= search &&
2322 item_bytenr + size > search) {
2323 ret = read_chunk_block(mdres, buffer, search,
2337 if (bytenr & BLOCK_MASK)
2338 bytenr += BLOCK_SIZE - (bytenr & BLOCK_MASK);
2339 current_cluster = bytenr;
2348 static int build_chunk_tree(struct mdrestore_struct *mdres,
2349 struct meta_cluster *cluster)
2351 struct btrfs_super_block *super;
2352 struct meta_cluster_header *header;
2353 struct meta_cluster_item *item = NULL;
2354 u64 chunk_root_bytenr = 0;
2360 /* We can't seek with stdin so don't bother doing this */
2361 if (mdres->in == stdin)
2364 ret = fread(cluster, BLOCK_SIZE, 1, mdres->in);
2366 error("unable to read cluster: %s", strerror(errno));
2371 header = &cluster->header;
2372 if (le64_to_cpu(header->magic) != HEADER_MAGIC ||
2373 le64_to_cpu(header->bytenr) != 0) {
2374 error("bad header in metadump image");
2378 bytenr += BLOCK_SIZE;
2379 mdres->compress_method = header->compress;
2380 nritems = le32_to_cpu(header->nritems);
2381 for (i = 0; i < nritems; i++) {
2382 item = &cluster->items[i];
2384 if (le64_to_cpu(item->bytenr) == BTRFS_SUPER_INFO_OFFSET)
2386 bytenr += le32_to_cpu(item->size);
2387 if (fseek(mdres->in, le32_to_cpu(item->size), SEEK_CUR)) {
2388 error("seek failed: %s", strerror(errno));
2393 if (!item || le64_to_cpu(item->bytenr) != BTRFS_SUPER_INFO_OFFSET) {
2394 error("did not find superblock at %llu",
2395 le64_to_cpu(item->bytenr));
2399 buffer = malloc(le32_to_cpu(item->size));
2401 error("not enough memory to allocate buffer");
2405 ret = fread(buffer, le32_to_cpu(item->size), 1, mdres->in);
2407 error("unable to read buffer: %s", strerror(errno));
2412 if (mdres->compress_method == COMPRESS_ZLIB) {
2413 size_t size = MAX_PENDING_SIZE * 2;
2416 tmp = malloc(MAX_PENDING_SIZE * 2);
2421 ret = uncompress(tmp, (unsigned long *)&size,
2422 buffer, le32_to_cpu(item->size));
2424 error("decompression failed with %d", ret);
2433 pthread_mutex_lock(&mdres->mutex);
2434 super = (struct btrfs_super_block *)buffer;
2435 chunk_root_bytenr = btrfs_super_chunk_root(super);
2436 mdres->nodesize = btrfs_super_nodesize(super);
2437 memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE);
2438 memcpy(mdres->uuid, super->dev_item.uuid,
2440 mdres->devid = le64_to_cpu(super->dev_item.devid);
2442 pthread_mutex_unlock(&mdres->mutex);
2444 return search_for_chunk_blocks(mdres, chunk_root_bytenr, 0);
2447 static int range_contains_super(u64 physical, u64 bytes)
2452 for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
2453 super_bytenr = btrfs_sb_offset(i);
2454 if (super_bytenr >= physical &&
2455 super_bytenr < physical + bytes)
2462 static void remap_overlapping_chunks(struct mdrestore_struct *mdres)
2464 struct fs_chunk *fs_chunk;
2466 while (!list_empty(&mdres->overlapping_chunks)) {
2467 fs_chunk = list_first_entry(&mdres->overlapping_chunks,
2468 struct fs_chunk, list);
2469 list_del_init(&fs_chunk->list);
2470 if (range_contains_super(fs_chunk->physical,
2473 "remapping a chunk that had a super mirror inside of it, clearing space cache so we don't end up with corruption");
2474 mdres->clear_space_cache = 1;
2476 fs_chunk->physical = mdres->last_physical_offset;
2477 tree_insert(&mdres->physical_tree, &fs_chunk->p, physical_cmp);
2478 mdres->last_physical_offset += fs_chunk->bytes;
2482 static int fixup_devices(struct btrfs_fs_info *fs_info,
2483 struct mdrestore_struct *mdres, off_t dev_size)
2485 struct btrfs_trans_handle *trans;
2486 struct btrfs_dev_item *dev_item;
2487 struct btrfs_path path;
2488 struct extent_buffer *leaf;
2489 struct btrfs_root *root = fs_info->chunk_root;
2490 struct btrfs_key key;
2491 u64 devid, cur_devid;
2494 trans = btrfs_start_transaction(fs_info->tree_root, 1);
2495 if (IS_ERR(trans)) {
2496 error("cannot starting transaction %ld", PTR_ERR(trans));
2497 return PTR_ERR(trans);
2500 dev_item = &fs_info->super_copy->dev_item;
2502 devid = btrfs_stack_device_id(dev_item);
2504 btrfs_set_stack_device_total_bytes(dev_item, dev_size);
2505 btrfs_set_stack_device_bytes_used(dev_item, mdres->alloced_chunks);
2507 key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
2508 key.type = BTRFS_DEV_ITEM_KEY;
2511 btrfs_init_path(&path);
2514 ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
2516 error("search failed: %d", ret);
2521 leaf = path.nodes[0];
2522 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
2523 ret = btrfs_next_leaf(root, &path);
2525 error("cannot go to next leaf %d", ret);
2532 leaf = path.nodes[0];
2535 btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
2536 if (key.type > BTRFS_DEV_ITEM_KEY)
2538 if (key.type != BTRFS_DEV_ITEM_KEY) {
2543 dev_item = btrfs_item_ptr(leaf, path.slots[0],
2544 struct btrfs_dev_item);
2545 cur_devid = btrfs_device_id(leaf, dev_item);
2546 if (devid != cur_devid) {
2547 ret = btrfs_del_item(trans, root, &path);
2549 error("cannot delete item: %d", ret);
2552 btrfs_release_path(&path);
2556 btrfs_set_device_total_bytes(leaf, dev_item, dev_size);
2557 btrfs_set_device_bytes_used(leaf, dev_item,
2558 mdres->alloced_chunks);
2559 btrfs_mark_buffer_dirty(leaf);
2563 btrfs_release_path(&path);
2564 ret = btrfs_commit_transaction(trans, fs_info->tree_root);
2566 error("unable to commit transaction: %d", ret);
2572 static int restore_metadump(const char *input, FILE *out, int old_restore,
2573 int num_threads, int fixup_offset,
2574 const char *target, int multi_devices)
2576 struct meta_cluster *cluster = NULL;
2577 struct meta_cluster_header *header;
2578 struct mdrestore_struct mdrestore;
2579 struct btrfs_fs_info *info = NULL;
2584 if (!strcmp(input, "-")) {
2587 in = fopen(input, "r");
2589 error("unable to open metadump image: %s",
2595 /* NOTE: open with write mode */
2597 info = open_ctree_fs_info(target, 0, 0, 0,
2599 OPEN_CTREE_RESTORE |
2600 OPEN_CTREE_PARTIAL);
2602 error("open ctree failed");
2608 cluster = malloc(BLOCK_SIZE);
2610 error("not enough memory for cluster");
2615 ret = mdrestore_init(&mdrestore, in, out, old_restore, num_threads,
2616 fixup_offset, info, multi_devices);
2618 error("failed to initialize metadata restore state: %d", ret);
2619 goto failed_cluster;
2622 if (!multi_devices && !old_restore) {
2623 ret = build_chunk_tree(&mdrestore, cluster);
2626 if (!list_empty(&mdrestore.overlapping_chunks))
2627 remap_overlapping_chunks(&mdrestore);
2630 if (in != stdin && fseek(in, 0, SEEK_SET)) {
2631 error("seek failed: %s", strerror(errno));
2635 while (!mdrestore.error) {
2636 ret = fread(cluster, BLOCK_SIZE, 1, in);
2640 header = &cluster->header;
2641 if (le64_to_cpu(header->magic) != HEADER_MAGIC ||
2642 le64_to_cpu(header->bytenr) != bytenr) {
2643 error("bad header in metadump image");
2647 ret = add_cluster(cluster, &mdrestore, &bytenr);
2649 error("failed to add cluster: %d", ret);
2653 ret = wait_for_worker(&mdrestore);
2655 if (!ret && !multi_devices && !old_restore) {
2656 struct btrfs_root *root;
2659 root = open_ctree_fd(fileno(out), target, 0,
2660 OPEN_CTREE_PARTIAL |
2662 OPEN_CTREE_NO_DEVICES);
2664 error("open ctree failed in %s", target);
2668 info = root->fs_info;
2670 if (stat(target, &st)) {
2671 error("stat %s failed: %s", target, strerror(errno));
2672 close_ctree(info->chunk_root);
2677 ret = fixup_devices(info, &mdrestore, st.st_size);
2678 close_ctree(info->chunk_root);
2683 mdrestore_destroy(&mdrestore, num_threads);
2687 if (fixup_offset && info)
2688 close_ctree(info->chunk_root);
2695 static int update_disk_super_on_device(struct btrfs_fs_info *info,
2696 const char *other_dev, u64 cur_devid)
2698 struct btrfs_key key;
2699 struct extent_buffer *leaf;
2700 struct btrfs_path path;
2701 struct btrfs_dev_item *dev_item;
2702 struct btrfs_super_block *disk_super;
2703 char dev_uuid[BTRFS_UUID_SIZE];
2704 char fs_uuid[BTRFS_UUID_SIZE];
2705 u64 devid, type, io_align, io_width;
2706 u64 sector_size, total_bytes, bytes_used;
2707 char buf[BTRFS_SUPER_INFO_SIZE];
2711 key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
2712 key.type = BTRFS_DEV_ITEM_KEY;
2713 key.offset = cur_devid;
2715 btrfs_init_path(&path);
2716 ret = btrfs_search_slot(NULL, info->chunk_root, &key, &path, 0, 0);
2718 error("search key failed: %d", ret);
2723 leaf = path.nodes[0];
2724 dev_item = btrfs_item_ptr(leaf, path.slots[0],
2725 struct btrfs_dev_item);
2727 devid = btrfs_device_id(leaf, dev_item);
2728 if (devid != cur_devid) {
2729 error("devid mismatch: %llu != %llu",
2730 (unsigned long long)devid,
2731 (unsigned long long)cur_devid);
2736 type = btrfs_device_type(leaf, dev_item);
2737 io_align = btrfs_device_io_align(leaf, dev_item);
2738 io_width = btrfs_device_io_width(leaf, dev_item);
2739 sector_size = btrfs_device_sector_size(leaf, dev_item);
2740 total_bytes = btrfs_device_total_bytes(leaf, dev_item);
2741 bytes_used = btrfs_device_bytes_used(leaf, dev_item);
2742 read_extent_buffer(leaf, dev_uuid, (unsigned long)btrfs_device_uuid(dev_item), BTRFS_UUID_SIZE);
2743 read_extent_buffer(leaf, fs_uuid, (unsigned long)btrfs_device_fsid(dev_item), BTRFS_UUID_SIZE);
2745 btrfs_release_path(&path);
2747 printf("update disk super on %s devid=%llu\n", other_dev, devid);
2749 /* update other devices' super block */
2750 fp = open(other_dev, O_CREAT | O_RDWR, 0600);
2752 error("could not open %s: %s", other_dev, strerror(errno));
2757 memcpy(buf, info->super_copy, BTRFS_SUPER_INFO_SIZE);
2759 disk_super = (struct btrfs_super_block *)buf;
2760 dev_item = &disk_super->dev_item;
2762 btrfs_set_stack_device_type(dev_item, type);
2763 btrfs_set_stack_device_id(dev_item, devid);
2764 btrfs_set_stack_device_total_bytes(dev_item, total_bytes);
2765 btrfs_set_stack_device_bytes_used(dev_item, bytes_used);
2766 btrfs_set_stack_device_io_align(dev_item, io_align);
2767 btrfs_set_stack_device_io_width(dev_item, io_width);
2768 btrfs_set_stack_device_sector_size(dev_item, sector_size);
2769 memcpy(dev_item->uuid, dev_uuid, BTRFS_UUID_SIZE);
2770 memcpy(dev_item->fsid, fs_uuid, BTRFS_UUID_SIZE);
2771 csum_block((u8 *)buf, BTRFS_SUPER_INFO_SIZE);
2773 ret = pwrite64(fp, buf, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
2774 if (ret != BTRFS_SUPER_INFO_SIZE) {
2776 error("cannot write superblock: %s", strerror(ret));
2778 error("cannot write superblock");
2783 write_backup_supers(fp, (u8 *)buf);
2791 static void print_usage(int ret)
2793 printf("usage: btrfs-image [options] source target\n");
2794 printf("\t-r \trestore metadump image\n");
2795 printf("\t-c value\tcompression level (0 ~ 9)\n");
2796 printf("\t-t value\tnumber of threads (1 ~ 32)\n");
2797 printf("\t-o \tdon't mess with the chunk tree when restoring\n");
2798 printf("\t-s \tsanitize file names, use once to just use garbage, use twice if you want crc collisions\n");
2799 printf("\t-w \twalk all trees instead of using extent tree, do this if your extent tree is broken\n");
2800 printf("\t-m \trestore for multiple devices\n");
2802 printf("\tIn the dump mode, source is the btrfs device and target is the output file (use '-' for stdout).\n");
2803 printf("\tIn the restore mode, source is the dumped image and target is the btrfs device/file.\n");
2807 int main(int argc, char *argv[])
2811 u64 num_threads = 0;
2812 u64 compress_level = 0;
2814 int old_restore = 0;
2816 int multi_devices = 0;
2818 enum sanitize_mode sanitize = SANITIZE_NONE;
2820 int usage_error = 0;
2824 static const struct option long_options[] = {
2825 { "help", no_argument, NULL, GETOPT_VAL_HELP},
2826 { NULL, 0, NULL, 0 }
2828 int c = getopt_long(argc, argv, "rc:t:oswm", long_options, NULL);
2836 num_threads = arg_strtou64(optarg);
2837 if (num_threads > MAX_WORKER_THREADS) {
2838 error("number of threads out of range: %llu > %d",
2839 (unsigned long long)num_threads,
2840 MAX_WORKER_THREADS);
2845 compress_level = arg_strtou64(optarg);
2846 if (compress_level > 9) {
2847 error("compression level out of range: %llu",
2848 (unsigned long long)compress_level);
2856 if (sanitize == SANITIZE_NONE)
2857 sanitize = SANITIZE_NAMES;
2858 else if (sanitize == SANITIZE_NAMES)
2859 sanitize = SANITIZE_COLLISIONS;
2868 case GETOPT_VAL_HELP:
2870 print_usage(c != GETOPT_VAL_HELP);
2875 if (check_argc_min(argc - optind, 2))
2878 dev_cnt = argc - optind - 1;
2883 "create and restore cannot be used at the same time");
2887 if (walk_trees || sanitize != SANITIZE_NONE || compress_level) {
2889 "useing -w, -s, -c options for restore makes no sense");
2892 if (multi_devices && dev_cnt < 2) {
2893 error("not enough devices specified for -m option");
2896 if (!multi_devices && dev_cnt != 1) {
2897 error("accepts only 1 device without -m option");
2905 source = argv[optind];
2906 target = argv[optind + 1];
2908 if (create && !strcmp(target, "-")) {
2911 out = fopen(target, "w+");
2913 error("unable to create target file %s", target);
2918 if (compress_level > 0 || create == 0) {
2919 if (num_threads == 0) {
2920 long tmp = sysconf(_SC_NPROCESSORS_ONLN);
2931 ret = check_mounted(source);
2933 warning("unable to check mount status of: %s",
2936 warning("%s already mounted, results may be inaccurate",
2940 ret = create_metadump(source, out, num_threads,
2941 compress_level, sanitize, walk_trees);
2943 ret = restore_metadump(source, out, old_restore, num_threads,
2944 0, target, multi_devices);
2947 error("%s failed: %s", (create) ? "create" : "restore",
2952 /* extended support for multiple devices */
2953 if (!create && multi_devices) {
2954 struct btrfs_fs_info *info;
2958 info = open_ctree_fs_info(target, 0, 0, 0,
2959 OPEN_CTREE_PARTIAL |
2960 OPEN_CTREE_RESTORE);
2962 error("open ctree failed at %s", target);
2966 total_devs = btrfs_super_num_devices(info->super_copy);
2967 if (total_devs != dev_cnt) {
2968 error("it needs %llu devices but has only %d",
2969 total_devs, dev_cnt);
2970 close_ctree(info->chunk_root);
2974 /* update super block on other disks */
2975 for (i = 2; i <= dev_cnt; i++) {
2976 ret = update_disk_super_on_device(info,
2977 argv[optind + i], (u64)i);
2979 error("update disk superblock failed devid %d: %d",
2981 close_ctree(info->chunk_root);
2986 close_ctree(info->chunk_root);
2988 /* fix metadata block to map correct chunk */
2989 ret = restore_metadump(source, out, 0, num_threads, 1,
2992 error("unable to fixup metadump: %d", ret);
2997 if (out == stdout) {
3001 if (ret && create) {
3004 unlink_ret = unlink(target);
3006 error("unlink output file %s failed: %s",
3007 target, strerror(errno));
3011 btrfs_close_all_devices();