mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-23 06:32:57 +00:00
Btrfs-Progs: fix subvolumes's some full_path invaild problems.
In the privous way, we list all the subvolumes in the filesystem default. But if a subvolume mounts on another directory, some result's full_path may be invaild. According to this, we try to list subvolumes under directoy only by default. In this way, all the subvolume can be arrived by the full_path. Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This commit is contained in:
parent
0f53cf81f6
commit
a1e89891eb
42
btrfs-list.c
42
btrfs-list.c
@ -584,7 +584,8 @@ void __free_all_subvolumn(struct root_lookup *root_tree)
|
|||||||
* This can't be called until all the root_info->path fields are filled
|
* This can't be called until all the root_info->path fields are filled
|
||||||
* in by lookup_ino_path
|
* in by lookup_ino_path
|
||||||
*/
|
*/
|
||||||
static int resolve_root(struct root_lookup *rl, struct root_info *ri)
|
static int resolve_root(struct root_lookup *rl, struct root_info *ri,
|
||||||
|
u64 top_id)
|
||||||
{
|
{
|
||||||
char *full_path = NULL;
|
char *full_path = NULL;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@ -621,6 +622,11 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri)
|
|||||||
|
|
||||||
next = found->ref_tree;
|
next = found->ref_tree;
|
||||||
|
|
||||||
|
if (next == top_id) {
|
||||||
|
ri->top_id = top_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the ref_tree refers to ourselves, we're at the top */
|
/* if the ref_tree refers to ourselves, we're at the top */
|
||||||
if (next == found->root_id) {
|
if (next == found->root_id) {
|
||||||
ri->top_id = next;
|
ri->top_id = next;
|
||||||
@ -1157,6 +1163,11 @@ static int filter_cgen_equal(struct root_info *ri, u64 data)
|
|||||||
return ri->ogen == data;
|
return ri->ogen == data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int filter_topid_equal(struct root_info *ri, u64 data)
|
||||||
|
{
|
||||||
|
return ri->top_id == data;
|
||||||
|
}
|
||||||
|
|
||||||
static btrfs_list_filter_func all_filter_funcs[] = {
|
static btrfs_list_filter_func all_filter_funcs[] = {
|
||||||
[BTRFS_LIST_FILTER_ROOTID] = filter_by_rootid,
|
[BTRFS_LIST_FILTER_ROOTID] = filter_by_rootid,
|
||||||
[BTRFS_LIST_FILTER_SNAPSHOT_ONLY] = filter_snapshot,
|
[BTRFS_LIST_FILTER_SNAPSHOT_ONLY] = filter_snapshot,
|
||||||
@ -1167,6 +1178,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
|
|||||||
[BTRFS_LIST_FILTER_CGEN_MORE] = filter_cgen_more,
|
[BTRFS_LIST_FILTER_CGEN_MORE] = filter_cgen_more,
|
||||||
[BTRFS_LIST_FILTER_CGEN_LESS] = filter_cgen_less,
|
[BTRFS_LIST_FILTER_CGEN_LESS] = filter_cgen_less,
|
||||||
[BTRFS_LIST_FILTER_CGEN_EQUAL] = filter_cgen_equal,
|
[BTRFS_LIST_FILTER_CGEN_EQUAL] = filter_cgen_equal,
|
||||||
|
[BTRFS_LIST_FILTER_TOPID_EQUAL] = filter_topid_equal,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
|
struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
|
||||||
@ -1248,11 +1260,13 @@ static int filter_root(struct root_info *ri,
|
|||||||
static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
|
static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
|
||||||
struct root_lookup *sort_tree,
|
struct root_lookup *sort_tree,
|
||||||
struct btrfs_list_filter_set *filter_set,
|
struct btrfs_list_filter_set *filter_set,
|
||||||
struct btrfs_list_comparer_set *comp_set)
|
struct btrfs_list_comparer_set *comp_set,
|
||||||
|
int fd)
|
||||||
{
|
{
|
||||||
struct rb_node *n;
|
struct rb_node *n;
|
||||||
struct root_info *entry;
|
struct root_info *entry;
|
||||||
int ret;
|
int ret;
|
||||||
|
u64 top_id = btrfs_list_get_path_rootid(fd);
|
||||||
|
|
||||||
root_lookup_init(sort_tree);
|
root_lookup_init(sort_tree);
|
||||||
|
|
||||||
@ -1260,7 +1274,7 @@ static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
|
|||||||
while (n) {
|
while (n) {
|
||||||
entry = rb_entry(n, struct root_info, rb_node);
|
entry = rb_entry(n, struct root_info, rb_node);
|
||||||
|
|
||||||
resolve_root(all_subvols, entry);
|
resolve_root(all_subvols, entry, top_id);
|
||||||
ret = filter_root(entry, filter_set);
|
ret = filter_root(entry, filter_set);
|
||||||
if (ret)
|
if (ret)
|
||||||
sort_tree_insert(sort_tree, entry, comp_set);
|
sort_tree_insert(sort_tree, entry, comp_set);
|
||||||
@ -1443,7 +1457,7 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
|
__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
|
||||||
comp_set);
|
comp_set, fd);
|
||||||
|
|
||||||
print_all_volume_info(&root_sort, is_tab_result);
|
print_all_volume_info(&root_sort, is_tab_result);
|
||||||
__free_all_subvolumn(&root_lookup);
|
__free_all_subvolumn(&root_lookup);
|
||||||
@ -1636,6 +1650,7 @@ char *btrfs_list_path_for_root(int fd, u64 root)
|
|||||||
struct rb_node *n;
|
struct rb_node *n;
|
||||||
char *ret_path = NULL;
|
char *ret_path = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
u64 top_id = btrfs_list_get_path_rootid(fd);
|
||||||
|
|
||||||
ret = __list_subvol_search(fd, &root_lookup);
|
ret = __list_subvol_search(fd, &root_lookup);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1650,7 +1665,7 @@ char *btrfs_list_path_for_root(int fd, u64 root)
|
|||||||
struct root_info *entry;
|
struct root_info *entry;
|
||||||
|
|
||||||
entry = rb_entry(n, struct root_info, rb_node);
|
entry = rb_entry(n, struct root_info, rb_node);
|
||||||
resolve_root(&root_lookup, entry);
|
resolve_root(&root_lookup, entry, top_id);
|
||||||
if (entry->root_id == root) {
|
if (entry->root_id == root) {
|
||||||
ret_path = entry->full_path;
|
ret_path = entry->full_path;
|
||||||
entry->full_path = NULL;
|
entry->full_path = NULL;
|
||||||
@ -1758,3 +1773,20 @@ int btrfs_list_parse_filter_string(char *optarg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 btrfs_list_get_path_rootid(int fd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct btrfs_ioctl_ino_lookup_args args;
|
||||||
|
|
||||||
|
memset(&args, 0, sizeof(args));
|
||||||
|
args.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
||||||
|
|
||||||
|
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: can't perform the search -%s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return args.treeid;
|
||||||
|
}
|
||||||
|
@ -70,6 +70,7 @@ enum btrfs_list_filter_enum {
|
|||||||
BTRFS_LIST_FILTER_CGEN_EQUAL = BTRFS_LIST_FILTER_CGEN,
|
BTRFS_LIST_FILTER_CGEN_EQUAL = BTRFS_LIST_FILTER_CGEN,
|
||||||
BTRFS_LIST_FILTER_CGEN_LESS,
|
BTRFS_LIST_FILTER_CGEN_LESS,
|
||||||
BTRFS_LIST_FILTER_CGEN_MORE,
|
BTRFS_LIST_FILTER_CGEN_MORE,
|
||||||
|
BTRFS_LIST_FILTER_TOPID_EQUAL,
|
||||||
BTRFS_LIST_FILTER_MAX,
|
BTRFS_LIST_FILTER_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,3 +104,4 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
|
|||||||
int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
|
int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
|
||||||
int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
|
int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
|
||||||
char *btrfs_list_path_for_root(int fd, u64 root);
|
char *btrfs_list_path_for_root(int fd, u64 root);
|
||||||
|
u64 btrfs_list_get_path_rootid(int fd);
|
||||||
|
@ -289,6 +289,7 @@ static int cmd_subvol_list(int argc, char **argv)
|
|||||||
struct btrfs_list_comparer_set *comparer_set;
|
struct btrfs_list_comparer_set *comparer_set;
|
||||||
u64 flags = 0;
|
u64 flags = 0;
|
||||||
int fd;
|
int fd;
|
||||||
|
u64 top_id;
|
||||||
int ret;
|
int ret;
|
||||||
int order;
|
int order;
|
||||||
int c;
|
int c;
|
||||||
@ -387,6 +388,11 @@ static int cmd_subvol_list(int argc, char **argv)
|
|||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
top_id = btrfs_list_get_path_rootid(fd);
|
||||||
|
btrfs_list_setup_filter(&filter_set,
|
||||||
|
BTRFS_LIST_FILTER_TOPID_EQUAL,
|
||||||
|
top_id);
|
||||||
|
|
||||||
ret = btrfs_list_subvols(fd, filter_set, comparer_set,
|
ret = btrfs_list_subvols(fd, filter_set, comparer_set,
|
||||||
is_tab_result);
|
is_tab_result);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
Loading…
Reference in New Issue
Block a user