Btrfs-progs: remove unsed pthread attribute objects
[platform/upstream/btrfs-progs.git] / cmds-send.c
index f7f98bc..1cd457d 100644 (file)
@@ -39,6 +39,7 @@
 #include "ioctl.h"
 #include "commands.h"
 #include "list.h"
+#include "utils.h"
 
 #include "send.h"
 #include "send-utils.h"
@@ -57,47 +58,6 @@ struct btrfs_send {
        struct subvol_uuid_search sus;
 };
 
-int find_mount_root(const char *path, char **mount_root)
-{
-       FILE *mnttab;
-       int fd;
-       struct mntent *ent;
-       int len;
-       int longest_matchlen = 0;
-       char *longest_match = NULL;
-
-       fd = open(path, O_RDONLY | O_NOATIME);
-       if (fd < 0)
-               return -errno;
-       close(fd);
-
-       mnttab = fopen("/proc/mounts", "r");
-       while ((ent = getmntent(mnttab))) {
-               len = strlen(ent->mnt_dir);
-               if (strncmp(ent->mnt_dir, path, len) == 0) {
-                       /* match found */
-                       if (longest_matchlen < len) {
-                               free(longest_match);
-                               longest_matchlen = len;
-                               longest_match = strdup(ent->mnt_dir);
-                       }
-               }
-       }
-       fclose(mnttab);
-
-       if (!longest_match) {
-               fprintf(stderr,
-                       "ERROR: Failed to find mount root for path %s.\n",
-                       path);
-               return -ENOENT;
-       }
-
-       *mount_root = realpath(longest_match, NULL);
-       free(longest_match);
-
-       return 0;
-}
-
 static int get_root_id(struct btrfs_send *s, const char *path, u64 *root_id)
 {
        struct subvol_info *si;
@@ -275,37 +235,24 @@ out:
        return ERR_PTR(ret);
 }
 
-static int do_send(struct btrfs_send *send, u64 root_id, u64 parent_root_id,
-                  int is_first_subvol, int is_last_subvol)
+static int do_send(struct btrfs_send *send, u64 parent_root_id,
+                  int is_first_subvol, int is_last_subvol, char *subvol)
 {
        int ret;
        pthread_t t_read;
-       pthread_attr_t t_attr;
        struct btrfs_ioctl_send_args io_send;
-       struct subvol_info *si;
        void *t_err = NULL;
        int subvol_fd = -1;
        int pipefd[2] = {-1, -1};
 
-       si = subvol_uuid_search(&send->sus, root_id, NULL, 0, NULL,
-                       subvol_search_by_root_id);
-       if (!si) {
-               ret = -ENOENT;
-               fprintf(stderr, "ERROR: could not find subvol info for %llu",
-                               root_id);
-               goto out;
-       }
-
-       subvol_fd = openat(send->mnt_fd, si->path, O_RDONLY | O_NOATIME);
+       subvol_fd = openat(send->mnt_fd, subvol, O_RDONLY | O_NOATIME);
        if (subvol_fd < 0) {
                ret = -errno;
-               fprintf(stderr, "ERROR: open %s failed. %s\n", si->path,
+               fprintf(stderr, "ERROR: open %s failed. %s\n", subvol,
                                strerror(-ret));
                goto out;
        }
 
-       ret = pthread_attr_init(&t_attr);
-
        ret = pipe(pipefd);
        if (ret < 0) {
                ret = -errno;
@@ -318,7 +265,7 @@ static int do_send(struct btrfs_send *send, u64 root_id, u64 parent_root_id,
        send->send_fd = pipefd[0];
 
        if (!ret)
-               ret = pthread_create(&t_read, &t_attr, dump_thread,
+               ret = pthread_create(&t_read, NULL, dump_thread,
                                        send);
        if (ret) {
                ret = -ret;
@@ -367,8 +314,6 @@ static int do_send(struct btrfs_send *send, u64 root_id, u64 parent_root_id,
                goto out;
        }
 
-       pthread_attr_destroy(&t_attr);
-
        ret = 0;
 
 out:
@@ -378,10 +323,6 @@ out:
                close(pipefd[0]);
        if (pipefd[1] != -1)
                close(pipefd[1]);
-       if (si) {
-               free(si->path);
-               free(si);
-       }
        return ret;
 }
 
@@ -511,6 +452,18 @@ int cmd_send(int argc, char **argv)
                                                "root_id for %s\n", subvol);
                                goto out;
                        }
+
+                       ret = is_subvol_ro(&send, subvol);
+                       if (ret < 0)
+                               goto out;
+                       if (!ret) {
+                               ret = -EINVAL;
+                               fprintf(stderr,
+                               "ERROR: cloned subvol %s is not read-only.\n",
+                                       subvol);
+                               goto out;
+                       }
+
                        add_clone_source(&send, root_id);
                        subvol_uuid_search_finit(&send.sus);
                        free(subvol);
@@ -539,6 +492,18 @@ int cmd_send(int argc, char **argv)
                                                "%s\n", optarg, strerror(-ret));
                                goto out;
                        }
+
+                       ret = is_subvol_ro(&send, snapshot_parent);
+                       if (ret < 0)
+                               goto out;
+                       if (!ret) {
+                               ret = -EINVAL;
+                               fprintf(stderr,
+                                       "ERROR: parent %s is not read-only.\n",
+                                       snapshot_parent);
+                               goto out;
+                       }
+
                        full_send = 0;
                        break;
                case 'i':
@@ -554,11 +519,8 @@ int cmd_send(int argc, char **argv)
                }
        }
 
