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