btrfs-progs: fix regexec to only work if we actually have a regexec
[platform/upstream/btrfs-progs.git] / cmds-restore.c
1 /*
2  * Copyright (C) 2011 Red Hat.  All rights reserved.
3  *
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.
7  *
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.
12  *
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.
17  */
18
19 #define _XOPEN_SOURCE 500
20 #define _GNU_SOURCE 1
21
22 #include "kerncompat.h"
23
24 #include <ctype.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <lzo/lzoconf.h>
32 #include <lzo/lzo1x.h>
33 #include <zlib.h>
34 #include <regex.h>
35
36 #include "ctree.h"
37 #include "disk-io.h"
38 #include "print-tree.h"
39 #include "transaction.h"
40 #include "list.h"
41 #include "version.h"
42 #include "volumes.h"
43 #include "utils.h"
44 #include "commands.h"
45
46 static char fs_name[4096];
47 static char path_name[4096];
48 static int get_snaps = 0;
49 static int verbose = 0;
50 static int ignore_errors = 0;
51 static int overwrite = 0;
52
53 #define LZO_LEN 4
54 #define PAGE_CACHE_SIZE 4096
55 #define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)
56
57 static int decompress_zlib(char *inbuf, char *outbuf, u64 compress_len,
58                            u64 decompress_len)
59 {
60         z_stream strm;
61         int ret;
62
63         memset(&strm, 0, sizeof(strm));
64         ret = inflateInit(&strm);
65         if (ret != Z_OK) {
66                 fprintf(stderr, "inflate init returnd %d\n", ret);
67                 return -1;
68         }
69
70         strm.avail_in = compress_len;
71         strm.next_in = (unsigned char *)inbuf;
72         strm.avail_out = decompress_len;
73         strm.next_out = (unsigned char *)outbuf;
74         ret = inflate(&strm, Z_NO_FLUSH);
75         if (ret != Z_STREAM_END) {
76                 (void)inflateEnd(&strm);
77                 fprintf(stderr, "failed to inflate: %d\n", ret);
78                 return -1;
79         }
80
81         (void)inflateEnd(&strm);
82         return 0;
83 }
84 static inline size_t read_compress_length(unsigned char *buf)
85 {
86         __le32 dlen;
87         memcpy(&dlen, buf, LZO_LEN);
88         return le32_to_cpu(dlen);
89 }
90
91 static int decompress_lzo(unsigned char *inbuf, char *outbuf, u64 compress_len,
92                           u64 *decompress_len)
93 {
94         size_t new_len;
95         size_t in_len;
96         size_t out_len = 0;
97         size_t tot_len;
98         size_t tot_in;
99         int ret;
100
101         ret = lzo_init();
102         if (ret != LZO_E_OK) {
103                 fprintf(stderr, "lzo init returned %d\n", ret);
104                 return -1;
105         }
106
107         tot_len = read_compress_length(inbuf);
108         inbuf += LZO_LEN;
109         tot_in = LZO_LEN;
110
111         while (tot_in < tot_len) {
112                 in_len = read_compress_length(inbuf);
113                 inbuf += LZO_LEN;
114                 tot_in += LZO_LEN;
115
116                 new_len = lzo1x_worst_compress(PAGE_CACHE_SIZE);
117                 ret = lzo1x_decompress_safe((const unsigned char *)inbuf, in_len,
118                                             (unsigned char *)outbuf,
119                                             (void *)&new_len, NULL);
120                 if (ret != LZO_E_OK) {
121                         fprintf(stderr, "failed to inflate: %d\n", ret);
122                         return -1;
123                 }
124                 out_len += new_len;
125                 outbuf += new_len;
126                 inbuf += in_len;
127                 tot_in += in_len;
128         }
129
130         *decompress_len = out_len;
131
132         return 0;
133 }
134
135 static int decompress(char *inbuf, char *outbuf, u64 compress_len,
136                       u64 *decompress_len, int compress)
137 {
138         switch (compress) {
139         case BTRFS_COMPRESS_ZLIB:
140                 return decompress_zlib(inbuf, outbuf, compress_len,
141                                        *decompress_len);
142         case BTRFS_COMPRESS_LZO:
143                 return decompress_lzo((unsigned char *)inbuf, outbuf, compress_len,
144                                       decompress_len);
145         default:
146                 break;
147         }
148
149         fprintf(stderr, "invalid compression type: %d\n", compress);
150         return -1;
151 }
152
153 int next_leaf(struct btrfs_root *root, struct btrfs_path *path)
154 {
155         int slot;
156         int level = 1;
157         int offset = 1;
158         struct extent_buffer *c;
159         struct extent_buffer *next = NULL;
160
161 again:
162         for (; level < BTRFS_MAX_LEVEL; level++) {
163                 if (path->nodes[level])
164                         break;
165         }
166
167         if (level == BTRFS_MAX_LEVEL)
168                 return 1;
169
170         slot = path->slots[level] + 1;
171
172         while(level < BTRFS_MAX_LEVEL) {
173                 if (!path->nodes[level])
174                         return 1;
175
176                 slot = path->slots[level] + offset;
177                 c = path->nodes[level];
178                 if (slot >= btrfs_header_nritems(c)) {
179                         level++;
180                         if (level == BTRFS_MAX_LEVEL)
181                                 return 1;
182                         continue;
183                 }
184
185                 if (path->reada)
186                         reada_for_search(root, path, level, slot, 0);
187
188                 next = read_node_slot(root, c, slot);
189                 if (next)
190                         break;
191                 offset++;
192         }
193         path->slots[level] = slot;
194         while(1) {
195                 level--;
196                 c = path->nodes[level];
197                 free_extent_buffer(c);
198                 path->nodes[level] = next;
199                 path->slots[level] = 0;
200                 if (!level)
201                         break;
202                 if (path->reada)
203                         reada_for_search(root, path, level, 0, 0);
204                 next = read_node_slot(root, next, 0);
205                 if (!next)
206                         goto again;
207         }
208         return 0;
209 }
210
211 static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
212 {
213         struct extent_buffer *leaf = path->nodes[0];
214         struct btrfs_file_extent_item *fi;
215         char buf[4096];
216         char *outbuf;
217         u64 ram_size;
218         ssize_t done;
219         unsigned long ptr;
220         int ret;
221         int len;
222         int compress;
223
224         fi = btrfs_item_ptr(leaf, path->slots[0],
225                             struct btrfs_file_extent_item);
226         ptr = btrfs_file_extent_inline_start(fi);
227         len = btrfs_file_extent_inline_item_len(leaf,
228                                         btrfs_item_nr(leaf, path->slots[0]));
229         read_extent_buffer(leaf, buf, ptr, len);
230
231         compress = btrfs_file_extent_compression(leaf, fi);
232         if (compress == BTRFS_COMPRESS_NONE) {
233                 done = pwrite(fd, buf, len, pos);
234                 if (done < len) {
235                         fprintf(stderr, "Short inline write, wanted %d, did "
236                                 "%zd: %d\n", len, done, errno);
237                         return -1;
238                 }
239                 return 0;
240         }
241
242         ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
243         outbuf = malloc(ram_size);
244         if (!outbuf) {
245                 fprintf(stderr, "No memory\n");
246                 return -1;
247         }
248
249         ret = decompress(buf, outbuf, len, &ram_size, compress);
250         if (ret) {
251                 free(outbuf);
252                 return ret;
253         }
254
255         done = pwrite(fd, outbuf, ram_size, pos);
256         free(outbuf);
257         if (done < ram_size) {
258                 fprintf(stderr, "Short compressed inline write, wanted %Lu, "
259                         "did %zd: %d\n", ram_size, done, errno);
260                 return -1;
261         }
262
263         return 0;
264 }
265
266 static int copy_one_extent(struct btrfs_root *root, int fd,
267                            struct extent_buffer *leaf,
268                            struct btrfs_file_extent_item *fi, u64 pos)
269 {
270         struct btrfs_multi_bio *multi = NULL;
271         struct btrfs_device *device;
272         char *inbuf, *outbuf = NULL;
273         ssize_t done, total = 0;
274         u64 bytenr;
275         u64 ram_size;
276         u64 disk_size;
277         u64 length;
278         u64 size_left;
279         u64 dev_bytenr;
280         u64 offset;
281         u64 count = 0;
282         int compress;
283         int ret;
284         int dev_fd;
285         int mirror_num = 1;
286         int num_copies;
287
288         compress = btrfs_file_extent_compression(leaf, fi);
289         bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
290         disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi);
291         ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
292         offset = btrfs_file_extent_offset(leaf, fi);
293         size_left = disk_size;
294
295         if (offset)
296                 printf("offset is %Lu\n", offset);
297         /* we found a hole */
298         if (disk_size == 0)
299                 return 0;
300
301         inbuf = malloc(disk_size);
302         if (!inbuf) {
303                 fprintf(stderr, "No memory\n");
304                 return -1;
305         }
306
307         if (compress != BTRFS_COMPRESS_NONE) {
308                 outbuf = malloc(ram_size);
309                 if (!outbuf) {
310                         fprintf(stderr, "No memory\n");
311                         free(inbuf);
312                         return -1;
313                 }
314         }
315 again:
316         length = size_left;
317         ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
318                               bytenr, &length, &multi, mirror_num, NULL);
319         if (ret) {
320                 fprintf(stderr, "Error mapping block %d\n", ret);
321                 goto out;
322         }
323         device = multi->stripes[0].dev;
324         dev_fd = device->fd;
325         device->total_ios++;
326         dev_bytenr = multi->stripes[0].physical;
327         kfree(multi);
328
329         if (size_left < length)
330                 length = size_left;
331
332         done = pread(dev_fd, inbuf+count, length, dev_bytenr);
333         /* Need both checks, or we miss negative values due to u64 conversion */
334         if (done < 0 || done < length) {
335                 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
336                                               bytenr, length);
337                 mirror_num++;
338                 /* mirror_num is 1-indexed, so num_copies is a valid mirror. */
339                 if (mirror_num > num_copies) {
340                         ret = -1;
341                         fprintf(stderr, "Exhausted mirrors trying to read\n");
342                         goto out;
343                 }
344                 fprintf(stderr, "Trying another mirror\n");
345                 goto again;
346         }
347
348         mirror_num = 1;
349         size_left -= length;
350         count += length;
351         bytenr += length;
352         if (size_left)
353                 goto again;
354
355         if (compress == BTRFS_COMPRESS_NONE) {
356                 while (total < ram_size) {
357                         done = pwrite(fd, inbuf+total, ram_size-total,
358                                       pos+total);
359                         if (done < 0) {
360                                 ret = -1;
361                                 fprintf(stderr, "Error writing: %d %s\n", errno, strerror(errno));
362                                 goto out;
363                         }
364                         total += done;
365                 }
366                 ret = 0;
367                 goto out;
368         }
369
370         ret = decompress(inbuf, outbuf, disk_size, &ram_size, compress);
371         if (ret) {
372                 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
373                                               bytenr, length);
374                 mirror_num++;
375                 if (mirror_num >= num_copies) {
376                         ret = -1;
377                         goto out;
378                 }
379                 fprintf(stderr, "Trying another mirror\n");
380                 goto again;
381         }
382
383         while (total < ram_size) {
384                 done = pwrite(fd, outbuf+total, ram_size-total, pos+total);
385                 if (done < 0) {
386                         ret = -1;
387                         goto out;
388                 }
389                 total += done;
390         }
391 out:
392         free(inbuf);
393         free(outbuf);
394         return ret;
395 }
396
397 static int ask_to_continue(const char *file)
398 {
399         char buf[2];
400         char *ret;
401
402         printf("We seem to be looping a lot on %s, do you want to keep going "
403                "on ? (y/N): ", file);
404 again:
405         ret = fgets(buf, 2, stdin);
406         if (*ret == '\n' || tolower(*ret) == 'n')
407                 return 1;
408         if (tolower(*ret) != 'y') {
409                 printf("Please enter either 'y' or 'n': ");
410                 goto again;
411         }
412
413         return 0;
414 }
415
416
417 static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key,
418                      const char *file)
419 {
420         struct extent_buffer *leaf;
421         struct btrfs_path *path;
422         struct btrfs_file_extent_item *fi;
423         struct btrfs_inode_item *inode_item;
424         struct btrfs_key found_key;
425         int ret;
426         int extent_type;
427         int compression;
428         int loops = 0;
429         u64 found_size = 0;
430
431         path = btrfs_alloc_path();
432         if (!path) {
433                 fprintf(stderr, "Ran out of memory\n");
434                 return -1;
435         }
436         path->skip_locking = 1;
437
438         ret = btrfs_lookup_inode(NULL, root, path, key, 0);
439         if (ret == 0) {
440                 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
441                                     struct btrfs_inode_item);
442                 found_size = btrfs_inode_size(path->nodes[0], inode_item);
443         }
444         btrfs_release_path(root, path);
445
446         key->offset = 0;
447         key->type = BTRFS_EXTENT_DATA_KEY;
448
449         ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
450         if (ret < 0) {
451                 fprintf(stderr, "Error searching %d\n", ret);
452                 btrfs_free_path(path);
453                 return ret;
454         }
455
456         leaf = path->nodes[0];
457         while (!leaf) {
458                 ret = next_leaf(root, path);
459                 if (ret < 0) {
460                         fprintf(stderr, "Error getting next leaf %d\n",
461                                 ret);
462                         btrfs_free_path(path);
463                         return ret;
464                 } else if (ret > 0) {
465                         /* No more leaves to search */
466                         btrfs_free_path(path);
467                         return 0;
468                 }
469                 leaf = path->nodes[0];
470         }
471
472         while (1) {
473                 if (loops++ >= 1024) {
474                         ret = ask_to_continue(file);
475                         if (ret)
476                                 break;
477                         loops = 0;
478                 }
479                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
480                         do {
481                                 ret = next_leaf(root, path);
482                                 if (ret < 0) {
483                                         fprintf(stderr, "Error searching %d\n", ret);
484                                         btrfs_free_path(path);
485                                         return ret;
486                                 } else if (ret) {
487                                         /* No more leaves to search */
488                                         btrfs_free_path(path);
489                                         goto set_size;
490                                 }
491                                 leaf = path->nodes[0];
492                         } while (!leaf);
493                         continue;
494                 }
495                 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
496                 if (found_key.objectid != key->objectid)
497                         break;
498                 if (found_key.type != key->type)
499                         break;
500                 fi = btrfs_item_ptr(leaf, path->slots[0],
501                                     struct btrfs_file_extent_item);
502                 extent_type = btrfs_file_extent_type(leaf, fi);
503                 compression = btrfs_file_extent_compression(leaf, fi);
504                 if (compression >= BTRFS_COMPRESS_LAST) {
505                         fprintf(stderr, "Don't support compression yet %d\n",
506                                 compression);
507                         btrfs_free_path(path);
508                         return -1;
509                 }
510
511                 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC)
512                         goto next;
513                 if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
514                         ret = copy_one_inline(fd, path, found_key.offset);
515                         if (ret) {
516                                 btrfs_free_path(path);
517                                 return -1;
518                         }
519                 } else if (extent_type == BTRFS_FILE_EXTENT_REG) {
520                         ret = copy_one_extent(root, fd, leaf, fi,
521                                               found_key.offset);
522                         if (ret) {
523                                 btrfs_free_path(path);
524                                 return ret;
525                         }
526                 } else {
527                         printf("Weird extent type %d\n", extent_type);
528                 }
529 next:
530                 path->slots[0]++;
531         }
532
533         btrfs_free_path(path);
534 set_size:
535         if (found_size) {
536                 ret = ftruncate(fd, (loff_t)found_size);
537                 if (ret)
538                         return ret;
539         }
540         return 0;
541 }
542
543 static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
544                       const char *output_rootdir, const char *dir,
545                       const regex_t *mreg)
546 {
547         struct btrfs_path *path;
548         struct extent_buffer *leaf;
549         struct btrfs_dir_item *dir_item;
550         struct btrfs_key found_key, location;
551         char filename[BTRFS_NAME_LEN + 1];
552         unsigned long name_ptr;
553         int name_len;
554         int ret;
555         int fd;
556         int loops = 0;
557         u8 type;
558
559         path = btrfs_alloc_path();
560         if (!path) {
561                 fprintf(stderr, "Ran out of memory\n");
562                 return -1;
563         }
564         path->skip_locking = 1;
565
566         key->offset = 0;
567         key->type = BTRFS_DIR_INDEX_KEY;
568
569         ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
570         if (ret < 0) {
571                 fprintf(stderr, "Error searching %d\n", ret);
572                 btrfs_free_path(path);
573                 return ret;
574         }
575
576         leaf = path->nodes[0];
577         while (!leaf) {
578                 if (verbose > 1)
579                         printf("No leaf after search, looking for the next "
580                                "leaf\n");
581                 ret = next_leaf(root, path);
582                 if (ret < 0) {
583                         fprintf(stderr, "Error getting next leaf %d\n",
584                                 ret);
585                         btrfs_free_path(path);
586                         return ret;
587                 } else if (ret > 0) {
588                         /* No more leaves to search */
589                         if (verbose)
590                                 printf("Reached the end of the tree looking "
591                                        "for the directory\n");
592                         btrfs_free_path(path);
593                         return 0;
594                 }
595                 leaf = path->nodes[0];
596         }
597
598         while (leaf) {
599                 if (loops++ >= 1024) {
600                         printf("We have looped trying to restore files in %s "
601                                "too many times to be making progress, "
602                                "stopping\n", dir);
603                         break;
604                 }
605
606                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
607                         do {
608                                 ret = next_leaf(root, path);
609                                 if (ret < 0) {
610                                         fprintf(stderr, "Error searching %d\n",
611                                                 ret);
612                                         btrfs_free_path(path);
613                                         return ret;
614                                 } else if (ret > 0) {
615                                         /* No more leaves to search */
616                                         if (verbose)
617                                                 printf("Reached the end of "
618                                                        "the tree searching the"
619                                                        " directory\n");
620                                         btrfs_free_path(path);
621                                         return 0;
622                                 }
623                                 leaf = path->nodes[0];
624                         } while (!leaf);
625                         continue;
626                 }
627                 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
628                 if (found_key.objectid != key->objectid) {
629                         if (verbose > 1)
630                                 printf("Found objectid=%Lu, key=%Lu\n",
631                                        found_key.objectid, key->objectid);
632                         break;
633                 }
634                 if (found_key.type != key->type) {
635                         if (verbose > 1)
636                                 printf("Found type=%u, want=%u\n",
637                                        found_key.type, key->type);
638                         break;
639                 }
640                 dir_item = btrfs_item_ptr(leaf, path->slots[0],
641                                           struct btrfs_dir_item);
642                 name_ptr = (unsigned long)(dir_item + 1);
643                 name_len = btrfs_dir_name_len(leaf, dir_item);
644                 read_extent_buffer(leaf, filename, name_ptr, name_len);
645                 filename[name_len] = '\0';
646                 type = btrfs_dir_type(leaf, dir_item);
647                 btrfs_dir_item_key_to_cpu(leaf, dir_item, &location);
648
649                 /* full path from root of btrfs being restored */
650                 snprintf(fs_name, 4096, "%s/%s", dir, filename);
651
652                 if (mreg && REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
653                         goto next;
654
655                 /* full path from system root */
656                 snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
657
658                 /*
659                  * At this point we're only going to restore directories and
660                  * files, no symlinks or anything else.
661                  */
662                 if (type == BTRFS_FT_REG_FILE) {
663                         if (!overwrite) {
664                                 static int warn = 0;
665                                 struct stat st;
666
667                                 ret = stat(path_name, &st);
668                                 if (!ret) {
669                                         loops = 0;
670                                         if (verbose || !warn)
671                                                 printf("Skipping existing file"
672                                                        " %s\n", path_name);
673                                         if (warn)
674                                                 goto next;
675                                         printf("If you wish to overwrite use "
676                                                "the -o option to overwrite\n");
677                                         warn = 1;
678                                         goto next;
679                                 }
680                                 ret = 0;
681                         }
682                         if (verbose)
683                                 printf("Restoring %s\n", path_name);
684                         fd = open(path_name, O_CREAT|O_WRONLY, 0644);
685                         if (fd < 0) {
686                                 fprintf(stderr, "Error creating %s: %d\n",
687                                         path_name, errno);
688                                 if (ignore_errors)
689                                         goto next;
690                                 btrfs_free_path(path);
691                                 return -1;
692                         }
693                         loops = 0;
694                         ret = copy_file(root, fd, &location, path_name);
695                         close(fd);
696                         if (ret) {
697                                 if (ignore_errors)
698                                         goto next;
699                                 btrfs_free_path(path);
700                                 return ret;
701                         }
702                 } else if (type == BTRFS_FT_DIR) {
703                         struct btrfs_root *search_root = root;
704                         char *dir = strdup(fs_name);
705
706                         if (!dir) {
707                                 fprintf(stderr, "Ran out of memory\n");
708                                 btrfs_free_path(path);
709                                 return -1;
710                         }
711
712                         if (location.type == BTRFS_ROOT_ITEM_KEY) {
713                                 /*
714                                  * If we are a snapshot and this is the index
715                                  * object to ourselves just skip it.
716                                  */
717                                 if (location.objectid ==
718                                     root->root_key.objectid) {
719                                         free(dir);
720                                         goto next;
721                                 }
722
723                                 location.offset = (u64)-1;
724                                 search_root = btrfs_read_fs_root(root->fs_info,
725                                                                  &location);
726                                 if (IS_ERR(search_root)) {
727                                         free(dir);
728                                         fprintf(stderr, "Error reading "
729                                                 "subvolume %s: %lu\n",
730                                                 path_name,
731                                                 PTR_ERR(search_root));
732                                         if (ignore_errors)
733                                                 goto next;
734                                         btrfs_free_path(path);
735                                         return PTR_ERR(search_root);
736                                 }
737
738                                 /*
739                                  * A subvolume will have a key.offset of 0, a
740                                  * snapshot will have key.offset of a transid.
741                                  */
742                                 if (search_root->root_key.offset != 0 &&
743                                     get_snaps == 0) {
744                                         free(dir);
745                                         printf("Skipping snapshot %s\n",
746                                                filename);
747                                         goto next;
748                                 }
749                                 location.objectid = BTRFS_FIRST_FREE_OBJECTID;
750                         }
751
752                         if (verbose)
753                                 printf("Restoring %s\n", path_name);
754
755                         errno = 0;
756                         ret = mkdir(path_name, 0755);
757                         if (ret && errno != EEXIST) {
758                                 free(dir);
759                                 fprintf(stderr, "Error mkdiring %s: %d\n",
760                                         path_name, errno);
761                                 if (ignore_errors)
762                                         goto next;
763                                 btrfs_free_path(path);
764                                 return -1;
765                         }
766                         loops = 0;
767                         ret = search_dir(search_root, &location,
768                                          output_rootdir, dir, mreg);
769                         free(dir);
770                         if (ret) {
771                                 if (ignore_errors)
772                                         goto next;
773                                 btrfs_free_path(path);
774                                 return ret;
775                         }
776                 }
777 next:
778                 path->slots[0]++;
779         }
780
781         if (verbose)
782                 printf("Done searching %s\n", dir);
783         btrfs_free_path(path);
784         return 0;
785 }
786
787 static int do_list_roots(struct btrfs_root *root)
788 {
789         struct btrfs_key key;
790         struct btrfs_key found_key;
791         struct btrfs_disk_key disk_key;
792         struct btrfs_path *path;
793         struct extent_buffer *leaf;
794         struct btrfs_root_item ri;
795         unsigned long offset;
796         int slot;
797         int ret;
798
799         root = root->fs_info->tree_root;
800         path = btrfs_alloc_path();
801         if (!path) {
802                 fprintf(stderr, "Failed to alloc path\n");
803                 return -1;
804         }
805
806         key.offset = 0;
807         key.objectid = 0;
808         key.type = BTRFS_ROOT_ITEM_KEY;
809
810         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
811         if (ret < 0) {
812                 fprintf(stderr, "Failed to do search %d\n", ret);
813                 btrfs_free_path(path);
814                 return -1;
815         }
816
817         while (1) {
818                 leaf = path->nodes[0];
819                 slot = path->slots[0];
820                 if (slot >= btrfs_header_nritems(leaf)) {
821                         ret = btrfs_next_leaf(root, path);
822                         if (ret)
823                                 break;
824                         leaf = path->nodes[0];
825                         slot = path->slots[0];
826                 }
827                 btrfs_item_key(leaf, &disk_key, slot);
828                 btrfs_disk_key_to_cpu(&found_key, &disk_key);
829                 if (btrfs_key_type(&found_key) != BTRFS_ROOT_ITEM_KEY) {
830                         path->slots[0]++;
831                         continue;
832                 }
833
834                 offset = btrfs_item_ptr_offset(leaf, slot);
835                 read_extent_buffer(leaf, &ri, offset, sizeof(ri));
836                 printf(" tree ");
837                 btrfs_print_key(&disk_key);
838                 printf(" %Lu level %d\n", btrfs_root_bytenr(&ri),
839                        btrfs_root_level(&ri));
840                 path->slots[0]++;
841         }
842         btrfs_free_path(path);
843
844         return 0;
845 }
846
847 static struct btrfs_root *open_fs(const char *dev, u64 root_location,
848                                   int super_mirror, int list_roots)
849 {
850         struct btrfs_fs_info *fs_info = NULL;
851         struct btrfs_root *root = NULL;
852         u64 bytenr;
853         int i;
854
855         for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
856                 bytenr = btrfs_sb_offset(i);
857                 fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0, 1);
858                 if (fs_info)
859                         break;
860                 fprintf(stderr, "Could not open root, trying backup super\n");
861         }
862
863         if (!fs_info)
864                 return NULL;
865
866         /*
867          * All we really need to succeed is reading the chunk tree, everything
868          * else we can do by hand, since we only need to read the tree root and
869          * the fs_root.
870          */
871         if (!extent_buffer_uptodate(fs_info->tree_root->node)) {
872                 u64 generation;
873
874                 root = fs_info->tree_root;
875                 if (!root_location)
876                         root_location = btrfs_super_root(fs_info->super_copy);
877                 generation = btrfs_super_generation(fs_info->super_copy);
878                 root->node = read_tree_block(root, root_location,
879                                              root->leafsize, generation);
880                 if (!extent_buffer_uptodate(root->node)) {
881                         fprintf(stderr, "Error opening tree root\n");
882                         close_ctree(root);
883                         return NULL;
884                 }
885         }
886
887         if (!list_roots && !fs_info->fs_root) {
888                 struct btrfs_key key;
889
890                 key.objectid = BTRFS_FS_TREE_OBJECTID;
891                 key.type = BTRFS_ROOT_ITEM_KEY;
892                 key.offset = (u64)-1;
893                 fs_info->fs_root = btrfs_read_fs_root_no_cache(fs_info, &key);
894                 if (IS_ERR(fs_info->fs_root)) {
895                         fprintf(stderr, "Couldn't read fs root: %ld\n",
896                                 PTR_ERR(fs_info->fs_root));
897                         close_ctree(fs_info->tree_root);
898                         return NULL;
899                 }
900         }
901
902         if (list_roots && do_list_roots(fs_info->tree_root)) {
903                 close_ctree(fs_info->tree_root);
904                 return NULL;
905         }
906
907         return fs_info->fs_root;
908 }
909
910 static int find_first_dir(struct btrfs_root *root, u64 *objectid)
911 {
912         struct btrfs_path *path;
913         struct btrfs_key found_key;
914         struct btrfs_key key;
915         int ret = -1;
916         int i;
917
918         key.objectid = 0;
919         key.type = BTRFS_DIR_INDEX_KEY;
920         key.offset = 0;
921
922         path = btrfs_alloc_path();
923         if (!path) {
924                 fprintf(stderr, "Ran out of memory\n");
925                 return ret;
926         }
927
928         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
929         if (ret < 0) {
930                 fprintf(stderr, "Error searching %d\n", ret);
931                 goto out;
932         }
933
934         if (!path->nodes[0]) {
935                 fprintf(stderr, "No leaf!\n");
936                 goto out;
937         }
938 again:
939         for (i = path->slots[0];
940              i < btrfs_header_nritems(path->nodes[0]); i++) {
941                 btrfs_item_key_to_cpu(path->nodes[0], &found_key, i);
942                 if (found_key.type != key.type)
943                         continue;
944
945                 printf("Using objectid %Lu for first dir\n",
946                        found_key.objectid);
947                 *objectid = found_key.objectid;
948                 ret = 0;
949                 goto out;
950         }
951         do {
952                 ret = next_leaf(root, path);
953                 if (ret < 0) {
954                         fprintf(stderr, "Error getting next leaf %d\n",
955                                 ret);
956                         goto out;
957                 } else if (ret > 0) {
958                         fprintf(stderr, "No more leaves\n");
959                         goto out;
960                 }
961         } while (!path->nodes[0]);
962         if (path->nodes[0])
963                 goto again;
964         printf("Couldn't find a dir index item\n");
965 out:
966         btrfs_free_path(path);
967         return ret;
968 }
969
970 const char * const cmd_restore_usage[] = {
971         "btrfs restore [options] <device>",
972         "Try to restore files from a damaged filesystem (unmounted)",
973         "",
974         "-s              get snapshots",
975         "-v              verbose",
976         "-i              ignore errors",
977         "-o              overwrite",
978         "-t              tree location",
979         "-f <offset>     filesystem location",
980         "-u <block>      super mirror",
981         "-d              find dir",
982         NULL
983 };
984
985 int cmd_restore(int argc, char **argv)
986 {
987         struct btrfs_root *root;
988         struct btrfs_key key;
989         char dir_name[128];
990         u64 tree_location = 0;
991         u64 fs_location = 0;
992         u64 root_objectid = 0;
993         int len;
994         int ret;
995         int opt;
996         int super_mirror = 0;
997         int find_dir = 0;
998         int list_roots = 0;
999         const char *match_regstr = NULL;
1000         int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
1001         regex_t match_reg, *mreg = NULL;
1002         char reg_err[256];
1003
1004         while ((opt = getopt(argc, argv, "sviot:u:df:r:lcm:")) != -1) {
1005
1006                 switch (opt) {
1007                         case 's':
1008                                 get_snaps = 1;
1009                                 break;
1010                         case 'v':
1011                                 verbose++;
1012                                 break;
1013                         case 'i':
1014                                 ignore_errors = 1;
1015                                 break;
1016                         case 'o':
1017                                 overwrite = 1;
1018                                 break;
1019                         case 't':
1020                                 errno = 0;
1021                                 tree_location = (u64)strtoll(optarg, NULL, 10);
1022                                 if (errno != 0) {
1023                                         fprintf(stderr, "Tree location not valid\n");
1024                                         exit(1);
1025                                 }
1026                                 break;
1027                         case 'f':
1028                                 errno = 0;
1029                                 fs_location = (u64)strtoll(optarg, NULL, 10);
1030                                 if (errno != 0) {
1031                                         fprintf(stderr, "Fs location not valid\n");
1032                                         exit(1);
1033                                 }
1034                                 break;
1035                         case 'u':
1036                                 errno = 0;
1037                                 super_mirror = (int)strtol(optarg, NULL, 10);
1038                                 if (errno != 0 ||
1039                                     super_mirror >= BTRFS_SUPER_MIRROR_MAX) {
1040                                         fprintf(stderr, "Super mirror not "
1041                                                 "valid\n");
1042                                         exit(1);
1043                                 }
1044                                 break;
1045                         case 'd':
1046                                 find_dir = 1;
1047                                 break;
1048                         case 'r':
1049                                 errno = 0;
1050                                 root_objectid = (u64)strtoll(optarg, NULL, 10);
1051                                 if (errno != 0) {
1052                                         fprintf(stderr, "Root objectid not valid\n");
1053                                         exit(1);
1054                                 }
1055                                 break;
1056                         case 'l':
1057                                 list_roots = 1;
1058                                 break;
1059                         case 'c':
1060                                 match_cflags |= REG_ICASE;
1061                                 break;
1062                         case 'm':
1063                                 match_regstr = optarg;
1064                                 break;
1065                         default:
1066                                 usage(cmd_restore_usage);
1067                 }
1068         }
1069
1070         if (!list_roots && optind + 1 >= argc)
1071                 usage(cmd_restore_usage);
1072         else if (list_roots && optind >= argc)
1073                 usage(cmd_restore_usage);
1074
1075         if ((ret = check_mounted(argv[optind])) < 0) {
1076                 fprintf(stderr, "Could not check mount status: %s\n",
1077                         strerror(-ret));
1078                 return ret;
1079         } else if (ret) {
1080                 fprintf(stderr, "%s is currently mounted.  Aborting.\n", argv[optind]);
1081                 return 1;
1082         }
1083
1084         root = open_fs(argv[optind], tree_location, super_mirror, list_roots);
1085         if (root == NULL)
1086                 return 1;
1087
1088         if (list_roots)
1089                 goto out;
1090
1091         if (fs_location != 0) {
1092                 free_extent_buffer(root->node);
1093                 root->node = read_tree_block(root, fs_location, root->leafsize, 0);
1094                 if (!root->node) {
1095                         fprintf(stderr, "Failed to read fs location\n");
1096                         goto out;
1097                 }
1098         }
1099
1100         memset(path_name, 0, 4096);
1101
1102         strncpy(dir_name, argv[optind + 1], sizeof dir_name);
1103         dir_name[sizeof dir_name - 1] = 0;
1104
1105         /* Strip the trailing / on the dir name */
1106         len = strlen(dir_name);
1107         while (len && dir_name[--len] == '/') {
1108                 dir_name[len] = '\0';
1109         }
1110
1111         if (root_objectid != 0) {
1112                 struct btrfs_root *orig_root = root;
1113
1114                 key.objectid = root_objectid;
1115                 key.type = BTRFS_ROOT_ITEM_KEY;
1116                 key.offset = (u64)-1;
1117                 root = btrfs_read_fs_root(orig_root->fs_info, &key);
1118                 if (IS_ERR(root)) {
1119                         fprintf(stderr, "Error reading root\n");
1120                         root = orig_root;
1121                         ret = 1;
1122                         goto out;
1123                 }
1124                 key.type = 0;
1125                 key.offset = 0;
1126         }
1127
1128         if (find_dir) {
1129                 ret = find_first_dir(root, &key.objectid);
1130                 if (ret)
1131                         goto out;
1132         } else {
1133                 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
1134         }
1135
1136         if (match_regstr) {
1137                 ret = regcomp(&match_reg, match_regstr, match_cflags);
1138                 if (ret) {
1139                         regerror(ret, &match_reg, reg_err, sizeof(reg_err));
1140                         fprintf(stderr, "Regex compile failed: %s\n", reg_err);
1141                         goto out;
1142                 }
1143                 mreg = &match_reg;
1144         }
1145
1146         ret = search_dir(root, &key, dir_name, "", mreg);
1147
1148 out:
1149         if (mreg)
1150                 regfree(mreg);
1151         close_ctree(root);
1152         return ret;
1153 }