btrfs-progs: extent_io: Fix NULL pointer dereference in free_extent_buffer_final()
[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 %m", 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: %m",
591                                         name, file_name);
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: %m");
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: %m");
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: %m");
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': %m\n",
908                                         path_name);
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: %m\n");
941                 goto out;
942         }
943
944         bts = btrfs_inode_atime(inode_item);
945         times[0].tv_sec  = btrfs_timespec_sec(path.nodes[0], bts);
946         times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
947
948         bts = btrfs_inode_mtime(inode_item);
949         times[1].tv_sec  = btrfs_timespec_sec(path.nodes[0], bts);
950         times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);
951
952         ret = utimensat(-1, file, times, AT_SYMLINK_NOFOLLOW);
953         if (ret)
954                 fprintf(stderr, "Failed to set times: %m\n");
955 out:
956         btrfs_release_path(&path);
957         return ret;
958 }
959
960 static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
961                       const char *output_rootdir, const char *in_dir,
962                       const regex_t *mreg)
963 {
964         struct btrfs_path path;
965         struct extent_buffer *leaf;
966         struct btrfs_dir_item *dir_item;
967         struct btrfs_key found_key, location;
968         char filename[BTRFS_NAME_LEN + 1];
969         unsigned long name_ptr;
970         int name_len;
971         int ret = 0;
972         int fd;
973         int loops = 0;
974         u8 type;
975
976         btrfs_init_path(&path);
977         key->offset = 0;
978         key->type = BTRFS_DIR_INDEX_KEY;
979         ret = btrfs_search_slot(NULL, root, key, &path, 0, 0);
980         if (ret < 0) {
981                 fprintf(stderr, "Error searching %d\n", ret);
982                 goto out;
983         }
984
985         ret = 0;
986
987         leaf = path.nodes[0];
988         while (!leaf) {
989                 if (verbose > 1)
990                         printf("No leaf after search, looking for the next "
991                                "leaf\n");
992                 ret = next_leaf(root, &path);
993                 if (ret < 0) {
994                         fprintf(stderr, "Error getting next leaf %d\n",
995                                 ret);
996                         goto out;
997                 } else if (ret > 0) {
998                         /* No more leaves to search */
999                         if (verbose)
1000                                 printf("Reached the end of the tree looking "
1001                                        "for the directory\n");
1002                         ret = 0;
1003                         goto out;
1004                 }
1005                 leaf = path.nodes[0];
1006         }
1007
1008         while (leaf) {
1009                 if (loops++ >= 1024) {
1010                         printf("We have looped trying to restore files in %s "
1011                                "too many times to be making progress, "
1012                                "stopping\n", in_dir);
1013                         break;
1014                 }
1015
1016                 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
1017                         do {
1018                                 ret = next_leaf(root, &path);
1019                                 if (ret < 0) {
1020                                         fprintf(stderr, "Error searching %d\n",
1021                                                 ret);
1022                                         goto out;
1023                                 } else if (ret > 0) {
1024                                         /* No more leaves to search */
1025                                         if (verbose)
1026                                                 printf("Reached the end of "
1027                                                        "the tree searching the"
1028                                                        " directory\n");
1029                                         ret = 0;
1030                                         goto out;
1031                                 }
1032                                 leaf = path.nodes[0];
1033                         } while (!leaf);
1034                         continue;
1035                 }
1036                 btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
1037                 if (found_key.objectid != key->objectid) {
1038                         if (verbose > 1)
1039                                 printf("Found objectid=%Lu, key=%Lu\n",
1040                                        found_key.objectid, key->objectid);
1041                         break;
1042                 }
1043                 if (found_key.type != key->type) {
1044                         if (verbose > 1)
1045                                 printf("Found type=%u, want=%u\n",
1046                                        found_key.type, key->type);
1047                         break;
1048                 }
1049                 dir_item = btrfs_item_ptr(leaf, path.slots[0],
1050                                           struct btrfs_dir_item);
1051                 name_ptr = (unsigned long)(dir_item + 1);
1052                 name_len = btrfs_dir_name_len(leaf, dir_item);
1053                 read_extent_buffer(leaf, filename, name_ptr, name_len);
1054                 filename[name_len] = '\0';
1055                 type = btrfs_dir_type(leaf, dir_item);
1056                 btrfs_dir_item_key_to_cpu(leaf, dir_item, &location);
1057
1058                 /* full path from root of btrfs being restored */
1059                 snprintf(fs_name, PATH_MAX, "%s/%s", in_dir, filename);
1060
1061                 if (mreg && REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
1062                         goto next;
1063
1064                 /* full path from system root */
1065                 snprintf(path_name, PATH_MAX, "%s%s", output_rootdir, fs_name);
1066
1067                 /*
1068                  * Restore directories, files, symlinks and metadata.
1069                  */
1070                 if (type == BTRFS_FT_REG_FILE) {
1071                         if (!overwrite_ok(path_name))
1072                                 goto next;
1073
1074                         if (verbose)
1075                                 printf("Restoring %s\n", path_name);
1076                         if (dry_run)
1077                                 goto next;
1078                         fd = open(path_name, O_CREAT|O_WRONLY, 0644);
1079                         if (fd < 0) {
1080                                 fprintf(stderr, "Error creating %s: %d\n",
1081                                         path_name, errno);
1082                                 if (ignore_errors)
1083                                         goto next;
1084                                 ret = -1;
1085                                 goto out;
1086                         }
1087                         loops = 0;
1088                         ret = copy_file(root, fd, &location, path_name);
1089                         close(fd);
1090                         if (ret) {
1091                                 fprintf(stderr, "Error copying data for %s\n",
1092                                         path_name);
1093                                 if (ignore_errors)
1094                                         goto next;
1095                                 goto out;
1096                         }
1097                 } else if (type == BTRFS_FT_DIR) {
1098                         struct btrfs_root *search_root = root;
1099                         char *dir = strdup(fs_name);
1100
1101                         if (!dir) {
1102                                 fprintf(stderr, "Ran out of memory\n");
1103                                 ret = -ENOMEM;
1104                                 goto out;
1105                         }
1106
1107                         if (location.type == BTRFS_ROOT_ITEM_KEY) {
1108                                 /*
1109                                  * If we are a snapshot and this is the index
1110                                  * object to ourselves just skip it.
1111                                  */
1112                                 if (location.objectid ==
1113                                     root->root_key.objectid) {
1114                                         free(dir);
1115                                         goto next;
1116                                 }
1117
1118                                 location.offset = (u64)-1;
1119                                 search_root = btrfs_read_fs_root(root->fs_info,
1120                                                                  &location);
1121                                 if (IS_ERR(search_root)) {
1122                                         free(dir);
1123                                         fprintf(stderr, "Error reading "
1124                                                 "subvolume %s: %lu\n",
1125                                                 path_name,
1126                                                 PTR_ERR(search_root));
1127                                         if (ignore_errors)
1128                                                 goto next;
1129                                         ret = PTR_ERR(search_root);
1130                                         goto out;
1131                                 }
1132
1133                                 /*
1134                                  * A subvolume will have a key.offset of 0, a
1135                                  * snapshot will have key.offset of a transid.
1136                                  */
1137                                 if (search_root->root_key.offset != 0 &&
1138                                     get_snaps == 0) {
1139                                         free(dir);
1140                                         printf("Skipping snapshot %s\n",
1141                                                filename);
1142                                         goto next;
1143                                 }
1144                                 location.objectid = BTRFS_FIRST_FREE_OBJECTID;
1145                         }
1146
1147                         if (verbose)
1148                                 printf("Restoring %s\n", path_name);
1149
1150                         errno = 0;
1151                         if (dry_run)
1152                                 ret = 0;
1153                         else
1154                                 ret = mkdir(path_name, 0755);
1155                         if (ret && errno != EEXIST) {
1156                                 free(dir);
1157                                 fprintf(stderr, "Error mkdiring %s: %d\n",
1158                                         path_name, errno);
1159                                 if (ignore_errors)
1160                                         goto next;
1161                                 ret = -1;
1162                                 goto out;
1163                         }
1164                         loops = 0;
1165                         ret = search_dir(search_root, &location,
1166                                          output_rootdir, dir, mreg);
1167                         free(dir);
1168                         if (ret) {
1169                                 fprintf(stderr, "Error searching %s\n",
1170                                         path_name);
1171                                 if (ignore_errors)
1172                                         goto next;
1173                                 goto out;
1174                         }
1175                 } else if (type == BTRFS_FT_SYMLINK) {
1176                         if (restore_symlinks)
1177                                 ret = copy_symlink(root, &location, path_name);
1178                         if (ret < 0) {
1179                                 if (ignore_errors)
1180                                         goto next;
1181                                 btrfs_release_path(&path);
1182                                 return ret;
1183                         }
1184                 }
1185 next:
1186                 path.slots[0]++;
1187         }
1188
1189         if (restore_metadata) {
1190                 snprintf(path_name, PATH_MAX, "%s%s", output_rootdir, in_dir);
1191                 fd = open(path_name, O_RDONLY);
1192                 if (fd < 0) {
1193                         fprintf(stderr, "ERROR: Failed to access %s to restore metadata\n",
1194                                         path_name);
1195                         if (!ignore_errors) {
1196                                 ret = -1;
1197                                 goto out;
1198                         }
1199                 } else {
1200                         /*
1201                          * Set owner/mode/time on the directory as well
1202                          */
1203                         key->type = BTRFS_INODE_ITEM_KEY;
1204                         ret = copy_metadata(root, fd, key);
1205                         close(fd);
1206                         if (ret && !ignore_errors)
1207                                 goto out;
1208                 }
1209         }
1210
1211         if (verbose)
1212                 printf("Done searching %s\n", in_dir);
1213 out:
1214         btrfs_release_path(&path);
1215         return ret;
1216 }
1217
1218 static int do_list_roots(struct btrfs_root *root)
1219 {
1220         struct btrfs_key key;
1221         struct btrfs_key found_key;
1222         struct btrfs_disk_key disk_key;
1223         struct btrfs_path path;
1224         struct extent_buffer *leaf;
1225         struct btrfs_root_item ri;
1226         unsigned long offset;
1227         int slot;
1228         int ret;
1229
1230         root = root->fs_info->tree_root;
1231
1232         btrfs_init_path(&path);
1233         key.offset = 0;
1234         key.objectid = 0;
1235         key.type = BTRFS_ROOT_ITEM_KEY;
1236         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
1237         if (ret < 0) {
1238                 fprintf(stderr, "Failed to do search %d\n", ret);
1239                 btrfs_release_path(&path);
1240                 return -1;
1241         }
1242
1243         leaf = path.nodes[0];
1244
1245         while (1) {
1246                 slot = path.slots[0];
1247                 if (slot >= btrfs_header_nritems(leaf)) {
1248                         ret = btrfs_next_leaf(root, &path);
1249                         if (ret)
1250                                 break;
1251                         leaf = path.nodes[0];
1252                         slot = path.slots[0];
1253                 }
1254                 btrfs_item_key(leaf, &disk_key, slot);
1255                 btrfs_disk_key_to_cpu(&found_key, &disk_key);
1256                 if (found_key.type != BTRFS_ROOT_ITEM_KEY) {
1257                         path.slots[0]++;
1258                         continue;
1259                 }
1260
1261                 offset = btrfs_item_ptr_offset(leaf, slot);
1262                 read_extent_buffer(leaf, &ri, offset, sizeof(ri));
1263                 printf(" tree ");
1264                 btrfs_print_key(&disk_key);
1265                 printf(" %Lu level %d\n", btrfs_root_bytenr(&ri),
1266                        btrfs_root_level(&ri));
1267                 path.slots[0]++;
1268         }
1269         btrfs_release_path(&path);
1270
1271         return 0;
1272 }
1273
1274 static struct btrfs_root *open_fs(const char *dev, u64 root_location,
1275                                   int super_mirror, int list_roots)
1276 {
1277         struct btrfs_fs_info *fs_info = NULL;
1278         struct btrfs_root *root = NULL;
1279         u64 bytenr;
1280         int i;
1281
1282         for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1283                 bytenr = btrfs_sb_offset(i);
1284                 fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0,
1285                                              OPEN_CTREE_PARTIAL);
1286                 if (fs_info)
1287                         break;
1288                 fprintf(stderr, "Could not open root, trying backup super\n");
1289         }
1290
1291         if (!fs_info)
1292                 return NULL;
1293
1294         /*
1295          * All we really need to succeed is reading the chunk tree, everything
1296          * else we can do by hand, since we only need to read the tree root and
1297          * the fs_root.
1298          */
1299         if (!extent_buffer_uptodate(fs_info->tree_root->node)) {
1300                 u64 generation;
1301
1302                 root = fs_info->tree_root;
1303                 if (!root_location)
1304                         root_location = btrfs_super_root(fs_info->super_copy);
1305                 generation = btrfs_super_generation(fs_info->super_copy);
1306                 root->node = read_tree_block(fs_info, root_location,
1307                                              generation);
1308                 if (!extent_buffer_uptodate(root->node)) {
1309                         fprintf(stderr, "Error opening tree root\n");
1310                         close_ctree(root);
1311                         return NULL;
1312                 }
1313         }
1314
1315         if (!list_roots && !fs_info->fs_root) {
1316                 struct btrfs_key key;
1317
1318                 key.objectid = BTRFS_FS_TREE_OBJECTID;
1319                 key.type = BTRFS_ROOT_ITEM_KEY;
1320                 key.offset = (u64)-1;
1321                 fs_info->fs_root = btrfs_read_fs_root_no_cache(fs_info, &key);
1322                 if (IS_ERR(fs_info->fs_root)) {
1323                         fprintf(stderr, "Couldn't read fs root: %ld\n",
1324                                 PTR_ERR(fs_info->fs_root));
1325                         close_ctree(fs_info->tree_root);
1326                         return NULL;
1327                 }
1328         }
1329
1330         if (list_roots && do_list_roots(fs_info->tree_root)) {
1331                 close_ctree(fs_info->tree_root);
1332                 return NULL;
1333         }
1334
1335         return fs_info->fs_root;
1336 }
1337
1338 static int find_first_dir(struct btrfs_root *root, u64 *objectid)
1339 {
1340         struct btrfs_path path;
1341         struct btrfs_key found_key;
1342         struct btrfs_key key;
1343         int ret = -1;
1344         int i;
1345
1346         btrfs_init_path(&path);
1347         key.objectid = 0;
1348         key.type = BTRFS_DIR_INDEX_KEY;
1349         key.offset = 0;
1350         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
1351         if (ret < 0) {
1352                 fprintf(stderr, "Error searching %d\n", ret);
1353                 goto out;
1354         }
1355
1356         if (!path.nodes[0]) {
1357                 fprintf(stderr, "No leaf!\n");
1358                 goto out;
1359         }
1360 again:
1361         for (i = path.slots[0];
1362              i < btrfs_header_nritems(path.nodes[0]); i++) {
1363                 btrfs_item_key_to_cpu(path.nodes[0], &found_key, i);
1364                 if (found_key.type != key.type)
1365                         continue;
1366
1367                 printf("Using objectid %Lu for first dir\n",
1368                        found_key.objectid);
1369                 *objectid = found_key.objectid;
1370                 ret = 0;
1371                 goto out;
1372         }
1373         do {
1374                 ret = next_leaf(root, &path);
1375                 if (ret < 0) {
1376                         fprintf(stderr, "Error getting next leaf %d\n",
1377                                 ret);
1378                         goto out;
1379                 } else if (ret > 0) {
1380                         fprintf(stderr, "No more leaves\n");
1381                         goto out;
1382                 }
1383         } while (!path.nodes[0]);
1384         if (path.nodes[0])
1385                 goto again;
1386         printf("Couldn't find a dir index item\n");
1387 out:
1388         btrfs_release_path(&path);
1389         return ret;
1390 }
1391
1392 const char * const cmd_restore_usage[] = {
1393         "btrfs restore [options] <device> <path> | -l <device>",
1394         "Try to restore files from a damaged filesystem (unmounted)",
1395         "",
1396         "-s|--snapshots       get snapshots",
1397         "-x|--xattr           restore extended attributes",
1398         "-m|--metadata        restore owner, mode and times",
1399         "-S|--symlink         restore symbolic links",
1400         "-v|--verbose         verbose",
1401         "-i|--ignore-errors   ignore errors",
1402         "-o|--overwrite       overwrite",
1403         "-t <bytenr>          tree location",
1404         "-f <bytenr>          filesystem location",
1405         "-u|--super <mirror>  super mirror",
1406         "-r|--root <rootid>   root objectid",
1407         "-d                   find dir",
1408         "-l|--list-roots      list tree roots",
1409         "-D|--dry-run         dry run (only list files that would be recovered)",
1410         "--path-regex <regex>",
1411         "                     restore only filenames matching regex,",
1412         "                     you have to use following syntax (possibly quoted):",
1413         "                     ^/(|home(|/username(|/Desktop(|/.*))))$",
1414         "-c                   ignore case (--path-regex only)",
1415         NULL
1416 };
1417
1418 int cmd_restore(int argc, char **argv)
1419 {
1420         struct btrfs_root *root;
1421         struct btrfs_key key;
1422         char dir_name[PATH_MAX];
1423         u64 tree_location = 0;
1424         u64 fs_location = 0;
1425         u64 root_objectid = 0;
1426         int len;
1427         int ret;
1428         int super_mirror = 0;
1429         int find_dir = 0;
1430         int list_roots = 0;
1431         const char *match_regstr = NULL;
1432         int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
1433         regex_t match_reg, *mreg = NULL;
1434         char reg_err[256];
1435
1436         while (1) {
1437                 int opt;
1438                 enum { GETOPT_VAL_PATH_REGEX = 256 };
1439                 static const struct option long_options[] = {
1440                         { "path-regex", required_argument, NULL,
1441                                 GETOPT_VAL_PATH_REGEX },
1442                         { "dry-run", no_argument, NULL, 'D'},
1443                         { "metadata", no_argument, NULL, 'm'},
1444                         { "symlinks", no_argument, NULL, 'S'},
1445                         { "snapshots", no_argument, NULL, 's'},
1446                         { "xattr", no_argument, NULL, 'x'},
1447                         { "verbose", no_argument, NULL, 'v'},
1448                         { "ignore-errors", no_argument, NULL, 'i'},
1449                         { "overwrite", no_argument, NULL, 'o'},
1450                         { "super", required_argument, NULL, 'u'},
1451                         { "root", required_argument, NULL, 'r'},
1452                         { "list-roots", no_argument, NULL, 'l'},
1453                         { NULL, 0, NULL, 0}
1454                 };
1455
1456                 opt = getopt_long(argc, argv, "sSxviot:u:dmf:r:lDc", long_options,
1457                                         NULL);
1458                 if (opt < 0)
1459                         break;
1460
1461                 switch (opt) {
1462                         case 's':
1463                                 get_snaps = 1;
1464                                 break;
1465                         case 'v':
1466                                 verbose++;
1467                                 break;
1468                         case 'i':
1469                                 ignore_errors = 1;
1470                                 break;
1471                         case 'o':
1472                                 overwrite = 1;
1473                                 break;
1474                         case 't':
1475                                 tree_location = arg_strtou64(optarg);
1476                                 break;
1477                         case 'f':
1478                                 fs_location = arg_strtou64(optarg);
1479                                 break;
1480                         case 'u':
1481                                 super_mirror = arg_strtou64(optarg);
1482                                 if (super_mirror >= BTRFS_SUPER_MIRROR_MAX) {
1483                                         fprintf(stderr, "Super mirror not "
1484                                                 "valid\n");
1485                                         exit(1);
1486                                 }
1487                                 break;
1488                         case 'd':
1489                                 find_dir = 1;
1490                                 break;
1491                         case 'r':
1492                                 root_objectid = arg_strtou64(optarg);
1493                                 if (!is_fstree(root_objectid)) {
1494                                         fprintf(stderr, "objectid %llu is not a valid fs/file tree\n",
1495                                                         root_objectid);
1496                                         exit(1);
1497                                 }
1498                                 break;
1499                         case 'l':
1500                                 list_roots = 1;
1501                                 break;
1502                         case 'm':
1503                                 restore_metadata = 1;
1504                                 break;
1505                         case 'S':
1506                                 restore_symlinks = 1;
1507                                 break;
1508                         case 'D':
1509                                 dry_run = 1;
1510                                 break;
1511                         case 'c':
1512                                 match_cflags |= REG_ICASE;
1513                                 break;
1514                         case GETOPT_VAL_PATH_REGEX:
1515                                 match_regstr = optarg;
1516                                 break;
1517                         case 'x':
1518                                 get_xattrs = 1;
1519                                 break;
1520                         default:
1521                                 usage(cmd_restore_usage);
1522                 }
1523         }
1524
1525         if (!list_roots && check_argc_min(argc - optind, 2))
1526                 usage(cmd_restore_usage);
1527         else if (list_roots && check_argc_min(argc - optind, 1))
1528                 usage(cmd_restore_usage);
1529
1530         if (fs_location && root_objectid) {
1531                 fprintf(stderr, "don't use -f and -r at the same time.\n");
1532                 return 1;
1533         }
1534
1535         if ((ret = check_mounted(argv[optind])) < 0) {
1536                 fprintf(stderr, "Could not check mount status: %s\n",
1537                         strerror(-ret));
1538                 return 1;
1539         } else if (ret) {
1540                 fprintf(stderr, "%s is currently mounted.  Aborting.\n", argv[optind]);
1541                 return 1;
1542         }
1543
1544         root = open_fs(argv[optind], tree_location, super_mirror, list_roots);
1545         if (root == NULL)
1546                 return 1;
1547
1548         if (list_roots)
1549                 goto out;
1550
1551         if (fs_location != 0) {
1552                 free_extent_buffer(root->node);
1553                 root->node = read_tree_block(root->fs_info, fs_location, 0);
1554                 if (!extent_buffer_uptodate(root->node)) {
1555                         fprintf(stderr, "Failed to read fs location\n");
1556                         ret = 1;
1557                         goto out;
1558                 }
1559         }
1560
1561         memset(path_name, 0, PATH_MAX);
1562
1563         if (strlen(argv[optind + 1]) >= PATH_MAX) {
1564                 fprintf(stderr, "ERROR: path too long\n");
1565                 ret = 1;
1566                 goto out;
1567         }
1568         strncpy(dir_name, argv[optind + 1], sizeof dir_name);
1569         dir_name[sizeof dir_name - 1] = 0;
1570
1571         /* Strip the trailing / on the dir name */
1572         len = strlen(dir_name);
1573         while (len && dir_name[--len] == '/') {
1574                 dir_name[len] = '\0';
1575         }
1576
1577         if (root_objectid != 0) {
1578                 struct btrfs_root *orig_root = root;
1579
1580                 key.objectid = root_objectid;
1581                 key.type = BTRFS_ROOT_ITEM_KEY;
1582                 key.offset = (u64)-1;
1583                 root = btrfs_read_fs_root(orig_root->fs_info, &key);
1584                 if (IS_ERR(root)) {
1585                         fprintf(stderr, "fail to read root %llu: %s\n",
1586                                         root_objectid, strerror(-PTR_ERR(root)));
1587                         root = orig_root;
1588                         ret = 1;
1589                         goto out;
1590                 }
1591                 key.type = 0;
1592                 key.offset = 0;
1593         }
1594
1595         if (find_dir) {
1596                 ret = find_first_dir(root, &key.objectid);
1597                 if (ret)
1598                         goto out;
1599         } else {
1600                 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
1601         }
1602
1603         if (match_regstr) {
1604                 ret = regcomp(&match_reg, match_regstr, match_cflags);
1605                 if (ret) {
1606                         regerror(ret, &match_reg, reg_err, sizeof(reg_err));
1607                         fprintf(stderr, "Regex compile failed: %s\n", reg_err);
1608                         goto out;
1609                 }
1610                 mreg = &match_reg;
1611         }
1612
1613         if (dry_run)
1614                 printf("This is a dry-run, no files are going to be restored\n");
1615
1616         ret = search_dir(root, &key, dir_name, "", mreg);
1617
1618 out:
1619         if (mreg)
1620                 regfree(mreg);
1621         close_ctree(root);
1622         return !!ret;
1623 }