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