btrfs-progs: docs: update dev stats help and manual page
[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>\n"
1334         "btrfs receive --dump [options]",
1335         "Receive subvolumes from a stream",
1336         "Receives one or more subvolumes that were previously",
1337         "sent with btrfs send. The received subvolumes are stored",
1338         "into MOUNT.",
1339         "The receive will fail in case the receiving subvolume",
1340         "already exists. It will also fail in case a previously",
1341         "received subvolume has been changed after it was received.",
1342         "After receiving a subvolume, it is immediately set to",
1343         "read-only.",
1344         "",
1345         "-v               increase verbosity about performed actions",
1346         "-f FILE          read the stream from FILE instead of stdin",
1347         "-e               terminate after receiving an <end cmd> marker in the stream.",
1348         "                 Without this option the receiver side terminates only in case",
1349         "                 of an error on end of file.",
1350         "-C|--chroot      confine the process to <mount> using chroot",
1351         "-E|--max-errors NERR",
1352         "                 terminate as soon as NERR errors occur while",
1353         "                 stream processing commands from the stream.",
1354         "                 Default value is 1. A value of 0 means no limit.",
1355         "-m ROOTMOUNT     the root mount point of the destination filesystem.",
1356         "                 If /proc is not accessible, use this to tell us where",
1357         "                 this file system is mounted.",
1358         "--dump           dump stream metadata, one line per operation,",
1359         "                 does not require the MOUNT parameter",
1360         NULL
1361 };