X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=btrfs-list.c;h=e01c58991dad9e16f46ec00fcc2546b73642a612;hb=6cedd688115d85e6f14a43f7653378749ef31624;hp=fc4215f062652ae8c291f61ef75906019b0a6cee;hpb=f4ea2ec9819f63b19e3cbf13ed77769de1d4718f;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/btrfs-list.c b/btrfs-list.c index fc4215f..e01c589 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -277,7 +277,7 @@ static int sort_comp(struct root_info *entry1, struct root_info *entry2, int i, ret = 0; if (!set || !set->ncomps) - goto comp_rootid; + return comp_entry_with_rootid(entry1, entry2, 0); for (i = 0; i < set->ncomps; i++) { if (!set->comps[i].comp_func) @@ -292,10 +292,8 @@ static int sort_comp(struct root_info *entry1, struct root_info *entry2, rootid_compared = 1; } - if (!rootid_compared) { -comp_rootid: + if (!rootid_compared) ret = comp_entry_with_rootid(entry1, entry2, 0); - } return ret; } @@ -506,9 +504,9 @@ static int add_root(struct root_lookup *root_lookup, memcpy(&ri->ruuid, ruuid, BTRFS_UUID_SIZE); ret = root_tree_insert(root_lookup, ri); - if (ret) { - error("failed to insert tree %llu", - (unsigned long long)root_id); + if (ret < 0) { + error("failed to insert subvolume %llu to tree: %s", + (unsigned long long)root_id, strerror(-ret)); exit(1); } return 0; @@ -646,8 +644,8 @@ static int lookup_ino_path(int fd, struct root_info *ri) ri->ref_tree = 0; return -ENOENT; } - error("failed to lookup path for root %llu: %s", - (unsigned long long)ri->ref_tree, strerror(errno)); + error("failed to lookup path for root %llu: %m", + (unsigned long long)ri->ref_tree); return ret; } @@ -697,9 +695,8 @@ static u64 find_root_gen(int fd) /* this ioctl fills in ino_args->treeid */ ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &ino_args); if (ret < 0) { - error("failed to lookup path for dirid %llu: %s", - (unsigned long long)BTRFS_FIRST_FREE_OBJECTID, - strerror(errno)); + error("failed to lookup path for dirid %llu: %m", + (unsigned long long)BTRFS_FIRST_FREE_OBJECTID); return 0; } @@ -723,7 +720,7 @@ static u64 find_root_gen(int fd) while (1) { ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); if (ret < 0) { - error("can't perform the search: %s", strerror(errno)); + error("can't perform the search: %m"); return 0; } /* the ioctl returns the number of item it found in nr_items */ @@ -783,8 +780,8 @@ static char *__ino_resolve(int fd, u64 dirid) ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args); if (ret < 0) { - error("failed to lookup path for dirid %llu: %s", - (unsigned long long)dirid, strerror(errno)); + error("failed to lookup path for dirid %llu: %m", + (unsigned long long)dirid); return ERR_PTR(ret); } @@ -862,7 +859,7 @@ static char *ino_resolve(int fd, u64 ino, u64 *cache_dirid, char **cache_name) ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); if (ret < 0) { - error("can't perform the search: %s", strerror(errno)); + error("can't perform the search: %m"); return NULL; } /* the ioctl returns the number of item it found in nr_items */ @@ -985,7 +982,7 @@ static int list_subvol_search(int fd, struct root_lookup *root_lookup) /* Search both live and deleted subvolumes */ sk->min_type = BTRFS_ROOT_ITEM_KEY; sk->max_type = BTRFS_ROOT_BACKREF_KEY; - sk->min_objectid = BTRFS_FIRST_FREE_OBJECTID; + sk->min_objectid = BTRFS_FS_TREE_OBJECTID; sk->max_objectid = BTRFS_LAST_FREE_OBJECTID; sk->max_offset = (u64)-1; sk->max_transid = (u64)-1; @@ -1016,7 +1013,9 @@ static int list_subvol_search(int fd, struct root_lookup *root_lookup) add_root_backref(root_lookup, sh.objectid, sh.offset, dir_id, name, name_len); - } else if (sh.type == BTRFS_ROOT_ITEM_KEY) { + } 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]; @@ -1273,8 +1272,18 @@ static void filter_and_sort_subvol(struct root_lookup *all_subvols, ret = resolve_root(all_subvols, entry, top_id); if (ret == -ENOENT) { - entry->full_path = strdup("DELETED"); - entry->deleted = 1; + if (entry->root_id != BTRFS_FS_TREE_OBJECTID) { + entry->full_path = strdup("DELETED"); + entry->deleted = 1; + } else { + /* + * The full path is not supposed to be printed, + * but we don't want to print an empty string, + * in case it appears somewhere. + */ + entry->full_path = strdup("TOPLEVEL"); + entry->deleted = 0; + } } ret = filter_root(entry, filter_set); if (ret) @@ -1340,21 +1349,21 @@ static void print_subvolume_column(struct root_info *subv, strcpy(uuidparse, "-"); else uuid_unparse(subv->uuid, uuidparse); - printf("%s", uuidparse); + printf("%-36s", uuidparse); break; case BTRFS_LIST_PUUID: if (uuid_is_null(subv->puuid)) strcpy(uuidparse, "-"); else uuid_unparse(subv->puuid, uuidparse); - printf("%s", uuidparse); + printf("%-36s", uuidparse); break; case BTRFS_LIST_RUUID: if (uuid_is_null(subv->ruuid)) strcpy(uuidparse, "-"); else uuid_unparse(subv->ruuid, uuidparse); - printf("%s", uuidparse); + printf("%-36s", uuidparse); break; case BTRFS_LIST_PATH: BUG_ON(!subv->full_path); @@ -1459,6 +1468,11 @@ static void print_all_subvol_info(struct root_lookup *sorted_tree, n = rb_first(&sorted_tree->root); while (n) { entry = rb_entry(n, struct root_info, sort_node); + + /* The toplevel subvolume is not listed by default */ + if (entry->root_id == BTRFS_FS_TREE_OBJECTID) + goto next; + switch (layout) { case BTRFS_LIST_LAYOUT_DEFAULT: print_one_subvol_info_default(entry); @@ -1470,6 +1484,7 @@ static void print_all_subvol_info(struct root_lookup *sorted_tree, print_one_subvol_info_raw(entry, raw_prefix); break; } +next: n = rb_next(n); } } @@ -1480,7 +1495,7 @@ static int btrfs_list_subvols(int fd, struct root_lookup *root_lookup) ret = list_subvol_search(fd, root_lookup); if (ret) { - error("can't perform the search: %s", strerror(errno)); + error("can't perform the search: %m"); return ret; } @@ -1526,6 +1541,37 @@ static char *strdup_or_null(const char *s) return strdup(s); } +int btrfs_get_toplevel_subvol(int fd, struct root_info *the_ri) +{ + int ret; + struct root_lookup rl; + struct rb_node *rbn; + struct root_info *ri; + u64 root_id; + + ret = btrfs_list_get_path_rootid(fd, &root_id); + if (ret) + return ret; + + ret = btrfs_list_subvols(fd, &rl); + if (ret) + return ret; + + rbn = rb_first(&rl.root); + ri = rb_entry(rbn, struct root_info, rb_node); + + if (ri->root_id != BTRFS_FS_TREE_OBJECTID) + return -ENOENT; + + memcpy(the_ri, ri, offsetof(struct root_info, path)); + the_ri->path = strdup_or_null("/"); + the_ri->name = strdup_or_null(""); + the_ri->full_path = strdup_or_null("/"); + rb_free_nodes(&rl.root, free_root_info); + + return ret; +} + int btrfs_get_subvol(int fd, struct root_info *the_ri) { int ret, rr; @@ -1551,7 +1597,9 @@ int btrfs_get_subvol(int fd, struct root_info *the_ri) rbn = rb_next(rbn); continue; } - if (!comp_entry_with_rootid(the_ri, ri, 0)) { + + if (!comp_entry_with_rootid(the_ri, ri, 0) || + !uuid_compare(the_ri->uuid, ri->uuid)) { memcpy(the_ri, ri, offsetof(struct root_info, path)); the_ri->path = strdup_or_null(ri->path); the_ri->name = strdup_or_null(ri->name); @@ -1683,7 +1731,7 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen) while(1) { ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); if (ret < 0) { - error("can't perform the search: %s", strerror(errno)); + error("can't perform the search: %m"); break; } /* the ioctl returns the number of item it found in nr_items */ @@ -1877,8 +1925,7 @@ int btrfs_list_get_path_rootid(int fd, u64 *treeid) ret = lookup_path_rootid(fd, treeid); if (ret < 0) - error("cannot resolve rootid for path: %s", - strerror(errno)); + error("cannot resolve rootid for path: %m"); return ret; }