@@ -535,54 +535,57 @@ static struct root_info *root_tree_search(struct rb_root *root_tree,
return NULL;
}
-static int update_root(struct rb_root *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 otime, u8 *uuid, u8 *puuid, u8 *ruuid)
+/* Update the root attributes of @found to @new, except the rootid. */
+static void update_root_attr(struct root_attr *found,
+ const struct root_attr *new)
{
- struct root_info *ri;
- struct root_attr *attrs;
+ if (new->name && new->name_len > 0) {
+ free(found->name);
- ri = root_tree_search(root_lookup, root_id);
- if (!ri || ri->attrs.root_id != root_id)
- return -ENOENT;
-
- attrs = &ri->attrs;
- if (name && name_len > 0) {
- free(attrs->name);
-
- attrs->name = malloc(name_len + 1);
- if (!attrs->name) {
+ found->name = malloc(new->name_len + 1);
+ if (!found->name) {
error_msg(ERROR_MSG_MEMORY, NULL);
exit(1);
}
- strncpy(attrs->name, name, name_len);
- attrs->name[name_len] = 0;
- attrs->name_len = name_len;
+ strncpy(found->name, new->name, new->name_len);
+ found->name[new->name_len] = '\0';
+ found->name_len = new->name_len;
}
- if (ref_tree)
- attrs->ref_tree = ref_tree;
- if (root_offset)
- attrs->root_offset = root_offset;
- if (flags)
- attrs->flags = flags;
- if (dir_id)
- attrs->dir_id = dir_id;
- if (gen)
- attrs->gen = gen;
- if (ogen)
- attrs->ogen = ogen;
- if (!attrs->ogen && root_offset)
- attrs->ogen = root_offset;
- if (otime)
- attrs->otime = otime;
- if (uuid)
- memcpy(&attrs->uuid, uuid, BTRFS_UUID_SIZE);
- if (puuid)
- memcpy(&attrs->puuid, puuid, BTRFS_UUID_SIZE);
- if (ruuid)
- memcpy(&attrs->ruuid, ruuid, BTRFS_UUID_SIZE);
+ if (new->ref_tree)
+ found->ref_tree = new->ref_tree;
+ if (new->root_offset)
+ found->root_offset = new->root_offset;
+ if (new->flags)
+ found->flags = new->flags;
+ if (new->dir_id)
+ found->dir_id = new->dir_id;
+ if (new->gen)
+ found->gen = new->gen;
+ if (new->ogen)
+ found->ogen = new->ogen;
+ if (!found->ogen && new->root_offset)
+ found->ogen = new->root_offset;
+ if (new->otime)
+ found->otime = new->otime;
+ if (new->uuid[0])
+ memcpy(&found->uuid, new->uuid, BTRFS_UUID_SIZE);
+ if (new->puuid[0])
+ memcpy(&found->puuid, new->puuid, BTRFS_UUID_SIZE);
+ if (new->ruuid[0])
+ memcpy(&found->ruuid, new->ruuid, BTRFS_UUID_SIZE);
+}
+
+static int update_root(struct rb_root *root_lookup,
+ struct root_attr const *new)
+{
+ struct root_info *ri;
+
+ ri = root_tree_search(root_lookup, new->root_id);
+ if (!ri || ri->attrs.root_id != new->root_id)
+ return -ENOENT;
+
+ update_root_attr(&ri->attrs, new);
return 0;
}
@@ -591,18 +594,12 @@ static int update_root(struct rb_root *root_lookup,
* into the lookup tree.
* attrs: the description for the new root.
*/
-static int add_root(struct rb_root *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 otime, u8 *uuid, u8 *puuid, u8 *ruuid)
+static int add_root(struct rb_root *root_lookup, const struct root_attr *new)
{
struct root_info *ri;
- struct root_attr *attrs;
int ret;
- ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
- dir_id, name, name_len, ogen, gen, otime,
- uuid, puuid, ruuid);
+ ret = update_root(root_lookup, new);
if (!ret)
return 0;
@@ -611,49 +608,14 @@ static int add_root(struct rb_root *root_lookup,
error_msg(ERROR_MSG_MEMORY, NULL);
exit(1);
}
- attrs = &ri->attrs;
- attrs->root_id = root_id;
+ ri->attrs.root_id = new->root_id;
- if (name && name_len > 0) {
- attrs->name = malloc(name_len + 1);
- if (!attrs->name) {
- error_msg(ERROR_MSG_MEMORY, NULL);
- exit(1);
- }
- strncpy(attrs->name, name, name_len);
- attrs->name[name_len] = 0;
- attrs->name_len = name_len;
- }
- if (ref_tree)
- attrs->ref_tree = ref_tree;
- if (dir_id)
- attrs->dir_id = dir_id;
- if (root_offset)
- attrs->root_offset = root_offset;
- if (flags)
- attrs->flags = flags;
- if (gen)
- attrs->gen = gen;
- if (ogen)
- attrs->ogen = ogen;
- if (!attrs->ogen && root_offset)
- attrs->ogen = root_offset;
- if (otime)
- attrs->otime = otime;
-
- if (uuid)
- memcpy(&attrs->uuid, uuid, BTRFS_UUID_SIZE);
-
- if (puuid)
- memcpy(&attrs->puuid, puuid, BTRFS_UUID_SIZE);
-
- if (ruuid)
- memcpy(&attrs->ruuid, ruuid, BTRFS_UUID_SIZE);
+ update_root_attr(&ri->attrs, new);
ret = root_tree_insert(root_lookup, ri);
if (ret < 0) {
errno = -ret;
- error("failed to insert subvolume %llu to tree: %m", root_id);
+ error("failed to insert subvolume %llu to tree: %m", new->root_id);
exit(1);
}
return 0;
@@ -666,8 +628,15 @@ static int add_root(struct rb_root *root_lookup,
static int add_root_backref(struct rb_root *root_lookup, u64 root_id,
u64 ref_tree, u64 dir_id, char *name, int name_len)
{
- return add_root(root_lookup, root_id, ref_tree, 0, 0, dir_id, name,
- name_len, 0, 0, 0, NULL, NULL, NULL);
+ struct root_attr tmp = { 0 };
+
+ tmp.root_id = root_id;
+ tmp.ref_tree = ref_tree;
+ tmp.dir_id = dir_id;
+ tmp.name = name;
+ tmp.name_len = name_len;
+
+ return add_root(root_lookup, &tmp);
}
static void free_root_info(struct rb_node *node)
@@ -832,9 +801,6 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
int name_len;
char *name;
u64 dir_id;
- u64 gen = 0;
- u64 ogen;
- u64 flags;
int i;
root_lookup->rb_node = NULL;
@@ -878,39 +844,29 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
} else if (sh.type == BTRFS_ROOT_ITEM_KEY &&
(sh.objectid >= BTRFS_FIRST_FREE_OBJECTID ||
sh.objectid == BTRFS_FS_TREE_OBJECTID)) {
- time_t otime;
- u8 uuid[BTRFS_UUID_SIZE];
- u8 puuid[BTRFS_UUID_SIZE];
- u8 ruuid[BTRFS_UUID_SIZE];
+ struct root_attr tmp = { 0 };
ri = (struct btrfs_root_item *)(args.buf + off);
- gen = btrfs_root_generation(ri);
- flags = btrfs_root_flags(ri);
+ tmp.root_id = sh.objectid;
+ tmp.root_offset = sh.offset;
+ tmp.gen = btrfs_root_generation(ri);
+ tmp.flags = btrfs_root_flags(ri);
if(sh.len >= sizeof(struct btrfs_root_item)) {
/*
* The new full btrfs_root_item with
* timestamp and UUID.
+ *
+ * For older v0 root item, those info is
+ * not in root_item, and would remain 0.
*/
- otime = btrfs_stack_timespec_sec(&ri->otime);
- 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 {
- /*
- * The old v0 root item, which doesn't
- * have timestamp nor UUID.
- */
- otime = 0;
- ogen = 0;
- memset(uuid, 0, BTRFS_UUID_SIZE);
- memset(puuid, 0, BTRFS_UUID_SIZE);
- memset(ruuid, 0, BTRFS_UUID_SIZE);
+ tmp.otime = btrfs_stack_timespec_sec(&ri->otime);
+ tmp.ogen = btrfs_root_otransid(ri);
+ memcpy(tmp.uuid, ri->uuid, BTRFS_UUID_SIZE);
+ memcpy(tmp.puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
+ memcpy(tmp.ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
}
- add_root(root_lookup, sh.objectid, 0,
- sh.offset, flags, 0, NULL, 0, ogen,
- gen, otime, uuid, puuid, ruuid);
+ add_root(root_lookup, &tmp);
}
off += sh.len;
Currently for the following functions, we have at least 14 parameters, just to describle various attributes: - update_root() - add_root() - add_root_backref() With the recent introduce of root_attr structure, we can easily replace those parameters with a root_attr structure pointer. Furthermore, since add_root() and update_root() are both updating the same structure, we can also extract a update_root_attr() helper, to remove the duplicated code. Signed-off-by: Qu Wenruo <wqu@suse.com> --- cmds/subvolume-list.c | 188 ++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 116 deletions(-)