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