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