-       if (optind == argc) {
-               fprintf(stderr, "ERROR: send needs path to snapshot\n");
-               ret = 1;
-               goto out;
-       }
+       if (optind == argc)
+               usage(cmd_send_usage);
 
        if (outname != NULL) {
                send.dump_fd = creat(outname, 0600);
@@ -657,14 +619,6 @@ int cmd_send(int argc, char **argv)
                        goto out;
                }
 
-               ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
-                               &root_id);
-               if (ret < 0) {
-                       fprintf(stderr, "ERROR: could not resolve root_id "
-                                       "for %s\n", subvol);
-                       goto out;
-               }
-
                if (!full_send && !parent_root_id) {
                        ret = find_good_parent(&send, root_id, &parent_root_id);
                        if (ret < 0) {
@@ -693,8 +647,8 @@ int cmd_send(int argc, char **argv)
                        is_first_subvol = 1;
                        is_last_subvol = 1;
                }
-               ret = do_send(&send, root_id, parent_root_id,
-                             is_first_subvol, is_last_subvol);
+               ret = do_send(&send, parent_root_id, is_first_subvol,
+                             is_last_subvol, subvol);
                if (ret < 0)
                        goto out;
 
@@ -715,13 +669,13 @@ out:
                close(send.mnt_fd);
        free(send.root_path);
        subvol_uuid_search_finit(&send.sus);
-       return ret;
+       return !!ret;
 }
 
 const char * const cmd_send_usage[] = {
-       "btrfs send [-ve] [-p <parent>] [-c <clone-src>] [-f <outfile>] <subvol>",
-       "Send the subvolume to stdout.",
-       "Sends the subvolume specified by <subvol> to stdout.",
+       "btrfs send [-ve] [-p <parent>] [-c <clone-src>] [-f <outfile>] <subvol> [<subvol>...]",
+       "Send the subvolume(s) to stdout.",
+       "Sends the subvolume(s) specified by <subvol> to stdout.",
        "By default, this will send the whole subvolume. To do an incremental",
        "send, use '-p <parent>'. If you want to allow btrfs to clone from",
        "any additional local snapshots, use '-c <clone-src>' (multiple times",