btrfs-progs: move prefixcmp helper to utils
[platform/upstream/btrfs-progs.git] / cmds-receive.c
1 /*
2  * Copyright (C) 2012 Alexander Block.  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 #include "kerncompat.h"
20 #include "androidcompat.h"
21
22 #include <unistd.h>
23 #include <stdint.h>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <pthread.h>
27 #include <math.h>
28 #include <ftw.h>
29 #include <sys/wait.h>
30 #include <assert.h>
31 #include <getopt.h>
32 #include <limits.h>
33
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
37 #include <sys/time.h>
38 #include <sys/types.h>
39 #include <sys/xattr.h>
40 #include <uuid/uuid.h>
41
42 #include "ctree.h"
43 #include "ioctl.h"
44 #include "commands.h"
45 #include "utils.h"
46 #include "list.h"
47 #include "btrfs-list.h"
48
49 #include "send.h"
50 #include "send-stream.h"
51 #include "send-utils.h"
52 #include "send-dump.h"
53 #include "help.h"
54
55 static int g_verbose = 0;
56
57 struct btrfs_receive
58 {
59         int mnt_fd;
60         int dest_dir_fd;
61
62         int write_fd;
63         char write_path[PATH_MAX];
64
65         char *root_path;
66         char *dest_dir_path; /* relative to root_path */
67         char full_subvol_path[PATH_MAX];
68         char *full_root_path;
69         int dest_dir_chroot;
70
71         struct subvol_info cur_subvol;
72         /*
73          * Substitute for cur_subvol::path which is a pointer and we cannot
74          * change it to an array as it's a public API.
75          */
76         char cur_subvol_path[PATH_MAX];
77
78         struct subvol_uuid_search sus;
79
80         int honor_end_cmd;
81
82         /*
83          * Buffer to store capabilities from security.capabilities xattr,
84          * usually 20 bytes, but make same room for potentially larger
85          * encodings. Must be set only once per file, denoted by length > 0.
86          */
87         char cached_capabilities[64];
88         int cached_capabilities_len;
89 };
90
91 static int finish_subvol(struct btrfs_receive *rctx)
92 {
93         int ret;
94         int subvol_fd = -1;
95         struct btrfs_ioctl_received_subvol_args rs_args;
96         char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
97         u64 flags;
98
99         if (rctx->cur_subvol_path[0] == 0)
100                 return 0;
101
102         subvol_fd = openat(rctx->mnt_fd, rctx->cur_subvol_path,
103                            O_RDONLY | O_NOATIME);
104         if (subvol_fd < 0) {
105                 ret = -errno;
106                 error("cannot open %s: %s",
107                                 rctx->cur_subvol_path, strerror(-ret));
108                 goto out;
109         }
110
111         memset(&rs_args, 0, sizeof(rs_args));
112         memcpy(rs_args.uuid, rctx->cur_subvol.received_uuid, BTRFS_UUID_SIZE);
113         rs_args.stransid = rctx->cur_subvol.stransid;
114
115         if (g_verbose >= 1) {
116                 uuid_unparse((u8*)rs_args.uuid, uuid_str);
117                 fprintf(stderr, "BTRFS_IOC_SET_RECEIVED_SUBVOL uuid=%s, "
118                                 "stransid=%llu\n", uuid_str, rs_args.stransid);
119         }
120
121         ret = ioctl(subvol_fd, BTRFS_IOC_SET_RECEIVED_SUBVOL, &rs_args);
122         if (ret < 0) {
123                 ret = -errno;
124                 error("ioctl BTRFS_IOC_SET_RECEIVED_SUBVOL failed: %s",
125                                 strerror(-ret));
126                 goto out;
127         }
128         rctx->cur_subvol.rtransid = rs_args.rtransid;
129
130         ret = ioctl(subvol_fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags);
131         if (ret < 0) {
132                 ret = -errno;
133                 error("ioctl BTRFS_IOC_SUBVOL_GETFLAGS failed: %s",
134                                 strerror(-ret));
135                 goto out;
136         }
137
138         flags |= BTRFS_SUBVOL_RDONLY;
139
140         ret = ioctl(subvol_fd, BTRFS_IOC_SUBVOL_SETFLAGS, &flags);
141         if (ret < 0) {
142                 ret = -errno;
143                 error("failed to make subvolume read only: %s",
144                                 strerror(-ret));
145                 goto out;
146         }
147
148         ret = 0;
149
150 out:
151         if (rctx->cur_subvol_path[0]) {
152                 rctx->cur_subvol_path[0] = 0;
153         }
154         if (subvol_fd != -1)
155                 close(subvol_fd);
156         return ret;
157 }
158
159 static int process_subvol(const char *path, const u8 *uuid, u64 ctransid,
160                           void *user)
161 {
162         int ret;
163         struct btrfs_receive *rctx = user;
164         struct btrfs_ioctl_vol_args args_v1;
165         char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
166
167         ret = finish_subvol(rctx);
168         if (ret < 0)
169                 goto out;
170
171         if (rctx->cur_subvol.path) {
172                 error("subvol: another one already started, path ptr: %s",
173                                 rctx->cur_subvol.path);
174                 ret = -EINVAL;
175                 goto out;
176         }
177         if (rctx->cur_subvol_path[0]) {
178                 error("subvol: another one already started, path buf: %s",
179                                 rctx->cur_subvol.path);
180                 ret = -EINVAL;
181                 goto out;
182         }
183
184         if (*rctx->dest_dir_path == 0) {
185                 strncpy_null(rctx->cur_subvol_path, path);
186         } else {
187                 ret = path_cat_out(rctx->cur_subvol_path, rctx->dest_dir_path,
188                                    path);
189                 if (ret < 0) {
190                         error("subvol: path invalid: %s", path);
191                         goto out;
192                 }
193         }
194         ret = path_cat3_out(rctx->full_subvol_path, rctx->root_path,
195                             rctx->dest_dir_path, path);
196         if (ret < 0) {
197                 error("subvol: path invalid: %s", path);
198                 goto out;
199         }
200
201         fprintf(stderr, "At subvol %s\n", path);
202
203         memcpy(rctx->cur_subvol.received_uuid, uuid, BTRFS_UUID_SIZE);
204         rctx->cur_subvol.stransid = ctransid;
205
206         if (g_verbose) {
207                 uuid_unparse((u8*)rctx->cur_subvol.received_uuid, uuid_str);
208                 fprintf(stderr, "receiving subvol %s uuid=%s, stransid=%llu\n",
209                                 path, uuid_str,
210                                 rctx->cur_subvol.stransid);
211         }
212
213         memset(&args_v1, 0, sizeof(args_v1));
214         strncpy_null(args_v1.name, path);
215         ret = ioctl(rctx->dest_dir_fd, BTRFS_IOC_SUBVOL_CREATE, &args_v1);
216         if (ret < 0) {
217                 ret = -errno;
218                 error("creating subvolume %s failed: %s", path, strerror(-ret));
219                 goto out;
220         }
221
222 out:
223         return ret;
224 }
225
226 static int process_snapshot(const char *path, const u8 *uuid, u64 ctransid,
227                             const u8 *parent_uuid, u64 parent_ctransid,
228                             void *user)
229 {
230         int ret;
231         struct btrfs_receive *rctx = user;
232         char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
233         struct btrfs_ioctl_vol_args_v2 args_v2;
234         struct subvol_info *parent_subvol = NULL;
235
236         ret = finish_subvol(rctx);
237         if (ret < 0)
238                 goto out;
239
240         if (rctx->cur_subvol.path) {
241                 error("snapshot: another one already started, path ptr: %s",
242                                 rctx->cur_subvol.path);
243                 ret = -EINVAL;
244                 goto out;
245         }
246         if (rctx->cur_subvol_path[0]) {
247                 error("snapshot: another one already started, path buf: %s",
248                                 rctx->cur_subvol.path);
249                 ret = -EINVAL;
250                 goto out;
251         }
252
253         if (*rctx->dest_dir_path == 0) {
254                 strncpy_null(rctx->cur_subvol_path, path);
255         } else {
256                 ret = path_cat_out(rctx->cur_subvol_path, rctx->dest_dir_path,
257                                    path);
258                 if (ret < 0) {
259                         error("snapshot: path invalid: %s", path);
260                         goto out;
261                 }
262         }
263         ret = path_cat3_out(rctx->full_subvol_path, rctx->root_path,
264                             rctx->dest_dir_path, path);
265         if (ret < 0) {
266                 error("snapshot: path invalid: %s", path);
267                 goto out;
268         }
269
270         fprintf(stdout, "At snapshot %s\n", path);
271
272         memcpy(rctx->cur_subvol.received_uuid, uuid, BTRFS_UUID_SIZE);
273         rctx->cur_subvol.stransid = ctransid;
274
275         if (g_verbose) {
276                 uuid_unparse((u8*)rctx->cur_subvol.received_uuid, uuid_str);
277                 fprintf(stderr, "receiving snapshot %s uuid=%s, "
278                                 "ctransid=%llu ", path, uuid_str,
279                                 rctx->cur_subvol.stransid);
280                 uuid_unparse(parent_uuid, uuid_str);
281                 fprintf(stderr, "parent_uuid=%s, parent_ctransid=%llu\n",
282                                 uuid_str, parent_ctransid);
283         }
284
285         memset(&args_v2, 0, sizeof(args_v2));
286         strncpy_null(args_v2.name, path);
287
288         parent_subvol = subvol_uuid_search(&rctx->sus, 0, parent_uuid,
289                                            parent_ctransid, NULL,
290                                            subvol_search_by_received_uuid);
291         if (IS_ERR_OR_NULL(parent_subvol)) {
292                 parent_subvol = subvol_uuid_search(&rctx->sus, 0, parent_uuid,
293                                                    parent_ctransid, NULL,
294                                                    subvol_search_by_uuid);
295         }
296         if (IS_ERR_OR_NULL(parent_subvol)) {
297                 if (!parent_subvol)
298                         ret = -ENOENT;
299                 else
300                         ret = PTR_ERR(parent_subvol);
301                 error("cannot find parent subvolume");
302                 goto out;
303         }
304
305         /*
306          * The path is resolved from the root subvol, but we could be in some
307          * subvolume under the root subvolume, so try and adjust the path to be
308          * relative to our root path.
309          */
310         if (rctx->full_root_path) {
311                 size_t root_len;
312                 size_t sub_len;
313
314                 root_len = strlen(rctx->full_root_path);
315                 sub_len = strlen(parent_subvol->path);
316
317                 /* First make sure the parent subvol is actually in our path */
318                 if (sub_len < root_len ||
319                     strstr(parent_subvol->path, rctx->full_root_path) == NULL) {
320                         error(
321                 "parent subvol is not reachable from inside the root subvol");
322                         ret = -ENOENT;
323                         goto out;
324                 }
325
326                 if (sub_len == root_len) {
327                         parent_subvol->path[0] = '/';
328                         parent_subvol->path[1] = '\0';
329                 } else {
330                         /*
331                          * root path is foo/bar
332                          * subvol path is foo/bar/baz
333                          *
334                          * we need to have baz be the path, so we need to move
335                          * the bit after foo/bar/, so path + root_len + 1, and
336                          * move the part we care about, so sub_len - root_len -
337                          * 1.
338                          */
339                         memmove(parent_subvol->path,
340                                 parent_subvol->path + root_len + 1,
341                                 sub_len - root_len - 1);
342                         parent_subvol->path[sub_len - root_len - 1] = '\0';
343                 }
344         }
345         /*if (rs_args.ctransid > rs_args.rtransid) {
346                 if (!r->force) {
347                         ret = -EINVAL;
348                         fprintf(stderr, "ERROR: subvolume %s was modified after it was received.\n", r->subvol_parent_name);
349                         goto out;
350                 } else {
351                         fprintf(stderr, "WARNING: subvolume %s was modified after it was received.\n", r->subvol_parent_name);
352                 }
353         }*/
354
355         if (*parent_subvol->path == 0)
356                 args_v2.fd = dup(rctx->mnt_fd);
357         else
358                 args_v2.fd = openat(rctx->mnt_fd, parent_subvol->path,
359                                     O_RDONLY | O_NOATIME);
360         if (args_v2.fd < 0) {
361                 ret = -errno;
362                 if (errno != ENOENT)
363                         error("cannot open %s: %s",
364                                         parent_subvol->path, strerror(-ret));
365                 else
366                         fprintf(stderr,
367                                 "It seems that you have changed your default "
368                                 "subvolume or you specify other subvolume to\n"
369                                 "mount btrfs, try to remount this btrfs filesystem "
370                                 "with fs tree, and run btrfs receive again!\n");
371                 goto out;
372         }
373
374         ret = ioctl(rctx->dest_dir_fd, BTRFS_IOC_SNAP_CREATE_V2, &args_v2);
375         close(args_v2.fd);
376         if (ret < 0) {
377                 ret = -errno;
378                 error("creating snapshot %s -> %s failed: %s",
379                                 parent_subvol->path, path, strerror(-ret));
380                 goto out;
381         }
382
383 out:
384         if (parent_subvol) {
385                 free(parent_subvol->path);
386                 free(parent_subvol);
387         }
388         return ret;
389 }
390
391 static int process_mkfile(const char *path, void *user)
392 {
393         int ret;
394         struct btrfs_receive *rctx = user;
395         char full_path[PATH_MAX];
396
397         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
398         if (ret < 0) {
399                 error("mkfile: path invalid: %s", path);
400                 goto out;
401         }
402
403         if (g_verbose >= 2)
404                 fprintf(stderr, "mkfile %s\n", path);
405
406         ret = creat(full_path, 0600);
407         if (ret < 0) {
408                 ret = -errno;
409                 error("mkfile %s failed: %s", path, strerror(-ret));
410                 goto out;
411         }
412         close(ret);
413         ret = 0;
414
415 out:
416         return ret;
417 }
418
419 static int process_mkdir(const char *path, void *user)
420 {
421         int ret;
422         struct btrfs_receive *rctx = user;
423         char full_path[PATH_MAX];
424
425         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
426         if (ret < 0) {
427                 error("mkdir: path invalid: %s", path);
428                 goto out;
429         }
430
431         if (g_verbose >= 2)
432                 fprintf(stderr, "mkdir %s\n", path);
433
434         ret = mkdir(full_path, 0700);
435         if (ret < 0) {
436                 ret = -errno;
437                 error("mkdir %s failed: %s", path, strerror(-ret));
438         }
439
440 out:
441         return ret;
442 }
443
444 static int process_mknod(const char *path, u64 mode, u64 dev, void *user)
445 {
446         int ret;
447         struct btrfs_receive *rctx = user;
448         char full_path[PATH_MAX];
449
450         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
451         if (ret < 0) {
452                 error("mknod: path invalid: %s", path);
453                 goto out;
454         }
455
456         if (g_verbose >= 2)
457                 fprintf(stderr, "mknod %s mode=%llu, dev=%llu\n",
458                                 path, mode, dev);
459
460         ret = mknod(full_path, mode & S_IFMT, dev);
461         if (ret < 0) {
462                 ret = -errno;
463                 error("mknod %s failed: %s", path, strerror(-ret));
464         }
465
466 out:
467         return ret;
468 }
469
470 static int process_mkfifo(const char *path, void *user)
471 {
472         int ret;
473         struct btrfs_receive *rctx = user;
474         char full_path[PATH_MAX];
475
476         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
477         if (ret < 0) {
478                 error("mkfifo: path invalid: %s", path);
479                 goto out;
480         }
481
482         if (g_verbose >= 2)
483                 fprintf(stderr, "mkfifo %s\n", path);
484
485         ret = mkfifo(full_path, 0600);
486         if (ret < 0) {
487                 ret = -errno;
488                 error("mkfifo %s failed: %s", path, strerror(-ret));
489         }
490
491 out:
492         return ret;
493 }
494
495 static int process_mksock(const char *path, void *user)
496 {
497         int ret;
498         struct btrfs_receive *rctx = user;
499         char full_path[PATH_MAX];
500
501         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
502         if (ret < 0) {
503                 error("mksock: path invalid: %s", path);
504                 goto out;
505         }
506
507         if (g_verbose >= 2)
508                 fprintf(stderr, "mksock %s\n", path);
509
510         ret = mknod(full_path, 0600 | S_IFSOCK, 0);
511         if (ret < 0) {
512                 ret = -errno;
513                 error("mknod %s failed: %s", path, strerror(-ret));
514         }
515
516 out:
517         return ret;
518 }
519
520 static int process_symlink(const char *path, const char *lnk, void *user)
521 {
522         int ret;
523         struct btrfs_receive *rctx = user;
524         char full_path[PATH_MAX];
525
526         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
527         if (ret < 0) {
528                 error("symlink: path invalid: %s", path);
529                 goto out;
530         }
531
532         if (g_verbose >= 2)
533                 fprintf(stderr, "symlink %s -> %s\n", path, lnk);
534
535         ret = symlink(lnk, full_path);
536         if (ret < 0) {
537                 ret = -errno;
538                 error("symlink %s -> %s failed: %s", path,
539                                 lnk, strerror(-ret));
540         }
541
542 out:
543         return ret;
544 }
545
546 static int process_rename(const char *from, const char *to, void *user)
547 {
548         int ret;
549         struct btrfs_receive *rctx = user;
550         char full_from[PATH_MAX];
551         char full_to[PATH_MAX];
552
553         ret = path_cat_out(full_from, rctx->full_subvol_path, from);
554         if (ret < 0) {
555                 error("rename: source path invalid: %s", from);
556                 goto out;
557         }
558
559         ret = path_cat_out(full_to, rctx->full_subvol_path, to);
560         if (ret < 0) {
561                 error("rename: target path invalid: %s", to);
562                 goto out;
563         }
564
565         if (g_verbose >= 2)
566                 fprintf(stderr, "rename %s -> %s\n", from, to);
567
568         ret = rename(full_from, full_to);
569         if (ret < 0) {
570                 ret = -errno;
571                 error("rename %s -> %s failed: %s", from,
572                                 to, strerror(-ret));
573         }
574
575 out:
576         return ret;
577 }
578
579 static int process_link(const char *path, const char *lnk, void *user)
580 {
581         int ret;
582         struct btrfs_receive *rctx = user;
583         char full_path[PATH_MAX];
584         char full_link_path[PATH_MAX];
585
586         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
587         if (ret < 0) {
588                 error("link: source path invalid: %s", full_path);
589                 goto out;
590         }
591
592         ret = path_cat_out(full_link_path, rctx->full_subvol_path, lnk);
593         if (ret < 0) {
594                 error("link: target path invalid: %s", full_link_path);
595                 goto out;
596         }
597
598         if (g_verbose >= 2)
599                 fprintf(stderr, "link %s -> %s\n", path, lnk);
600
601         ret = link(full_link_path, full_path);
602         if (ret < 0) {
603                 ret = -errno;
604                 error("link %s -> %s failed: %s", path, lnk, strerror(-ret));
605         }
606
607 out:
608         return ret;
609 }
610
611
612 static int process_unlink(const char *path, void *user)
613 {
614         int ret;
615         struct btrfs_receive *rctx = user;
616         char full_path[PATH_MAX];
617
618         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
619         if (ret < 0) {
620                 error("unlink: path invalid: %s", path);
621                 goto out;
622         }
623
624         if (g_verbose >= 2)
625                 fprintf(stderr, "unlink %s\n", path);
626
627         ret = unlink(full_path);
628         if (ret < 0) {
629                 ret = -errno;
630                 error("unlink %s failed. %s", path, strerror(-ret));
631         }
632
633 out:
634         return ret;
635 }
636
637 static int process_rmdir(const char *path, void *user)
638 {
639         int ret;
640         struct btrfs_receive *rctx = user;
641         char full_path[PATH_MAX];
642
643         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
644         if (ret < 0) {
645                 error("rmdir: path invalid: %s", path);
646                 goto out;
647         }
648
649         if (g_verbose >= 2)
650                 fprintf(stderr, "rmdir %s\n", path);
651
652         ret = rmdir(full_path);
653         if (ret < 0) {
654                 ret = -errno;
655                 error("rmdir %s failed: %s", path, strerror(-ret));
656         }
657
658 out:
659         return ret;
660 }
661
662 static int open_inode_for_write(struct btrfs_receive *rctx, const char *path)
663 {
664         int ret = 0;
665
666         if (rctx->write_fd != -1) {
667                 if (strcmp(rctx->write_path, path) == 0)
668                         goto out;
669                 close(rctx->write_fd);
670                 rctx->write_fd = -1;
671         }
672
673         rctx->write_fd = open(path, O_RDWR);
674         if (rctx->write_fd < 0) {
675                 ret = -errno;
676                 error("cannot open %s: %s", path, strerror(-ret));
677                 goto out;
678         }
679         strncpy_null(rctx->write_path, path);
680
681 out:
682         return ret;
683 }
684
685 static void close_inode_for_write(struct btrfs_receive *rctx)
686 {
687         if(rctx->write_fd == -1)
688                 return;
689
690         close(rctx->write_fd);
691         rctx->write_fd = -1;
692         rctx->write_path[0] = 0;
693 }
694
695 static int process_write(const char *path, const void *data, u64 offset,
696                          u64 len, void *user)
697 {
698         int ret = 0;
699         struct btrfs_receive *rctx = user;
700         char full_path[PATH_MAX];
701         u64 pos = 0;
702         int w;
703
704         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
705         if (ret < 0) {
706                 error("write: path invalid: %s", path);
707                 goto out;
708         }
709
710         ret = open_inode_for_write(rctx, full_path);
711         if (ret < 0)
712                 goto out;
713
714         while (pos < len) {
715                 w = pwrite(rctx->write_fd, (char*)data + pos, len - pos,
716                                 offset + pos);
717                 if (w < 0) {
718                         ret = -errno;
719                         error("writing to %s failed: %s",
720                                         path, strerror(-ret));
721                         goto out;
722                 }
723                 pos += w;
724         }
725
726 out:
727         return ret;
728 }
729
730 static int process_clone(const char *path, u64 offset, u64 len,
731                          const u8 *clone_uuid, u64 clone_ctransid,
732                          const char *clone_path, u64 clone_offset,
733                          void *user)
734 {
735         int ret;
736         struct btrfs_receive *rctx = user;
737         struct btrfs_ioctl_clone_range_args clone_args;
738         struct subvol_info *si = NULL;
739         char full_path[PATH_MAX];
740         char *subvol_path = NULL;
741         char full_clone_path[PATH_MAX];
742         int clone_fd = -1;
743
744         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
745         if (ret < 0) {
746                 error("clone: source path invalid: %s", path);
747                 goto out;
748         }
749
750         ret = open_inode_for_write(rctx, full_path);
751         if (ret < 0)
752                 goto out;
753
754         si = subvol_uuid_search(&rctx->sus, 0, clone_uuid, clone_ctransid,
755                                 NULL,
756                                 subvol_search_by_received_uuid);
757         if (IS_ERR_OR_NULL(si)) {
758                 if (memcmp(clone_uuid, rctx->cur_subvol.received_uuid,
759                                 BTRFS_UUID_SIZE) == 0) {
760                         /* TODO check generation of extent */
761                         subvol_path = strdup(rctx->cur_subvol_path);
762                 } else {
763                         if (!si)
764                                 ret = -ENOENT;
765                         else
766                                 ret = PTR_ERR(si);
767                         error("clone: did not find source subvol");
768                         goto out;
769                 }
770         } else {
771                 /*if (rs_args.ctransid > rs_args.rtransid) {
772                         if (!r->force) {
773                                 ret = -EINVAL;
774                                 fprintf(stderr, "ERROR: subvolume %s was "
775                                                 "modified after it was "
776                                                 "received.\n",
777                                                 r->subvol_parent_name);
778                                 goto out;
779                         } else {
780                                 fprintf(stderr, "WARNING: subvolume %s was "
781                                                 "modified after it was "
782                                                 "received.\n",
783                                                 r->subvol_parent_name);
784                         }
785                 }*/
786                 subvol_path = strdup(si->path);
787         }
788
789         ret = path_cat_out(full_clone_path, subvol_path, clone_path);
790         if (ret < 0) {
791                 error("clone: target path invalid: %s", clone_path);
792                 goto out;
793         }
794
795         clone_fd = openat(rctx->mnt_fd, full_clone_path, O_RDONLY | O_NOATIME);
796         if (clone_fd < 0) {
797                 ret = -errno;
798                 error("cannot open %s: %s", full_clone_path, strerror(-ret));
799                 goto out;
800         }
801
802         clone_args.src_fd = clone_fd;
803         clone_args.src_offset = clone_offset;
804         clone_args.src_length = len;
805         clone_args.dest_offset = offset;
806         ret = ioctl(rctx->write_fd, BTRFS_IOC_CLONE_RANGE, &clone_args);
807         if (ret < 0) {
808                 ret = -errno;
809                 error("failed to clone extents to %s\n%s",
810                                 path, strerror(-ret));
811                 goto out;
812         }
813
814 out:
815         if (si) {
816                 free(si->path);
817                 free(si);
818         }
819         free(subvol_path);
820         if (clone_fd != -1)
821                 close(clone_fd);
822         return ret;
823 }
824
825
826 static int process_set_xattr(const char *path, const char *name,
827                              const void *data, int len, void *user)
828 {
829         int ret = 0;
830         struct btrfs_receive *rctx = user;
831         char full_path[PATH_MAX];
832
833         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
834         if (ret < 0) {
835                 error("set_xattr: path invalid: %s", path);
836                 goto out;
837         }
838
839         if (strcmp("security.capability", name) == 0) {
840                 if (g_verbose >= 3)
841                         fprintf(stderr, "set_xattr: cache capabilities\n");
842                 if (rctx->cached_capabilities_len)
843                         warning("capabilities set multiple times per file: %s",
844                                 full_path);
845                 if (len > sizeof(rctx->cached_capabilities)) {
846                         error("capabilities encoded to %d bytes, buffer too small",
847                                 len);
848                         ret = -E2BIG;
849                         goto out;
850                 }
851                 rctx->cached_capabilities_len = len;
852                 memcpy(rctx->cached_capabilities, data, len);
853         }
854
855         if (g_verbose >= 2) {
856                 fprintf(stderr, "set_xattr %s - name=%s data_len=%d "
857                                 "data=%.*s\n", path, name, len,
858                                 len, (char*)data);
859         }
860
861         ret = lsetxattr(full_path, name, data, len, 0);
862         if (ret < 0) {
863                 ret = -errno;
864                 error("lsetxattr %s %s=%.*s failed: %s",
865                                 path, name, len, (char*)data, strerror(-ret));
866                 goto out;
867         }
868
869 out:
870         return ret;
871 }
872
873 static int process_remove_xattr(const char *path, const char *name, void *user)
874 {
875         int ret = 0;
876         struct btrfs_receive *rctx = user;
877         char full_path[PATH_MAX];
878
879         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
880         if (ret < 0) {
881                 error("remove_xattr: path invalid: %s", path);
882                 goto out;
883         }
884
885         if (g_verbose >= 2) {
886                 fprintf(stderr, "remove_xattr %s - name=%s\n",
887                                 path, name);
888         }
889
890         ret = lremovexattr(full_path, name);
891         if (ret < 0) {
892                 ret = -errno;
893                 error("lremovexattr %s %s failed: %s",
894                                 path, name, strerror(-ret));
895                 goto out;
896         }
897
898 out:
899         return ret;
900 }
901
902 static int process_truncate(const char *path, u64 size, void *user)
903 {
904         int ret = 0;
905         struct btrfs_receive *rctx = user;
906         char full_path[PATH_MAX];
907
908         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
909         if (ret < 0) {
910                 error("truncate: path invalid: %s", path);
911                 goto out;
912         }
913
914         if (g_verbose >= 2)
915                 fprintf(stderr, "truncate %s size=%llu\n", path, size);
916
917         ret = truncate(full_path, size);
918         if (ret < 0) {
919                 ret = -errno;
920                 error("truncate %s failed: %s", path, strerror(-ret));
921                 goto out;
922         }
923
924 out:
925         return ret;
926 }
927
928 static int process_chmod(const char *path, u64 mode, void *user)
929 {
930         int ret = 0;
931         struct btrfs_receive *rctx = user;
932         char full_path[PATH_MAX];
933
934         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
935         if (ret < 0) {
936                 error("chmod: path invalid: %s", path);
937                 goto out;
938         }
939
940         if (g_verbose >= 2)
941                 fprintf(stderr, "chmod %s - mode=0%o\n", path, (int)mode);
942
943         ret = chmod(full_path, mode);
944         if (ret < 0) {
945                 ret = -errno;
946                 error("chmod %s failed: %s", path, strerror(-ret));
947                 goto out;
948         }
949
950 out:
951         return ret;
952 }
953
954 static int process_chown(const char *path, u64 uid, u64 gid, void *user)
955 {
956         int ret = 0;
957         struct btrfs_receive *rctx = user;
958         char full_path[PATH_MAX];
959
960         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
961         if (ret < 0) {
962                 error("chown: path invalid: %s", path);
963                 goto out;
964         }
965
966         if (g_verbose >= 2)
967                 fprintf(stderr, "chown %s - uid=%llu, gid=%llu\n", path,
968                                 uid, gid);
969
970         ret = lchown(full_path, uid, gid);
971         if (ret < 0) {
972                 ret = -errno;
973                 error("chown %s failed: %s", path, strerror(-ret));
974                 goto out;
975         }
976
977         if (rctx->cached_capabilities_len) {
978                 if (g_verbose >= 2)
979                         fprintf(stderr, "chown: restore capabilities\n");
980                 ret = lsetxattr(full_path, "security.capability",
981                                 rctx->cached_capabilities,
982                                 rctx->cached_capabilities_len, 0);
983                 memset(rctx->cached_capabilities, 0,
984                                 sizeof(rctx->cached_capabilities));
985                 rctx->cached_capabilities_len = 0;
986                 if (ret < 0) {
987                         ret = -errno;
988                         error("restoring capabilities %s: %s",
989                                         path, strerror(-ret));
990                         goto out;
991                 }
992         }
993
994 out:
995         return ret;
996 }
997
998 static int process_utimes(const char *path, struct timespec *at,
999                           struct timespec *mt, struct timespec *ct,
1000                           void *user)
1001 {
1002         int ret = 0;
1003         struct btrfs_receive *rctx = user;
1004         char full_path[PATH_MAX];
1005         struct timespec tv[2];
1006
1007         ret = path_cat_out(full_path, rctx->full_subvol_path, path);
1008         if (ret < 0) {
1009                 error("utimes: path invalid: %s", path);
1010                 goto out;
1011         }
1012
1013         if (g_verbose >= 2)
1014                 fprintf(stderr, "utimes %s\n", path);
1015
1016         tv[0] = *at;
1017         tv[1] = *mt;
1018         ret = utimensat(AT_FDCWD, full_path, tv, AT_SYMLINK_NOFOLLOW);
1019         if (ret < 0) {
1020                 ret = -errno;
1021                 error("utimes %s failed: %s",
1022                                 path, strerror(-ret));
1023                 goto out;
1024         }
1025
1026 out:
1027         return ret;
1028 }
1029
1030 static int process_update_extent(const char *path, u64 offset, u64 len,
1031                 void *user)
1032 {
1033         if (g_verbose >= 2)
1034                 fprintf(stderr, "update_extent %s: offset=%llu, len=%llu\n",
1035                                 path, (unsigned long long)offset,
1036                                 (unsigned long long)len);
1037
1038         /*
1039          * Sent with BTRFS_SEND_FLAG_NO_FILE_DATA, nothing to do.
1040          */
1041
1042         return 0;
1043 }
1044
1045 static struct btrfs_send_ops send_ops = {
1046         .subvol = process_subvol,
1047         .snapshot = process_snapshot,
1048         .mkfile = process_mkfile,
1049         .mkdir = process_mkdir,
1050         .mknod = process_mknod,
1051         .mkfifo = process_mkfifo,
1052         .mksock = process_mksock,
1053         .symlink = process_symlink,
1054         .rename = process_rename,
1055         .link = process_link,
1056         .unlink = process_unlink,
1057         .rmdir = process_rmdir,
1058         .write = process_write,
1059         .clone = process_clone,
1060         .set_xattr = process_set_xattr,
1061         .remove_xattr = process_remove_xattr,
1062         .truncate = process_truncate,
1063         .chmod = process_chmod,
1064         .chown = process_chown,
1065         .utimes = process_utimes,
1066         .update_extent = process_update_extent,
1067 };
1068
1069 static int do_receive(struct btrfs_receive *rctx, const char *tomnt,
1070                       char *realmnt, int r_fd, u64 max_errors)
1071 {
1072         u64 subvol_id;
1073         int ret;
1074         char *dest_dir_full_path;
1075         char root_subvol_path[PATH_MAX];
1076         int end = 0;
1077         int count;
1078
1079         dest_dir_full_path = realpath(tomnt, NULL);
1080         if (!dest_dir_full_path) {
1081                 ret = -errno;
1082                 error("realpath(%s) failed: %s", tomnt, strerror(-ret));
1083                 goto out;
1084         }
1085         rctx->dest_dir_fd = open(dest_dir_full_path, O_RDONLY | O_NOATIME);
1086         if (rctx->dest_dir_fd < 0) {
1087                 ret = -errno;
1088                 error("cannot open destination directory %s: %s",
1089                         dest_dir_full_path, strerror(-ret));
1090                 goto out;
1091         }
1092
1093         if (realmnt[0]) {
1094                 rctx->root_path = realmnt;
1095         } else {
1096                 ret = find_mount_root(dest_dir_full_path, &rctx->root_path);
1097                 if (ret < 0) {
1098                         error("failed to determine mount point for %s: %s",
1099                                 dest_dir_full_path, strerror(-ret));
1100                         ret = -EINVAL;
1101                         goto out;
1102                 }
1103                 if (ret > 0) {
1104                         error("%s doesn't belong to btrfs mount point",
1105                                 dest_dir_full_path);
1106                         ret = -EINVAL;
1107                         goto out;
1108                 }
1109         }
1110         rctx->mnt_fd = open(rctx->root_path, O_RDONLY | O_NOATIME);
1111         if (rctx->mnt_fd < 0) {
1112                 ret = -errno;
1113                 error("cannot open %s: %s", rctx->root_path, strerror(-ret));
1114                 goto out;
1115         }
1116
1117         /*
1118          * If we use -m or a default subvol we want to resolve the path to the
1119          * subvolume we're sitting in so that we can adjust the paths of any
1120          * subvols we want to receive in.
1121          */
1122         ret = btrfs_list_get_path_rootid(rctx->mnt_fd, &subvol_id);
1123         if (ret)
1124                 goto out;
1125
1126         root_subvol_path[0] = 0;
1127         ret = btrfs_subvolid_resolve(rctx->mnt_fd, root_subvol_path,
1128                                      PATH_MAX, subvol_id);
1129         if (ret) {
1130                 error("cannot resolve our subvol path");
1131                 goto out;
1132         }
1133
1134         /*
1135          * Ok we're inside of a subvol off of the root subvol, we need to
1136          * actually set full_root_path.
1137          */
1138         if (*root_subvol_path)
1139                 rctx->full_root_path = root_subvol_path;
1140
1141         if (rctx->dest_dir_chroot) {
1142                 if (chroot(dest_dir_full_path)) {
1143                         ret = -errno;
1144                         error("failed to chroot to %s: %s",
1145                                 dest_dir_full_path, strerror(-ret));
1146                         goto out;
1147                 }
1148                 if (chdir("/")) {
1149                         ret = -errno;
1150                         error("failed to chdir to / after chroot: %s",
1151                                 strerror(-ret));
1152                         goto out;
1153                 }
1154                 fprintf(stderr, "Chroot to %s\n", dest_dir_full_path);
1155                 rctx->root_path = strdup("/");
1156                 rctx->dest_dir_path = rctx->root_path;
1157         } else {
1158                 /*
1159                  * find_mount_root returns a root_path that is a subpath of
1160                  * dest_dir_full_path. Now get the other part of root_path,
1161                  * which is the destination dir relative to root_path.
1162                  */
1163                 rctx->dest_dir_path = dest_dir_full_path + strlen(rctx->root_path);
1164                 while (rctx->dest_dir_path[0] == '/')
1165                         rctx->dest_dir_path++;
1166         }
1167
1168         ret = subvol_uuid_search_init(rctx->mnt_fd, &rctx->sus);
1169         if (ret < 0)
1170                 goto out;
1171
1172         count = 0;
1173         while (!end) {
1174                 if (rctx->cached_capabilities_len) {
1175                         if (g_verbose >= 3)
1176                                 fprintf(stderr, "clear cached capabilities\n");
1177                         memset(rctx->cached_capabilities, 0,
1178                                         sizeof(rctx->cached_capabilities));
1179                         rctx->cached_capabilities_len = 0;
1180                 }
1181
1182                 ret = btrfs_read_and_process_send_stream(r_fd, &send_ops,
1183                                                          rctx,
1184                                                          rctx->honor_end_cmd,
1185                                                          max_errors);
1186                 if (ret < 0)
1187                         goto out;
1188                 /* Empty stream is invalid */
1189                 if (ret && count == 0) {
1190                         error("empty stream is not considered valid");
1191                         ret = -EINVAL;
1192                         goto out;
1193                 }
1194                 count++;
1195                 if (ret)
1196                         end = 1;
1197
1198                 close_inode_for_write(rctx);
1199                 ret = finish_subvol(rctx);
1200                 if (ret < 0)
1201                         goto out;
1202         }
1203         ret = 0;
1204
1205 out:
1206         if (rctx->write_fd != -1) {
1207                 close(rctx->write_fd);
1208                 rctx->write_fd = -1;
1209         }
1210
1211         if (rctx->root_path != realmnt)
1212                 free(rctx->root_path);
1213         rctx->root_path = NULL;
1214         rctx->dest_dir_path = NULL;
1215         free(dest_dir_full_path);
1216         subvol_uuid_search_finit(&rctx->sus);
1217         if (rctx->mnt_fd != -1) {
1218                 close(rctx->mnt_fd);
1219                 rctx->mnt_fd = -1;
1220         }
1221         if (rctx->dest_dir_fd != -1) {
1222                 close(rctx->dest_dir_fd);
1223                 rctx->dest_dir_fd = -1;
1224         }
1225
1226         return ret;
1227 }
1228
1229 int cmd_receive(int argc, char **argv)
1230 {
1231         char *tomnt = NULL;
1232         char fromfile[PATH_MAX];
1233         char realmnt[PATH_MAX];
1234         struct btrfs_receive rctx;
1235         int receive_fd = fileno(stdin);
1236         u64 max_errors = 1;
1237         int dump = 0;
1238         int ret = 0;
1239
1240         memset(&rctx, 0, sizeof(rctx));
1241         rctx.mnt_fd = -1;
1242         rctx.write_fd = -1;
1243         rctx.dest_dir_fd = -1;
1244         rctx.dest_dir_chroot = 0;
1245         realmnt[0] = 0;
1246         fromfile[0] = 0;
1247
1248         while (1) {
1249                 int c;
1250                 enum { GETOPT_VAL_DUMP = 257 };
1251                 static const struct option long_opts[] = {
1252                         { "max-errors", required_argument, NULL, 'E' },
1253                         { "chroot", no_argument, NULL, 'C' },
1254                         { "dump", no_argument, NULL, GETOPT_VAL_DUMP },
1255                         { NULL, 0, NULL, 0 }
1256                 };
1257
1258                 c = getopt_long(argc, argv, "Cevf:m:", long_opts, NULL);
1259                 if (c < 0)
1260                         break;
1261
1262                 switch (c) {
1263                 case 'v':
1264                         g_verbose++;
1265                         break;
1266                 case 'f':
1267                         if (arg_copy_path(fromfile, optarg, sizeof(fromfile))) {
1268                                 error("input file path too long (%zu)",
1269                                         strlen(optarg));
1270                                 ret = 1;
1271                                 goto out;
1272                         }
1273                         break;
1274                 case 'e':
1275                         rctx.honor_end_cmd = 1;
1276                         break;
1277                 case 'C':
1278                         rctx.dest_dir_chroot = 1;
1279                         break;
1280                 case 'E':
1281                         max_errors = arg_strtou64(optarg);
1282                         break;
1283                 case 'm':
1284                         if (arg_copy_path(realmnt, optarg, sizeof(realmnt))) {
1285                                 error("mount point path too long (%zu)",
1286                                         strlen(optarg));
1287                                 ret = 1;
1288                                 goto out;
1289                         }
1290                         break;
1291                 case GETOPT_VAL_DUMP:
1292                         dump = 1;
1293                         break;
1294                 case '?':
1295                 default:
1296                         error("receive args invalid");
1297                         return 1;
1298                 }
1299         }
1300
1301         if (dump && check_argc_exact(argc - optind, 0))
1302                 usage(cmd_receive_usage);
1303         if (!dump && check_argc_exact(argc - optind, 1))
1304                 usage(cmd_receive_usage);
1305
1306         tomnt = argv[optind];
1307
1308         if (fromfile[0]) {
1309                 receive_fd = open(fromfile, O_RDONLY | O_NOATIME);
1310                 if (receive_fd < 0) {
1311                         error("cannot open %s: %s", fromfile, strerror(errno));
1312                         goto out;
1313                 }
1314         }
1315
1316         if (dump) {
1317                 struct btrfs_dump_send_args dump_args;
1318
1319                 dump_args.root_path[0] = '.';
1320                 dump_args.root_path[1] = '\0';
1321                 dump_args.full_subvol_path[0] = '.';
1322                 dump_args.full_subvol_path[1] = '\0';
1323                 ret = btrfs_read_and_process_send_stream(receive_fd,
1324                                 &btrfs_print_send_ops, &dump_args, 0, 0);
1325                 if (ret < 0)
1326                         error("failed to dump the send stream: %s",
1327                               strerror(-ret));
1328         } else {
1329                 ret = do_receive(&rctx, tomnt, realmnt, receive_fd, max_errors);
1330         }
1331
1332         if (receive_fd != fileno(stdin))
1333                 close(receive_fd);
1334 out:
1335
1336         return !!ret;
1337 }
1338
1339 const char * const cmd_receive_usage[] = {
1340         "btrfs receive [options] <mount>\n"
1341         "btrfs receive --dump [options]",
1342         "Receive subvolumes from a stream",
1343         "Receives one or more subvolumes that were previously",
1344         "sent with btrfs send. The received subvolumes are stored",
1345         "into MOUNT.",
1346         "The receive will fail in case the receiving subvolume",
1347         "already exists. It will also fail in case a previously",
1348         "received subvolume has been changed after it was received.",
1349         "After receiving a subvolume, it is immediately set to",
1350         "read-only.",
1351         "",
1352         "-v               increase verbosity about performed actions",
1353         "-f FILE          read the stream from FILE instead of stdin",
1354         "-e               terminate after receiving an <end cmd> marker in the stream.",
1355         "                 Without this option the receiver side terminates only in case",
1356         "                 of an error on end of file.",
1357         "-C|--chroot      confine the process to <mount> using chroot",
1358         "-E|--max-errors NERR",
1359         "                 terminate as soon as NERR errors occur while",
1360         "                 stream processing commands from the stream.",
1361         "                 Default value is 1. A value of 0 means no limit.",
1362         "-m ROOTMOUNT     the root mount point of the destination filesystem.",
1363         "                 If /proc is not accessible, use this to tell us where",
1364         "                 this file system is mounted.",
1365         "--dump           dump stream metadata, one line per operation,",
1366         "                 does not require the MOUNT parameter",
1367         NULL
1368 };