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