btrfs-progs: Add further checks to btrfs replace start command
[platform/upstream/btrfs-progs.git] / btrfs-list.c
index 542dfe0..875a89d 100644 (file)
  * Boston, MA 021110-1307, USA.
  */
 
-#define _GNU_SOURCE
 #include <sys/ioctl.h>
 #include <sys/mount.h>
-#include "ioctl.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include "ctree.h"
 #include "transaction.h"
 #include "utils.h"
+#include "ioctl.h"
 #include <uuid/uuid.h>
 #include "btrfs-list.h"
+#include "rbtree-utils.h"
 
 #define BTRFS_LIST_NFILTERS_INCREASE   (2 * BTRFS_LIST_FILTER_MAX)
 #define BTRFS_LIST_NCOMPS_INCREASE     (2 * BTRFS_LIST_COMP_MAX)
@@ -85,6 +85,11 @@ static struct {
                .need_print     = 0,
        },
        {
+               .name           = "received_uuid",
+               .column_name    = "Received UUID",
+               .need_print     = 0,
+       },
+       {
                .name           = "uuid",
                .column_name    = "UUID",
                .need_print     = 0,
@@ -391,7 +396,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
                       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
                       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-                      time_t ot, void *uuid, void *puuid)
+                      time_t ot, void *uuid, void *puuid, void *ruuid)
 {
        struct root_info *ri;
 
@@ -429,6 +434,8 @@ static int update_root(struct root_lookup *root_lookup,
                memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
        if (puuid)
                memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+       if (ruuid)
+               memcpy(&ri->ruuid, ruuid, BTRFS_UUID_SIZE);
 
        return 0;
 }
@@ -447,17 +454,19 @@ static int update_root(struct root_lookup *root_lookup,
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
  * puuid: uuid of the root parent if any
+ * ruuid: uuid of the received subvol, if any
  */
 static int add_root(struct root_lookup *root_lookup,
                    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
                    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-                   time_t ot, void *uuid, void *puuid)
+                   time_t ot, void *uuid, void *puuid, void *ruuid)
 {
        struct root_info *ri;
        int ret;
 
        ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-                         dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
+                         dir_id, name, name_len, ogen, gen, ot,
+                         uuid, puuid, ruuid);
        if (!ret)
                return 0;
 
@@ -501,6 +510,9 @@ static int add_root(struct root_lookup *root_lookup,
        if (puuid)
                memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
+       if (ruuid)
+               memcpy(&ri->ruuid, ruuid, BTRFS_UUID_SIZE);
+
        ret = root_tree_insert(root_lookup, ri);
        if (ret) {
                printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -978,6 +990,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
        time_t t;
        u8 uuid[BTRFS_UUID_SIZE];
        u8 puuid[BTRFS_UUID_SIZE];
+       u8 ruuid[BTRFS_UUID_SIZE];
 
        root_lookup_init(root_lookup);
        memset(&args, 0, sizeof(args));
@@ -1030,7 +1043,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
                                add_root(root_lookup, sh.objectid, sh.offset,
                                         0, 0, dir_id, name, name_len, 0, 0, 0,
-                                        NULL, NULL);
+                                        NULL, NULL, NULL);
                        } else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
                                ri = (struct btrfs_root_item *)(args.buf + off);
                                gen = btrfs_root_generation(ri);
@@ -1041,16 +1054,18 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
                                        ogen = btrfs_root_otransid(ri);
                                        memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
                                        memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
+                                       memcpy(ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
                                } else {
                                        t = 0;
                                        ogen = 0;
                                        memset(uuid, 0, BTRFS_UUID_SIZE);
                                        memset(puuid, 0, BTRFS_UUID_SIZE);
+                                       memset(ruuid, 0, BTRFS_UUID_SIZE);
                                }
 
                                add_root(root_lookup, sh.objectid, 0,
                                         sh.offset, flags, 0, NULL, 0, ogen,
-                                        gen, t, uuid, puuid);
+                                        gen, t, uuid, puuid, ruuid);
                        }
 
                        off += sh.len;
@@ -1361,6 +1376,13 @@ static void print_subvolume_column(struct root_info *subv,
                        uuid_unparse(subv->puuid, uuidparse);
                printf("%s", uuidparse);
                break;
+       case BTRFS_LIST_RUUID:
+               if (uuid_is_null(subv->ruuid))
+                       strcpy(uuidparse, "-");
+               else
+                       uuid_unparse(subv->ruuid, uuidparse);
+               printf("%s", uuidparse);
+               break;
        case BTRFS_LIST_PATH:
                BUG_ON(!subv->full_path);
                printf("%s", subv->full_path);
@@ -1688,7 +1710,7 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen)
                ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
                e = errno;
                if (ret < 0) {
-                       fprintf(stderr, "ERROR: can't perform the search- %s\n",
+                       fprintf(stderr, "ERROR: can't perform the search - %s\n",
                                strerror(e));
                        break;
                }
@@ -1888,7 +1910,7 @@ int btrfs_list_get_path_rootid(int fd, u64 *treeid)
        ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
        if (ret < 0) {
                fprintf(stderr,
-                       "ERROR: can't perform the search -%s\n",
+                       "ERROR: can't perform the search - %s\n",
                        strerror(errno));
                return ret;
        }