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