btrfs-progs: don't use __u8 for fsid buffers
[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
20 #include "kerncompat.h"
21
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <lzo/lzoconf.h>
30 #include <lzo/lzo1x.h>
31 #include <zlib.h>
32 #if BTRFSRESTORE_ZSTD
33 #include <zstd.h>
34 #endif
35 #include <regex.h>
36 #include <getopt.h>
37 #include <sys/types.h>
38 #include <sys/xattr.h>
39
40 #include "ctree.h"
41 #include "disk-io.h"
42 #include "print-tree.h"
43 #include "transaction.h"
44 #include "list.h"
45 #include "volumes.h"
46 #include "utils.h"
47 #include "commands.h"
48 #include "help.h"
49
50 static char fs_name[PATH_MAX];
51 static char path_name[PATH_MAX];
52 static char symlink_target[PATH_MAX];
53 static int get_snaps = 0;
54 static int verbose = 0;
55 static int restore_metadata = 0;
56 static int restore_symlinks = 0;
57 static int ignore_errors = 0;
58 static int overwrite = 0;
59 static int get_xattrs = 0;
60 static int dry_run = 0;
61
62 #define LZO_LEN 4
63 #define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)
64
65 static int decompress_zlib(char *inbuf, char *outbuf, u64 compress_len,
66                            u64 decompress_len)
67 {
68         z_stream strm;
69         int ret;
70
71         memset(&strm, 0, sizeof(strm));
72         ret = inflateInit(&strm);
73         if (ret != Z_OK) {
74                 error("zlib init returned %d", ret);
75                 return -1;
76         }
77
78         strm.avail_in = compress_len;
79         strm.next_in = (unsigned char *)inbuf;
80         strm.avail_out = decompress_len;
81         strm.next_out = (unsigned char *)outbuf;
82         ret = inflate(&strm, Z_NO_FLUSH);
83         if (ret != Z_STREAM_END) {
84                 (void)inflateEnd(&strm);
85                 error("zlib inflate failed: %d", ret);
86                 return -1;
87         }
88
89         (void)inflateEnd(&strm);
90         return 0;
91 }
92 static inline size_t read_compress_length(unsigned char *buf)
93 {
94         __le32 dlen;
95         memcpy(&dlen, buf, LZO_LEN);
96         return le32_to_cpu(dlen);
97 }
98
99 static int decompress_lzo(struct btrfs_root *root, unsigned char *inbuf,
100                         char *outbuf, u64 compress_len, u64 *decompress_len)
101 {
102         size_t new_len;
103         size_t in_len;
104         size_t out_len = 0;
105         size_t tot_len;
106         size_t tot_in;
107         int ret;
108
109         ret = lzo_init();
110         if (ret != LZO_E_OK) {
111                 error("lzo init returned %d", ret);
112                 return -1;
113         }
114
115         tot_len = read_compress_length(inbuf);
116         inbuf += LZO_LEN;
117         tot_in = LZO_LEN;
118
119         while (tot_in < tot_len) {
120                 size_t mod_page;
121                 size_t rem_page;
122                 in_len = read_compress_length(inbuf);
123
124                 if ((tot_in + LZO_LEN + in_len) > tot_len) {
125                         error("bad compress length %lu",
126                                 (unsigned long)in_len);
127                         return -1;
128                 }
129
130                 inbuf += LZO_LEN;
131                 tot_in += LZO_LEN;
132                 new_len = lzo1x_worst_compress(root->fs_info->sectorsize);
133                 ret = lzo1x_decompress_safe((const unsigned char *)inbuf, in_len,
134                                             (unsigned char *)outbuf,
135                                             (void *)&new_len, NULL);
136                 if (ret != LZO_E_OK) {
137                         error("lzo decompress failed: %d", ret);
138                         return -1;
139                 }
140                 out_len += new_len;
141                 outbuf += new_len;
142                 inbuf += in_len;
143                 tot_in += in_len;
144
145                 /*
146                  * If the 4 byte header does not fit to the rest of the page we
147                  * have to move to the next one, unless we read some garbage
148                  */
149                 mod_page = tot_in % root->fs_info->sectorsize;
150                 rem_page = root->fs_info->sectorsize - mod_page;
151                 if (rem_page < LZO_LEN) {
152                         inbuf += rem_page;
153                         tot_in += rem_page;
154                 }
155         }
156
157         *decompress_len = out_len;
158
159         return 0;
160 }
161
162 static int decompress_zstd(const char *inbuf, char *outbuf, u64 compress_len,
163                            u64 decompress_len)
164 {
165 #if !BTRFSRESTORE_ZSTD
166         error("btrfs not compiled with zstd support");
167         return -1;
168 #else
169         ZSTD_DStream *strm;
170         size_t zret;
171         int ret = 0;
172         ZSTD_inBuffer in = {inbuf, compress_len, 0};
173         ZSTD_outBuffer out = {outbuf, decompress_len, 0};
174
175         strm = ZSTD_createDStream();
176         if (!strm) {
177                 error("zstd create failed");
178                 return -1;
179         }
180
181         zret = ZSTD_initDStream(strm);
182         if (ZSTD_isError(zret)) {
183                 error("zstd init failed: %s", ZSTD_getErrorName(zret));
184                 ret = -1;
185                 goto out;
186         }
187
188         zret = ZSTD_decompressStream(strm, &out, &in);
189         if (ZSTD_isError(zret)) {
190                 error("zstd decompress failed %s\n", ZSTD_getErrorName(zret));
191                 ret = -1;
192                 goto out;
193         }
194         if (zret != 0) {
195                 error("zstd frame incomplete");
196                 ret = -1;
197                 goto out;
198         }
199
200 out:
201         ZSTD_freeDStream(strm);
202         return ret;
203 #endif
204 }
205
206 static int decompress(struct btrfs_root *root, char *inbuf, char *outbuf,
207                         u64 compress_len, u64 *decompress_len, int compress)
208 {
209         switch (compress) {
210         case BTRFS_COMPRESS_ZLIB:
211                 return decompress_zlib(inbuf, outbuf, compress_len,
212                                        *decompress_len);
213         case BTRFS_COMPRESS_LZO:
214                 return decompress_lzo(root, (unsigned char *)inbuf, outbuf,
215                                         compress_len, decompress_len);
216         case BTRFS_COMPRESS_ZSTD:
217                 return decompress_zstd(inbuf, outbuf, compress_len,
218                                        *decompress_len);
219         default:
220                 break;
221         }
222
223         error("invalid compression type: %d", compress);
224         return -1;
225 }
226
227 static int next_leaf(struct btrfs_root *root, struct btrfs_path *path)
228 {
229         int slot;
230         int level = 1;
231         int offset = 1;
232         struct extent_buffer *c;
233         struct extent_buffer *next = NULL;
234         struct btrfs_fs_info *fs_info = root->fs_info;
235
236 again:
237         for (; level < BTRFS_MAX_LEVEL; level++) {
238                 if (path->nodes[level])
239                         break;
240         }
241
242         if (level >= BTRFS_MAX_LEVEL)
243                 return 1;
244
245         slot = path->slots[level] + 1;
246
247         while(level < BTRFS_MAX_LEVEL) {
248                 if (!path->nodes[level])
249                         return 1;
250
251                 slot = path->slots[level] + offset;
252                 c = path->nodes[level];
253                 if (slot >= btrfs_header_nritems(c)) {
254                         level++;
255                         if (level == BTRFS_MAX_LEVEL)
256                                 return 1;
257                         offset = 1;
258                         continue;
259                 }
260
261                 if (path->reada)
262                         reada_for_search(root, path, level, slot, 0);
263
264                 next = read_node_slot(fs_info, c, slot);
265                 if (extent_buffer_uptodate(next))
266                         break;
267                 offset++;
268         }
269         path->slots[level] = slot;
270         while(1) {
271                 level--;
272                 c = path->nodes[level];
273                 free_extent_buffer(c);
274                 path->nodes[level] = next;
275                 path->slots[level] = 0;
276                 if (!level)
277                         break;
278                 if (path->reada)
279                         reada_for_search(root, path, level, 0, 0);
280                 next = read_node_slot(fs_info, next, 0);
281                 if (!extent_buffer_uptodate(next))
282                         goto again;
283         }
284         return 0;
285 }
286
287 static int copy_one_inline(struct btrfs_root *root, int fd,
288                                 struct btrfs_path *path, u64 pos)
289 {
290         struct extent_buffer *leaf = path->nodes[0];
291         struct btrfs_file_extent_item *fi;
292         char buf[4096];
293         char *outbuf;
294         u64 ram_size;
295         ssize_t done;
296         unsigned long ptr;
297         int ret;
298         int len;
299         int inline_item_len;
300         int compress;
301
302         fi = btrfs_item_ptr(leaf, path->slots[0],
303                             struct btrfs_file_extent_item);
304         ptr = btrfs_file_extent_inline_start(fi);
305         len = btrfs_file_extent_inline_len(leaf, path->slots[0], fi);
306         inline_item_len = btrfs_file_extent_inline_item_len(leaf, btrfs_item_nr(path->slots[0]));
307         read_extent_buffer(leaf, buf, ptr, inline_item_len);
308
309         compress = btrfs_file_extent_compression(leaf, fi);
310         if (compress == BTRFS_COMPRESS_NONE) {
311                 done = pwrite(fd, buf, len, pos);
312                 if (done < len) {
313                         fprintf(stderr, "Short inline write, wanted %d, did "
314                                 "%zd: %d\n", len, done, errno);
315                         return -1;
316                 }
317                 return 0;
318         }
319
320         ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
321         outbuf = calloc(1, ram_size);
322         if (!outbuf) {
323                 error("not enough memory");
324                 return -ENOMEM;
325         }
326
327         ret = decompress(root, buf, outbuf, len, &ram_size, compress);
328         if (ret) {
329                 free(outbuf);
330                 return ret;
331         }
332
333         done = pwrite(fd, outbuf, ram_size, pos);
334         free(outbuf);
335         if (done < ram_size) {
336                 fprintf(stderr, "Short compressed inline write, wanted %Lu, "
337                         "did %zd: %d\n", ram_size, done, errno);
338                 return -1;
339         }
340
341         return 0;
342 }
343
344 static int copy_one_extent(struct btrfs_root *root, int fd,
345                            struct extent_buffer *leaf,
346                            struct btrfs_file_extent_item *fi, u64 pos)
347 {
348         struct btrfs_multi_bio *multi = NULL;
349         struct btrfs_device *device;
350         char *inbuf, *outbuf = NULL;
351         ssize_t done, total = 0;
352         u64 bytenr;
353         u64 ram_size;
354         u64 disk_size;
355         u64 num_bytes;
356         u64 length;
357         u64 size_left;
358         u64 dev_bytenr;
359         u64 offset;
360         u64 count = 0;
361         int compress;
362         int ret;
363         int dev_fd;
364         int mirror_num = 1;
365         int num_copies;
366
367         compress = btrfs_file_extent_compression(leaf, fi);
368         bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
369         disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi);
370         ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
371         offset = btrfs_file_extent_offset(leaf, fi);
372         num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
373         size_left = disk_size;
374         if (compress == BTRFS_COMPRESS_NONE)
375                 bytenr += offset;
376
377         if (verbose && offset)
378                 printf("offset is %Lu\n", offset);
379         /* we found a hole */
380         if (disk_size == 0)
381                 return 0;
382
383         inbuf = malloc(size_left);
384         if (!inbuf) {
385                 error("not enough memory");
386                 return -ENOMEM;
387         }
388
389         if (compress != BTRFS_COMPRESS_NONE) {
390                 outbuf = calloc(1, ram_size);
391                 if (!outbuf) {
392                         error("not enough memory");
393                         free(inbuf);
394                         return -ENOMEM;
395                 }
396         }
397 again:
398         length = size_left;
399         ret = btrfs_map_block(root->fs_info, READ, bytenr, &length, &multi,
400                               mirror_num, NULL);
401         if (ret) {
402                 error("cannot map block logical %llu length %llu: %d",
403                                 (unsigned long long)bytenr,
404                                 (unsigned long long)length, ret);
405                 goto out;
406         }
407         device = multi->stripes[0].dev;
408         dev_fd = device->fd;
409         device->total_ios++;
410         dev_bytenr = multi->stripes[0].physical;
411         free(multi);
412
413         if (size_left < length)
414                 length = size_left;
415
416         done = pread(dev_fd, inbuf+count, length, dev_bytenr);
417         /* Need both checks, or we miss negative values due to u64 conversion */
418         if (done < 0 || done < length) {
419                 num_copies = btrfs_num_copies(root->fs_info, bytenr, length);
420                 mirror_num++;
421                 /* mirror_num is 1-indexed, so num_copies is a valid mirror. */
422                 if (mirror_num > num_copies) {
423                         ret = -1;
424                         error("exhausted mirrors trying to read (%d > %d)",
425                                         mirror_num, num_copies);
426                         goto out;
427                 }
428                 fprintf(stderr, "Trying another mirror\n");
429                 goto again;
430         }
431
432         mirror_num = 1;
433         size_left -= length;
434         count += length;
435         bytenr += length;
436         if (size_left)
437                 goto again;
438
439         if (compress == BTRFS_COMPRESS_NONE) {
440                 while (total < num_bytes) {
441                         done = pwrite(fd, inbuf+total, num_bytes-total,
442                                       pos+total);
443                         if (done < 0) {
444                                 ret = -1;
445                                 error("cannot write data: %d %s", errno, strerror(errno));
446                                 goto out;
447                         }
448                         total += done;
449                 }
450                 ret = 0;
451                 goto out;
452         }
453
454         ret = decompress(root, inbuf, outbuf, disk_size, &ram_size, compress);
455         if (ret) {
456                 num_copies = btrfs_num_copies(root->fs_info, bytenr, length);
457                 mirror_num++;
458                 if (mirror_num >= num_copies) {
459                         ret = -1;
460                         goto out;
461                 }
462                 fprintf(stderr, "Trying another mirror\n");
463                 goto again;
464         }
465
466         while (total < num_bytes) {
467                 done = pwrite(fd, outbuf + offset + total,
468                               num_bytes - total,
469                               pos + total);
470                 if (done < 0) {
471                         ret = -1;
472                         goto out;
473                 }
474                 total += done;
475         }
476 out:
477         free(inbuf);
478         free(outbuf);
479         return ret;
480 }
481
482 enum loop_response {
483         LOOP_STOP,
484         LOOP_CONTINUE,
485         LOOP_DONTASK
486 };
487
488 static enum loop_response ask_to_continue(const char *file)
489 {
490         char buf[2];
491         char *ret;
492
493         printf("We seem to be looping a lot on %s, do you want to keep going "
494                "on ? (y/N/a): ", file);
495 again:
496         ret = fgets(buf, 2, stdin);
497         if (*ret == '\n' || tolower(*ret) == 'n')
498                 return LOOP_STOP;
499         if (tolower(*ret) == 'a')
500                 return LOOP_DONTASK;
501         if (tolower(*ret) != 'y') {
502                 printf("Please enter one of 'y', 'n', or 'a': ");
503                 goto again;
504         }
505
506         return LOOP_CONTINUE;
507 }
508
509
510 static int set_file_xattrs(struct btrfs_root *root, u64 inode,
511                            int fd, const char *file_name)
512 {
513         struct btrfs_key key;
514         struct btrfs_path path;
515         struct extent_buffer *leaf;
516         struct btrfs_dir_item *di;
517         u32 name_len = 0;
518         u32 data_len = 0;
519         u32 len = 0;
520         u32 cur, total_len;
521         char *name = NULL;
522         char *data = NULL;
523         int ret = 0;
524
525         btrfs_init_path(&path);
526         key.objectid = inode;
527         key.type = BTRFS_XATTR_ITEM_KEY;
528         key.offset = 0;
529         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
530         if (ret < 0)
531                 goto out;
532
533         leaf = path.nodes[0];
534         while (1) {
535                 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
536                         do {
537                                 ret = next_leaf(root, &path);
538                                 if (ret < 0) {
539                                         error("searching for extended attributes: %d",
540                                                 ret);
541                                         goto out;
542                                 } else if (ret) {
543                                         /* No more leaves to search */
544                                         ret = 0;
545                                         goto out;
546                                 }
547                                 leaf = path.nodes[0];
548                         } while (!leaf);
549                         continue;
550                 }
551
552                 btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
553                 if (key.type != BTRFS_XATTR_ITEM_KEY || key.objectid != inode)
554                         break;
555                 cur = 0;
556                 total_len = btrfs_item_size_nr(leaf, path.slots[0]);
557                 di = btrfs_item_ptr(leaf, path.slots[0],
558                                     struct btrfs_dir_item);
559
560                 while (cur < total_len) {
561                         len = btrfs_dir_name_len(leaf, di);
562                         if (len > name_len) {
563                                 free(name);
564                                 name = (char *) malloc(len + 1);
565                                 if (!name) {
566                                         ret = -ENOMEM;
567                                         goto out;
568                                 }
569                         }
570                         read_extent_buffer(leaf, name,
571                                            (unsigned long)(di + 1), len);
572                         name[len] = '\0';
573                         name_len = len;
574
575                         len = btrfs_dir_data_len(leaf, di);
576                         if (len > data_len) {
577                                 free(data);
578                                 data = (char *) malloc(len);
579                                 if (!data) {
580                                         ret = -ENOMEM;
581                                         goto out;
582                                 }
583                         }
584                         read_extent_buffer(leaf, data,
585                                            (unsigned long)(di + 1) + name_len,
586                                            len);
587                         data_len = len;
588
589                         if (fsetxattr(fd, name, data, data_len, 0))
590                                 error("setting extended attribute %s on file %s: %s",
591                                         name, file_name, strerror(errno));
592
593                         len = sizeof(*di) + name_len + data_len;
594                         cur += len;
595                         di = (struct btrfs_dir_item *)((char *)di + len);
596                 }
597                 path.slots[0]++;
598         }
599         ret = 0;
600 out:
601         btrfs_release_path(&path);
602         free(name);
603         free(data);
604
605         return ret;
606 }
607
608 static int copy_metadata(struct btrfs_root *root, int fd,
609                 struct btrfs_key *key)
610 {
611         struct btrfs_path path;
612         struct btrfs_inode_item *inode_item;
613         int ret;
614
615         btrfs_init_path(&path);
616         ret = btrfs_lookup_inode(NULL, root, &path, key, 0);
617         if (ret == 0) {
618                 struct btrfs_timespec *bts;
619                 struct timespec times[2];
620
621                 inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0],
622                                 struct btrfs_inode_item);
623
624                 ret = fchown(fd, btrfs_inode_uid(path.nodes[0], inode_item),
625                                 btrfs_inode_gid(path.nodes[0], inode_item));
626                 if (ret) {
627                         error("failed to change owner: %s", strerror(errno));
628                         goto out;
629                 }
630
631                 ret = fchmod(fd, btrfs_inode_mode(path.nodes[0], inode_item));
632                 if (ret) {
633                         error("failed to change mode: %s", strerror(errno));
634                         goto out;
635                 }
636
637                 bts = btrfs_inode_atime(inode_item);
638                 times[0].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
639                 times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
640
641                 bts = btrfs_inode_mtime(inode_item);
642                 times[1].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
643                 times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
644
645                 ret = futimens(fd, times);
646                 if (ret) {
647                         error("failed to set times: %s", strerror(errno));
648                         goto out;
649                 }
650         }
651 out:
652         btrfs_release_path(&path);
653         return ret;
654 }
655
656 static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key,
657                      const char *file)
658 {
659         struct extent_buffer *leaf;
660         struct btrfs_path path;
661         struct btrfs_file_extent_item *fi;
662         struct btrfs_inode_item *inode_item;
663         struct btrfs_timespec *bts;
664         struct btrfs_key found_key;
665         int ret;
666         int extent_type;
667         int compression;
668         int loops = 0;
669         u64 found_size = 0;
670         struct timespec times[2];
671         int times_ok = 0;
672
673         btrfs_init_path(&path);
674         ret = btrfs_lookup_inode(NULL, root, &path, key, 0);
675         if (ret == 0) {
676                 inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0],
677                                     struct btrfs_inode_item);
678                 found_size = btrfs_inode_size(path.nodes[0], inode_item);
679
680                 if (restore_metadata) {
681                         /*
682                          * Change the ownership and mode now, set times when
683                          * copyout is finished.
684                          */
685
686                         ret = fchown(fd, btrfs_inode_uid(path.nodes[0], inode_item),
687                                         btrfs_inode_gid(path.nodes[0], inode_item));
688                         if (ret && !ignore_errors)
689                                 goto out;
690
691                         ret = fchmod(fd, btrfs_inode_mode(path.nodes[0], inode_item));
692                         if (ret && !ignore_errors)
693                                 goto out;
694
695                         bts = btrfs_inode_atime(inode_item);
696                         times[0].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
697                         times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
698
699                         bts = btrfs_inode_mtime(inode_item);
700                         times[1].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
701                         times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
702                         times_ok = 1;
703                 }
704         }
705         btrfs_release_path(&path);
706
707         key->offset = 0;
708         key->type = BTRFS_EXTENT_DATA_KEY;
709
710         ret = btrfs_search_slot(NULL, root, key, &path, 0, 0);
711         if (ret < 0) {
712                 error("searching extent data returned %d", ret);
713                 goto out;
714         }
715
716         leaf = path.nodes[0];
717         while (!leaf) {
718                 ret = next_leaf(root, &path);
719                 if (ret < 0) {
720                         error("cannot get next leaf: %d", ret);
721                         goto out;
722                 } else if (ret > 0) {
723                         /* No more leaves to search */
724                         ret = 0;
725                         goto out;
726                 }
727                 leaf = path.nodes[0];
728         }
729
730         while (1) {
731                 if (loops >= 0 && loops++ >= 1024) {
732                         enum loop_response resp;
733
734                         resp = ask_to_continue(file);
735                         if (resp == LOOP_STOP)
736                                 break;
737                         else if (resp == LOOP_CONTINUE)
738                                 loops = 0;
739                         else if (resp == LOOP_DONTASK)
740                                 loops = -1;
741                 }
742                 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
743                         do {
744                                 ret = next_leaf(root, &path);
745                                 if (ret < 0) {
746                                         fprintf(stderr, "Error searching %d\n", ret);
747                                         goto out;
748                                 } else if (ret) {
749                                         /* No more leaves to search */
750                                         btrfs_release_path(&path);
751                                         goto set_size;
752                                 }
753                                 leaf = path.nodes[0];
754                         } while (!leaf);
755                         continue;
756                 }
757                 btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
758                 if (found_key.objectid != key->objectid)
759                         break;
760                 if (found_key.type != key->type)
761                         break;
762                 fi = btrfs_item_ptr(leaf, path.slots[0],
763                                     struct btrfs_file_extent_item);
764                 extent_type = btrfs_file_extent_type(leaf, fi);
765                 compression = btrfs_file_extent_compression(leaf, fi);
766                 if (compression >= BTRFS_COMPRESS_LAST) {
767                         warning("compression type %d not supported",
768                                 compression);
769                         ret = -1;
770                         goto out;
771                 }
772
773                 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC)
774                         goto next;
775                 if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
776                         ret = copy_one_inline(root, fd, &path, found_key.offset);
777                         if (ret)
778                                 goto out;
779                 } else if (extent_type == BTRFS_FILE_EXTENT_REG) {
780                         ret = copy_one_extent(root, fd, leaf, fi,
781                                               found_key.offset);
782                         if (ret)
783                                 goto out;
784                 } else {
785                         warning("weird extent type %d", extent_type);
786                 }
787 next:
788                 path.slots[0]++;
789         }
790
791         btrfs_release_path(&path);
792 set_size:
793         if (found_size) {
794                 ret = ftruncate(fd, (loff_t)found_size);
795                 if (ret)
796                         return ret;
797         }
798         if (get_xattrs) {
799                 ret = set_file_xattrs(root, key->objectid, fd, file);
800                 if (ret)
801                         return ret;
802         }
803         if (restore_metadata && times_ok) {
804                 ret = futimens(fd, times);
805                 if (ret)
806                         return ret;
807         }
808         return 0;
809
810 out:
811         btrfs_release_path(&path);
812         return ret;
813 }
814
815 /*
816  * returns:
817  *  0 if the file exists and should be skipped.
818  *  1 if the file does NOT exist
819  *  2 if the file exists but is OK to overwrite
820  */
821 static int overwrite_ok(const char * path)
822 {
823         static int warn = 0;
824         struct stat st;
825         int ret;
826
827         /* don't be fooled by symlinks */
828         ret = fstatat(-1, path_name, &st, AT_SYMLINK_NOFOLLOW);
829
830         if (!ret) {
831                 if (overwrite)
832                         return 2;
833
834                 if (verbose || !warn)
835                         printf("Skipping existing file"
836                                    " %s\n", path);
837                 if (!warn)
838                         printf("If you wish to overwrite use -o\n");
839                 warn = 1;
840                 return 0;
841         }
842         return 1;
843 }
844
845 static int copy_symlink(struct btrfs_root *root, struct btrfs_key *key,
846                      const char *file)
847 {
848         struct btrfs_path path;
849         struct extent_buffer *leaf;
850         struct btrfs_file_extent_item *extent_item;
851         struct btrfs_inode_item *inode_item;
852         u32 len;
853         u32 name_offset;
854         int ret;
855         struct btrfs_timespec *bts;
856         struct timespec times[2];
857
858         ret = overwrite_ok(path_name);
859         if (ret == 0)
860             return 0; /* skip this file */
861
862         /* symlink() can't overwrite, so unlink first */
863         if (ret == 2) {
864                 ret = unlink(path_name);
865                 if (ret) {
866                         fprintf(stderr, "failed to unlink '%s' for overwrite\n",
867                                         path_name);
868                         return ret;
869                 }
870         }
871
872         btrfs_init_path(&path);
873         key->type = BTRFS_EXTENT_DATA_KEY;
874         key->offset = 0;
875         ret = btrfs_search_slot(NULL, root, key, &path, 0, 0);
876         if (ret < 0)
877                 goto out;
878
879         leaf = path.nodes[0];
880         if (!leaf) {
881                 fprintf(stderr, "Error getting leaf for symlink '%s'\n", file);
882                 ret = -1;
883                 goto out;
884         }
885
886         extent_item = btrfs_item_ptr(leaf, path.slots[0],
887                         struct btrfs_file_extent_item);
888
889         len = btrfs_file_extent_inline_item_len(leaf,
890                         btrfs_item_nr(path.slots[0]));
891         if (len >= PATH_MAX) {
892                 fprintf(stderr, "Symlink '%s' target length %d is longer than PATH_MAX\n",
893                                 fs_name, len);
894                 ret = -1;
895                 goto out;
896         }
897
898         name_offset = (unsigned long) extent_item
899                         + offsetof(struct btrfs_file_extent_item, disk_bytenr);
900         read_extent_buffer(leaf, symlink_target, name_offset, len);
901
902         symlink_target[len] = 0;
903
904         if (!dry_run) {
905                 ret = symlink(symlink_target, path_name);
906                 if (ret < 0) {
907                         fprintf(stderr, "Failed to restore symlink '%s': %s\n",
908                                         path_name, strerror(errno));
909                         goto out;
910                 }
911         }
912         printf("SYMLINK: '%s' => '%s'\n", path_name, symlink_target);
913
914         ret = 0;
915         if (!restore_metadata)
916                 goto out;
917
918         /*
919          * Symlink metadata operates differently than files/directories, so do
920          * our own work here.
921          */
922         key->type = BTRFS_INODE_ITEM_KEY;
923         key->offset = 0;
924
925         btrfs_release_path(&path);
926
927         ret = btrfs_lookup_inode(NULL, root, &path, key, 0);
928         if (ret) {
929                 fprintf(stderr, "Failed to lookup inode for '%s'\n", file);
930                 goto out;
931         }
932
933         inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0],
934                         struct btrfs_inode_item);
935
936         ret = fchownat(-1, file, btrfs_inode_uid(path.nodes[0], inode_item),
937                                    btrfs_inode_gid(path.nodes[0], inode_item),
938                                    AT_SYMLINK_NOFOLLOW);
939         if (ret) {
940                 fprintf(stderr, "Failed to change owner: %s\n",
941                                 strerror(errno));
942                 goto out;
943         }
944
945         bts = btrfs_inode_atime(inode_item);
946         times[0].tv_sec  = btrfs_timespec_sec(path.nodes[0], bts);
947         times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
948
949         bts = btrfs_inode_mtime(inode_item);
950         times[1].tv_sec  = btrfs_timespec_sec(path.nodes[0], bts);
951         times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
952
953         ret = utimensat(-1, file, times, AT_SYMLINK_NOFOLLOW);
954         if (ret)
955                 fprintf(stderr, "Failed to set times: %s\n", strerror(errno));
956 out:
957         btrfs_release_path(&path);
958         return ret;
959 }
960
961 static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
962                       const char *output_rootdir, const char *in_dir,
963                       const regex_t *mreg)
964 {
965         struct btrfs_path path;
966         struct extent_buffer *leaf;
967         struct btrfs_dir_item *dir_item;
968         struct btrfs_key found_key, location;
969         char filename[BTRFS_NAME_LEN + 1];
970         unsigned long name_ptr;
971         int name_len;
972         int ret = 0;
973         int fd;
974         int loops = 0;
975         u8 type;
976
977         btrfs_init_path(&path);
978         key->offset = 0;
979         key->type = BTRFS_DIR_INDEX_KEY;
980         ret = btrfs_search_slot(NULL, root, key, &path, 0, 0);
981         if (ret < 0) {
982                 fprintf(stderr, "Error searching %d\n", ret);
983                 goto out;
984         }
985
986         ret = 0;
987
988         leaf = path.nodes[0];
989         while (!leaf) {
990                 if (verbose > 1)
991                         printf("No leaf after search, looking for the next "
992                                "leaf\n");
993                 ret = next_leaf(root, &path);
994                 if (ret < 0) {
995                         fprintf(stderr, "Error getting next leaf %d\n",
996                                 ret);
997                         goto out;
998                 } else if (ret > 0) {
999                         /* No more leaves to search */
1000                         if (verbose)
1001                                 printf("Reached the end of the tree looking "
1002                                        "for the directory\n");
1003                         ret = 0;
1004                         goto out;
1005                 }
1006                 leaf = path.nodes[0];
1007         }
1008
1009         while (leaf) {
1010                 if (loops++ >= 1024) {
1011                         printf("We have looped trying to restore files in %s "
1012                                "too many times to be making progress, "
1013                                "stopping\n", in_dir);
1014                         break;
1015                 }
1016
1017                 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
1018                         do {
1019                                 ret = next_leaf(root, &path);
1020                                 if (ret < 0) {
1021                                         fprintf(stderr, "Error searching %d\n",
1022                                                 ret);
1023                                         goto out;
1024                                 } else if (ret > 0) {
1025                                         /* No more leaves to search */
1026                                         if (verbose)
1027                                                 printf("Reached the end of "
1028                                                        "the tree searching the"
1029                                                        " directory\n");
1030                                         ret = 0;
1031                                         goto out;
1032                                 }
1033                                 leaf = path.nodes[0];
1034                         } while (!leaf);
1035                         continue;
1036                 }
1037                 btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
1038                 if (found_key.objectid != key->objectid) {
1039                         if (verbose > 1)
1040                                 printf("Found objectid=%Lu, key=%Lu\n",
1041                                        found_key.objectid, key->objectid);
1042                         break;
1043                 }
1044                 if (found_key.type != key->type) {
1045                         if (verbose > 1)
1046                                 printf("Found type=%u, want=%u\n",
1047                                        found_key.type, key->type);
1048                         break;
1049                 }
1050                 dir_item = btrfs_item_ptr(leaf, path.slots[0],
1051                                           struct btrfs_dir_item);
1052                 name_ptr = (unsigned long)(dir_item + 1);
1053                 name_len = btrfs_dir_name_len(leaf, dir_item);
1054                 read_extent_buffer(leaf, filename, name_ptr, name_len);
1055                 filename[name_len] = '\0';
1056                 type = btrfs_dir_type(leaf, dir_item);
1057                 btrfs_dir_item_key_to_cpu(leaf, dir_item, &location);
1058
1059                 /* full path from root of btrfs being restored */
1060                 snprintf(fs_name, PATH_MAX, "%s/%s", in_dir, filename);
1061
1062                 if (mreg && REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
1063                         goto next;
1064
1065                 /* full path from system root */
1066                 snprintf(path_name, PATH_MAX, "%s%s", output_rootdir, fs_name);
1067
1068                 /*
1069                  * Restore directories, files, symlinks and metadata.
1070                  */
1071                 if (type == BTRFS_FT_REG_FILE) {
1072                         if (!overwrite_ok(path_name))
1073                                 goto next;
1074
1075                         if (verbose)
1076                                 printf("Restoring %s\n", path_name);
1077                         if (dry_run)
1078                                 goto next;
1079                         fd = open(path_name, O_CREAT|O_WRONLY, 0644);
1080                         if (fd < 0) {
1081                                 fprintf(stderr, "Error creating %s: %d\n",
1082                                         path_name, errno);
1083                                 if (ignore_errors)
1084                                         goto next;
1085                                 ret = -1;
1086                                 goto out;
1087                         }
1088                         loops = 0;
1089                         ret = copy_file(root, fd, &location, path_name);
1090                         close(fd);
1091                         if (ret) {
1092                                 fprintf(stderr, "Error copying data for %s\n",
1093                                         path_name);
1094                                 if (ignore_errors)
1095                                         goto next;
1096                                 goto out;
1097                         }
1098                 } else if (type == BTRFS_FT_DIR) {
1099                         struct btrfs_root *search_root = root;
1100                         char *dir = strdup(fs_name);
1101
1102                         if (!dir) {
1103                                 fprintf(stderr, "Ran out of memory\n");
1104                                 ret = -ENOMEM;
1105                                 goto out;
1106                         }
1107
1108                         if (location.type == BTRFS_ROOT_ITEM_KEY) {
1109                                 /*
1110                                  * If we are a snapshot and this is the index
1111                                  * object to ourselves just skip it.
1112                                  */
1113                                 if (location.objectid ==
1114                                     root->root_key.objectid) {
1115                                         free(dir);
1116                                         goto next;
1117                                 }
1118
1119                                 location.offset = (u64)-1;
1120                                 search_root = btrfs_read_fs_root(root->fs_info,
1121                                                                  &location);
1122                                 if (IS_ERR(search_root)) {
1123                                         free(dir);
1124                                         fprintf(stderr, "Error reading "
1125                                                 "subvolume %s: %lu\n",
1126                                                 path_name,
1127                                                 PTR_ERR(search_root));
1128                                         if (ignore_errors)
1129                                                 goto next;
1130                                         ret = PTR_ERR(search_root);
1131                                         goto out;
1132                                 }
1133
1134                                 /*
1135                                  * A subvolume will have a key.offset of 0, a
1136                                  * snapshot will have key.offset of a transid.
1137                                  */
1138                                 if (search_root->root_key.offset != 0 &&
1139                                     get_snaps == 0) {
1140                                         free(dir);
1141                                         printf("Skipping snapshot %s\n",
1142                                                filename);
1143                                         goto next;
1144                                 }
1145                                 location.objectid = BTRFS_FIRST_FREE_OBJECTID;
1146                         }
1147
1148                         if (verbose)
1149                                 printf("Restoring %s\n", path_name);
1150
1151                         errno = 0;
1152                         if (dry_run)
1153                                 ret = 0;
1154                         else
1155                                 ret = mkdir(path_name, 0755);
1156                         if (ret && errno != EEXIST) {
1157                                 free(dir);
1158                                 fprintf(stderr, "Error mkdiring %s: %d\n",
1159                                         path_name, errno);
1160                                 if (ignore_errors)
1161                                         goto next;
1162                                 ret = -1;
1163                                 goto out;
1164                         }
1165                         loops = 0;
1166                         ret = search_dir(search_root, &location,
1167                                          output_rootdir, dir, mreg);
1168                         free(dir);
1169                         if (ret) {
1170                                 fprintf(stderr, "Error searching %s\n",
1171                                         path_name);
1172                                 if (ignore_errors)
1173                                         goto next;
1174                                 goto out;
1175                         }
1176                 } else if (type == BTRFS_FT_SYMLINK) {
1177                         if (restore_symlinks)
1178                                 ret = copy_symlink(root, &location, path_name);
1179                         if (ret < 0) {
1180                                 if (ignore_errors)
1181                                         goto next;
1182                                 btrfs_release_path(&path);
1183                                 return ret;
1184                         }
1185                 }
1186 next:
1187                 path.slots[0]++;
1188         }
1189
1190         if (restore_metadata) {
1191                 snprintf(path_name, PATH_MAX, "%s%s", output_rootdir, in_dir);
1192                 fd = open(path_name, O_RDONLY);
1193                 if (fd < 0) {
1194                         fprintf(stderr, "ERROR: Failed to access %s to restore metadata\n",
1195                                         path_name);
1196                         if (!ignore_errors) {
1197                                 ret = -1;
1198                                 goto out;
1199                         }
1200                 } else {
1201                         /*
1202                          * Set owner/mode/time on the directory as well
1203                          */
1204                         key->type = BTRFS_INODE_ITEM_KEY;
1205                         ret = copy_metadata(root, fd, key);
1206                         close(fd);
1207                         if (ret && !ignore_errors)
1208                                 goto out;
1209                 }
1210         }
1211
1212         if (verbose)
1213                 printf("Done searching %s\n", in_dir);
1214 out:
1215         btrfs_release_path(&path);
1216         return ret;
1217 }
1218
1219 static int do_list_roots(struct btrfs_root *root)
1220 {
1221         struct btrfs_key key;
1222         struct btrfs_key found_key;
1223         struct btrfs_disk_key disk_key;
1224         struct btrfs_path path;
1225         struct extent_buffer *leaf;
1226         struct btrfs_root_item ri;
1227         unsigned long offset;
1228         int slot;
1229         int ret;
1230
1231         root = root->fs_info->tree_root;
1232
1233         btrfs_init_path(&path);
1234         key.offset = 0;
1235         key.objectid = 0;
1236         key.type = BTRFS_ROOT_ITEM_KEY;
1237         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
1238         if (ret < 0) {
1239                 fprintf(stderr, "Failed to do search %d\n", ret);
1240                 btrfs_release_path(&path);
1241                 return -1;
1242         }
1243
1244         leaf = path.nodes[0];
1245
1246         while (1) {
1247                 slot = path.slots[0];
1248                 if (slot >= btrfs_header_nritems(leaf)) {
1249                         ret = btrfs_next_leaf(root, &path);
1250                         if (ret)
1251                                 break;
1252                         leaf = path.nodes[0];
1253                         slot = path.slots[0];
1254                 }
1255                 btrfs_item_key(leaf, &disk_key, slot);
1256                 btrfs_disk_key_to_cpu(&found_key, &disk_key);
1257                 if (found_key.type != BTRFS_ROOT_ITEM_KEY) {
1258                         path.slots[0]++;
1259                         continue;
1260                 }
1261
1262                 offset = btrfs_item_ptr_offset(leaf, slot);
1263                 read_extent_buffer(leaf, &ri, offset, sizeof(ri));
1264                 printf(" tree ");
1265                 btrfs_print_key(&disk_key);
1266                 printf(" %Lu level %d\n", btrfs_root_bytenr(&ri),
1267                        btrfs_root_level(&ri));
1268                 path.slots[0]++;
1269         }
1270         btrfs_release_path(&path);
1271
1272         return 0;
1273 }
1274
1275 static struct btrfs_root *open_fs(const char *dev, u64 root_location,
1276                                   int super_mirror, int list_roots)
1277 {
1278         struct btrfs_fs_info *fs_info = NULL;
1279         struct btrfs_root *root = NULL;
1280         u64 bytenr;
1281         int i;
1282
1283         for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1284                 bytenr = btrfs_sb_offset(i);
1285                 fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0,
1286                                              OPEN_CTREE_PARTIAL);
1287                 if (fs_info)
1288                         break;
1289                 fprintf(stderr, "Could not open root, trying backup super\n");
1290         }
1291
1292         if (!fs_info)
1293                 return NULL;
1294
1295         /*
1296          * All we really need to succeed is reading the chunk tree, everything
1297          * else we can do by hand, since we only need to read the tree root and
1298          * the fs_root.
1299          */
1300         if (!extent_buffer_uptodate(fs_info->tree_root->node)) {
1301                 u64 generation;
1302
1303                 root = fs_info->tree_root;
1304                 if (!root_location)
1305                         root_location = btrfs_super_root(fs_info->super_copy);
1306                 generation = btrfs_super_generation(fs_info->super_copy);
1307                 root->node = read_tree_block(fs_info, root_location,
1308                                              generation);
1309                 if (!extent_buffer_uptodate(root->node)) {
1310                         fprintf(stderr, "Error opening tree root\n");
1311                         close_ctree(root);
1312                         return NULL;
1313                 }
1314         }
1315
1316         if (!list_roots && !fs_info->fs_root) {
1317                 struct btrfs_key key;
1318
1319                 key.objectid = BTRFS_FS_TREE_OBJECTID;
1320                 key.type = BTRFS_ROOT_ITEM_KEY;
1321                 key.offset = (u64)-1;
1322                 fs_info->fs_root = btrfs_read_fs_root_no_cache(fs_info, &key);
1323                 if (IS_ERR(fs_info->fs_root)) {
1324                         fprintf(stderr, "Couldn't read fs root: %ld\n",
1325                                 PTR_ERR(fs_info->fs_root));
1326                         close_ctree(fs_info->tree_root);
1327                         return NULL;
1328                 }
1329         }
1330
1331         if (list_roots && do_list_roots(fs_info->tree_root)) {
1332                 close_ctree(fs_info->tree_root);
1333                 return NULL;
1334         }
1335
1336         return fs_info->fs_root;
1337 }
1338
1339 static int find_first_dir(struct btrfs_root *root, u64 *objectid)
1340 {
1341         struct btrfs_path path;
1342         struct btrfs_key found_key;
1343         struct btrfs_key key;
1344         int ret = -1;
1345         int i;
1346
1347         btrfs_init_path(&path);
1348         key.objectid = 0;
1349         key.type = BTRFS_DIR_INDEX_KEY;
1350         key.offset = 0;
1351         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
1352         if (ret < 0) {
1353                 fprintf(stderr, "Error searching %d\n", ret);
1354                 goto out;
1355         }
1356
1357         if (!path.nodes[0]) {
1358                 fprintf(stderr, "No leaf!\n");
1359                 goto out;
1360         }
1361 again:
1362         for (i = path.slots[0];
1363              i < btrfs_header_nritems(path.nodes[0]); i++) {
1364                 btrfs_item_key_to_cpu(path.nodes[0], &found_key, i);
1365                 if (found_key.type != key.type)
1366                         continue;
1367
1368                 printf("Using objectid %Lu for first dir\n",
1369                        found_key.objectid);
1370                 *objectid = found_key.objectid;
1371                 ret = 0;
1372                 goto out;
1373         }
1374         do {
1375                 ret = next_leaf(root, &path);
1376                 if (ret < 0) {
1377                         fprintf(stderr, "Error getting next leaf %d\n",
1378                                 ret);
1379                         goto out;
1380                 } else if (ret > 0) {
1381                         fprintf(stderr, "No more leaves\n");
1382                         goto out;
1383                 }
1384         } while (!path.nodes[0]);
1385         if (path.nodes[0])
1386                 goto again;
1387         printf("Couldn't find a dir index item\n");
1388 out:
1389         btrfs_release_path(&path);
1390         return ret;
1391 }
1392
1393 const char * const cmd_restore_usage[] = {
1394         "btrfs restore [options] <device> <path> | -l <device>",
1395         "Try to restore files from a damaged filesystem (unmounted)",
1396         "",
1397         "-s|--snapshots       get snapshots",
1398         "-x|--xattr           restore extended attributes",
1399         "-m|--metadata        restore owner, mode and times",
1400         "-S|--symlink         restore symbolic links",
1401         "-v|--verbose         verbose",
1402         "-i|--ignore-errors   ignore errors",
1403         "-o|--overwrite       overwrite",
1404         "-t <bytenr>          tree location",
1405         "-f <bytenr>          filesystem location",
1406         "-u|--super <mirror>  super mirror",
1407         "-r|--root <rootid>   root objectid",
1408         "-d                   find dir",
1409         "-l|--list-roots      list tree roots",
1410         "-D|--dry-run         dry run (only list files that would be recovered)",
1411         "--path-regex <regex>",
1412         "                     restore only filenames matching regex,",
1413         "                     you have to use following syntax (possibly quoted):",
1414         "                     ^/(|home(|/username(|/Desktop(|/.*))))$",
1415         "-c                   ignore case (--path-regex only)",
1416         NULL
1417 };
1418
1419 int cmd_restore(int argc, char **argv)
1420 {
1421         struct btrfs_root *root;
1422         struct btrfs_key key;
1423         char dir_name[PATH_MAX];
1424         u64 tree_location = 0;
1425         u64 fs_location = 0;
1426         u64 root_objectid = 0;
1427         int len;
1428         int ret;
1429         int super_mirror = 0;
1430         int find_dir = 0;
1431         int list_roots = 0;
1432         const char *match_regstr = NULL;
1433         int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
1434         regex_t match_reg, *mreg = NULL;
1435         char reg_err[256];
1436
1437         while (1) {
1438                 int opt;
1439                 enum { GETOPT_VAL_PATH_REGEX = 256 };
1440                 static const struct option long_options[] = {
1441                         { "path-regex", required_argument, NULL,
1442                                 GETOPT_VAL_PATH_REGEX },
1443                         { "dry-run", no_argument, NULL, 'D'},
1444                         { "metadata", no_argument, NULL, 'm'},
1445                         { "symlinks", no_argument, NULL, 'S'},
1446                         { "snapshots", no_argument, NULL, 's'},
1447                         { "xattr", no_argument, NULL, 'x'},
1448                         { "verbose", no_argument, NULL, 'v'},
1449                         { "ignore-errors", no_argument, NULL, 'i'},
1450                         { "overwrite", no_argument, NULL, 'o'},
1451                         { "super", required_argument, NULL, 'u'},
1452                         { "root", required_argument, NULL, 'r'},
1453                         { "list-roots", no_argument, NULL, 'l'},
1454                         { NULL, 0, NULL, 0}
1455                 };
1456
1457                 opt = getopt_long(argc, argv, "sSxviot:u:dmf:r:lDc", long_options,
1458                                         NULL);
1459                 if (opt < 0)
1460                         break;
1461
1462                 switch (opt) {
1463                         case 's':
1464                                 get_snaps = 1;
1465                                 break;
1466                         case 'v':
1467                                 verbose++;
1468                                 break;
1469                         case 'i':
1470                                 ignore_errors = 1;
1471                                 break;
1472                         case 'o':
1473                                 overwrite = 1;
1474                                 break;
1475                         case 't':
1476                                 tree_location = arg_strtou64(optarg);
1477                                 break;
1478                         case 'f':
1479                                 fs_location = arg_strtou64(optarg);
1480                                 break;
1481                         case 'u':
1482                                 super_mirror = arg_strtou64(optarg);
1483                                 if (super_mirror >= BTRFS_SUPER_MIRROR_MAX) {
1484                                         fprintf(stderr, "Super mirror not "
1485                                                 "valid\n");
1486                                         exit(1);
1487                                 }
1488                                 break;
1489                         case 'd':
1490                                 find_dir = 1;
1491                                 break;
1492                         case 'r':
1493                                 root_objectid = arg_strtou64(optarg);
1494                                 if (!is_fstree(root_objectid)) {
1495                                         fprintf(stderr, "objectid %llu is not a valid fs/file tree\n",
1496                                                         root_objectid);
1497                                         exit(1);
1498                                 }
1499                                 break;
1500                         case 'l':
1501                                 list_roots = 1;
1502                                 break;
1503                         case 'm':
1504                                 restore_metadata = 1;
1505                                 break;
1506                         case 'S':
1507                                 restore_symlinks = 1;
1508                                 break;
1509                         case 'D':
1510                                 dry_run = 1;
1511                                 break;
1512                         case 'c':
1513                                 match_cflags |= REG_ICASE;
1514                                 break;
1515                         case GETOPT_VAL_PATH_REGEX:
1516                                 match_regstr = optarg;
1517                                 break;
1518                         case 'x':
1519                                 get_xattrs = 1;
1520                                 break;
1521                         default:
1522                                 usage(cmd_restore_usage);
1523                 }
1524         }
1525
1526         if (!list_roots && check_argc_min(argc - optind, 2))
1527                 usage(cmd_restore_usage);
1528         else if (list_roots && check_argc_min(argc - optind, 1))
1529                 usage(cmd_restore_usage);
1530
1531         if (fs_location && root_objectid) {
1532                 fprintf(stderr, "don't use -f and -r at the same time.\n");
1533                 return 1;
1534         }
1535
1536         if ((ret = check_mounted(argv[optind])) < 0) {
1537                 fprintf(stderr, "Could not check mount status: %s\n",
1538                         strerror(-ret));
1539                 return 1;
1540         } else if (ret) {
1541                 fprintf(stderr, "%s is currently mounted.  Aborting.\n", argv[optind]);
1542                 return 1;
1543         }
1544
1545         root = open_fs(argv[optind], tree_location, super_mirror, list_roots);
1546         if (root == NULL)
1547                 return 1;
1548
1549         if (list_roots)
1550                 goto out;
1551
1552         if (fs_location != 0) {
1553                 free_extent_buffer(root->node);
1554                 root->node = read_tree_block(root->fs_info, fs_location, 0);
1555                 if (!extent_buffer_uptodate(root->node)) {
1556                         fprintf(stderr, "Failed to read fs location\n");
1557                         ret = 1;
1558                         goto out;
1559                 }
1560         }
1561
1562         memset(path_name, 0, PATH_MAX);
1563
1564         if (strlen(argv[optind + 1]) >= PATH_MAX) {
1565                 fprintf(stderr, "ERROR: path too long\n");
1566                 ret = 1;
1567                 goto out;
1568         }
1569         strncpy(dir_name, argv[optind + 1], sizeof dir_name);
1570         dir_name[sizeof dir_name - 1] = 0;
1571
1572         /* Strip the trailing / on the dir name */
1573         len = strlen(dir_name);
1574         while (len && dir_name[--len] == '/') {
1575                 dir_name[len] = '\0';
1576         }
1577
1578         if (root_objectid != 0) {
1579                 struct btrfs_root *orig_root = root;
1580
1581                 key.objectid = root_objectid;
1582                 key.type = BTRFS_ROOT_ITEM_KEY;
1583                 key.offset = (u64)-1;
1584                 root = btrfs_read_fs_root(orig_root->fs_info, &key);
1585                 if (IS_ERR(root)) {
1586                         fprintf(stderr, "fail to read root %llu: %s\n",
1587                                         root_objectid, strerror(-PTR_ERR(root)));
1588                         root = orig_root;
1589                         ret = 1;
1590                         goto out;
1591                 }
1592                 key.type = 0;
1593                 key.offset = 0;
1594         }
1595
1596         if (find_dir) {
1597                 ret = find_first_dir(root, &key.objectid);
1598                 if (ret)
1599                         goto out;
1600         } else {
1601                 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
1602         }
1603
1604         if (match_regstr) {
1605                 ret = regcomp(&match_reg, match_regstr, match_cflags);
1606                 if (ret) {
1607                         regerror(ret, &match_reg, reg_err, sizeof(reg_err));
1608                         fprintf(stderr, "Regex compile failed: %s\n", reg_err);
1609                         goto out;
1610                 }
1611                 mreg = &match_reg;
1612         }
1613
1614         if (dry_run)
1615                 printf("This is a dry-run, no files are going to be restored\n");
1616
1617         ret = search_dir(root, &key, dir_name, "", mreg);
1618
1619 out:
1620         if (mreg)
1621                 regfree(mreg);
1622         close_ctree(root);
1623         return !!ret;
1624 }