2010-02-28 20:29:47 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2010 Oracle. All rights reserved.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public
|
|
|
|
* License v2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public
|
|
|
|
* License along with this program; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 021110-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <libgen.h>
|
|
|
|
#include "ctree.h"
|
|
|
|
#include "transaction.h"
|
|
|
|
#include "utils.h"
|
2015-06-10 00:21:42 +00:00
|
|
|
#include "ioctl.h"
|
2012-08-14 06:04:06 +00:00
|
|
|
#include <uuid/uuid.h>
|
2012-08-08 08:54:48 +00:00
|
|
|
#include "btrfs-list.h"
|
2014-10-10 20:57:08 +00:00
|
|
|
#include "rbtree-utils.h"
|
2010-02-28 20:29:47 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
#define BTRFS_LIST_NFILTERS_INCREASE (2 * BTRFS_LIST_FILTER_MAX)
|
|
|
|
#define BTRFS_LIST_NCOMPS_INCREASE (2 * BTRFS_LIST_COMP_MAX)
|
|
|
|
|
2010-02-28 20:29:47 +00:00
|
|
|
/* we store all the roots we find in an rbtree so that we can
|
|
|
|
* search for them later.
|
|
|
|
*/
|
|
|
|
struct root_lookup {
|
|
|
|
struct rb_root root;
|
|
|
|
};
|
|
|
|
|
2013-08-09 20:20:47 +00:00
|
|
|
static struct {
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
char *name;
|
|
|
|
char *column_name;
|
|
|
|
int need_print;
|
|
|
|
} btrfs_list_columns[] = {
|
|
|
|
{
|
|
|
|
.name = "ID",
|
|
|
|
.column_name = "ID",
|
2013-02-01 07:56:26 +00:00
|
|
|
.need_print = 0,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "gen",
|
|
|
|
.column_name = "Gen",
|
2013-02-01 07:56:26 +00:00
|
|
|
.need_print = 0,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cgen",
|
|
|
|
.column_name = "CGen",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "parent",
|
|
|
|
.column_name = "Parent",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "top level",
|
|
|
|
.column_name = "Top Level",
|
2013-02-01 07:56:26 +00:00
|
|
|
.need_print = 0,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "otime",
|
|
|
|
.column_name = "OTime",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
2013-02-01 07:56:21 +00:00
|
|
|
{
|
|
|
|
.name = "parent_uuid",
|
|
|
|
.column_name = "Parent UUID",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
2014-08-13 21:18:17 +00:00
|
|
|
{
|
|
|
|
.name = "received_uuid",
|
|
|
|
.column_name = "Received UUID",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
.name = "uuid",
|
|
|
|
.column_name = "UUID",
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "path",
|
|
|
|
.column_name = "Path",
|
2013-02-01 07:56:26 +00:00
|
|
|
.need_print = 0,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = NULL,
|
|
|
|
.column_name = NULL,
|
|
|
|
.need_print = 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static btrfs_list_filter_func all_filter_funcs[];
|
|
|
|
static btrfs_list_comp_func all_comp_funcs[];
|
|
|
|
|
|
|
|
void btrfs_list_setup_print_column(enum btrfs_list_column_enum column)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(0 <= column && column <= BTRFS_LIST_ALL);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
if (column < BTRFS_LIST_ALL) {
|
|
|
|
btrfs_list_columns[column].need_print = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++)
|
|
|
|
btrfs_list_columns[i].need_print = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int comp_entry_with_rootid(struct root_info *entry1,
|
|
|
|
struct root_info *entry2,
|
|
|
|
int is_descending)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (entry1->root_id > entry2->root_id)
|
|
|
|
ret = 1;
|
|
|
|
else if (entry1->root_id < entry2->root_id)
|
|
|
|
ret = -1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
return is_descending ? -ret : ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int comp_entry_with_gen(struct root_info *entry1,
|
|
|
|
struct root_info *entry2,
|
|
|
|
int is_descending)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (entry1->gen > entry2->gen)
|
|
|
|
ret = 1;
|
|
|
|
else if (entry1->gen < entry2->gen)
|
|
|
|
ret = -1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
return is_descending ? -ret : ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int comp_entry_with_ogen(struct root_info *entry1,
|
|
|
|
struct root_info *entry2,
|
|
|
|
int is_descending)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (entry1->ogen > entry2->ogen)
|
|
|
|
ret = 1;
|
|
|
|
else if (entry1->ogen < entry2->ogen)
|
|
|
|
ret = -1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
return is_descending ? -ret : ret;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
static int comp_entry_with_path(struct root_info *entry1,
|
|
|
|
struct root_info *entry2,
|
|
|
|
int is_descending)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (strcmp(entry1->full_path, entry2->full_path) > 0)
|
|
|
|
ret = 1;
|
|
|
|
else if (strcmp(entry1->full_path, entry2->full_path) < 0)
|
|
|
|
ret = -1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
return is_descending ? -ret : ret;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static btrfs_list_comp_func all_comp_funcs[] = {
|
|
|
|
[BTRFS_LIST_COMP_ROOTID] = comp_entry_with_rootid,
|
|
|
|
[BTRFS_LIST_COMP_OGEN] = comp_entry_with_ogen,
|
|
|
|
[BTRFS_LIST_COMP_GEN] = comp_entry_with_gen,
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
[BTRFS_LIST_COMP_PATH] = comp_entry_with_path,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
};
|
|
|
|
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
static char *all_sort_items[] = {
|
|
|
|
[BTRFS_LIST_COMP_ROOTID] = "rootid",
|
|
|
|
[BTRFS_LIST_COMP_OGEN] = "ogen",
|
|
|
|
[BTRFS_LIST_COMP_GEN] = "gen",
|
|
|
|
[BTRFS_LIST_COMP_PATH] = "path",
|
|
|
|
[BTRFS_LIST_COMP_MAX] = NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int btrfs_list_get_sort_item(char *sort_name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_COMP_MAX; i++) {
|
|
|
|
if (strcmp(sort_name, all_sort_items[i]) == 0)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct btrfs_list_comparer_set *btrfs_list_alloc_comparer_set(void)
|
|
|
|
{
|
|
|
|
struct btrfs_list_comparer_set *set;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
size = sizeof(struct btrfs_list_comparer_set) +
|
|
|
|
BTRFS_LIST_NCOMPS_INCREASE * sizeof(struct btrfs_list_comparer);
|
2015-09-29 17:10:36 +00:00
|
|
|
set = calloc(1, size);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (!set) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
set->total = BTRFS_LIST_NCOMPS_INCREASE;
|
|
|
|
|
|
|
|
return set;
|
|
|
|
}
|
|
|
|
|
2013-08-09 20:20:47 +00:00
|
|
|
static int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
|
|
|
|
enum btrfs_list_comp_enum comparer, int is_descending)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
struct btrfs_list_comparer_set *set = *comp_set;
|
|
|
|
int size;
|
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(set != NULL);
|
|
|
|
ASSERT(comparer < BTRFS_LIST_COMP_MAX);
|
|
|
|
ASSERT(set->ncomps <= set->total);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
if (set->ncomps == set->total) {
|
2015-08-21 08:51:52 +00:00
|
|
|
void *tmp;
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
size = set->total + BTRFS_LIST_NCOMPS_INCREASE;
|
|
|
|
size = sizeof(*set) + size * sizeof(struct btrfs_list_comparer);
|
2015-08-21 08:51:52 +00:00
|
|
|
tmp = set;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
set = realloc(set, size);
|
|
|
|
if (!set) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
2015-08-21 08:51:52 +00:00
|
|
|
free(tmp);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&set->comps[set->total], 0,
|
|
|
|
BTRFS_LIST_NCOMPS_INCREASE *
|
|
|
|
sizeof(struct btrfs_list_comparer));
|
|
|
|
set->total += BTRFS_LIST_NCOMPS_INCREASE;
|
|
|
|
*comp_set = set;
|
|
|
|
}
|
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(set->comps[set->ncomps].comp_func == NULL);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
set->comps[set->ncomps].comp_func = all_comp_funcs[comparer];
|
|
|
|
set->comps[set->ncomps].is_descending = is_descending;
|
|
|
|
set->ncomps++;
|
2010-02-28 20:29:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static int sort_comp(struct root_info *entry1, struct root_info *entry2,
|
|
|
|
struct btrfs_list_comparer_set *set)
|
2012-08-03 09:48:56 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int rootid_compared = 0;
|
|
|
|
int i, ret = 0;
|
|
|
|
|
|
|
|
if (!set || !set->ncomps)
|
2016-10-31 11:46:52 +00:00
|
|
|
return comp_entry_with_rootid(entry1, entry2, 0);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
for (i = 0; i < set->ncomps; i++) {
|
|
|
|
if (!set->comps[i].comp_func)
|
|
|
|
break;
|
|
|
|
|
|
|
|
ret = set->comps[i].comp_func(entry1, entry2,
|
|
|
|
set->comps[i].is_descending);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (set->comps[i].comp_func == comp_entry_with_rootid)
|
|
|
|
rootid_compared = 1;
|
|
|
|
}
|
|
|
|
|
2016-10-31 11:46:52 +00:00
|
|
|
if (!rootid_compared)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = comp_entry_with_rootid(entry1, entry2, 0);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sort_tree_insert(struct root_lookup *sort_tree,
|
|
|
|
struct root_info *ins,
|
|
|
|
struct btrfs_list_comparer_set *comp_set)
|
|
|
|
{
|
|
|
|
struct rb_node **p = &sort_tree->root.rb_node;
|
|
|
|
struct rb_node *parent = NULL;
|
|
|
|
struct root_info *curr;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
while (*p) {
|
|
|
|
parent = *p;
|
|
|
|
curr = rb_entry(parent, struct root_info, sort_node);
|
|
|
|
|
|
|
|
ret = sort_comp(ins, curr, comp_set);
|
|
|
|
if (ret < 0)
|
|
|
|
p = &(*p)->rb_left;
|
|
|
|
else if (ret > 0)
|
|
|
|
p = &(*p)->rb_right;
|
|
|
|
else
|
|
|
|
return -EEXIST;
|
|
|
|
}
|
|
|
|
|
|
|
|
rb_link_node(&ins->sort_node, parent, p);
|
|
|
|
rb_insert_color(&ins->sort_node, &sort_tree->root);
|
|
|
|
return 0;
|
2012-08-03 09:48:56 +00:00
|
|
|
}
|
|
|
|
|
2010-02-28 20:29:47 +00:00
|
|
|
/*
|
|
|
|
* insert a new root into the tree. returns the existing root entry
|
|
|
|
* if one is already there. Both root_id and ref_tree are used
|
|
|
|
* as the key
|
|
|
|
*/
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static int root_tree_insert(struct root_lookup *root_tree,
|
|
|
|
struct root_info *ins)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct rb_node **p = &root_tree->root.rb_node;
|
2010-02-28 20:29:47 +00:00
|
|
|
struct rb_node * parent = NULL;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct root_info *curr;
|
|
|
|
int ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
|
|
|
while(*p) {
|
|
|
|
parent = *p;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
curr = rb_entry(parent, struct root_info, rb_node);
|
2010-02-28 20:29:47 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = comp_entry_with_rootid(ins, curr, 0);
|
|
|
|
if (ret < 0)
|
2010-02-28 20:29:47 +00:00
|
|
|
p = &(*p)->rb_left;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
else if (ret > 0)
|
2010-02-28 20:29:47 +00:00
|
|
|
p = &(*p)->rb_right;
|
|
|
|
else
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
return -EEXIST;
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
rb_link_node(&ins->rb_node, parent, p);
|
|
|
|
rb_insert_color(&ins->rb_node, &root_tree->root);
|
|
|
|
return 0;
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* find a given root id in the tree. We return the smallest one,
|
|
|
|
* rb_next can be used to move forward looking for more if required
|
|
|
|
*/
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static struct root_info *root_tree_search(struct root_lookup *root_tree,
|
|
|
|
u64 root_id)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct rb_node *n = root_tree->root.rb_node;
|
2010-02-28 20:29:47 +00:00
|
|
|
struct root_info *entry;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct root_info tmp;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
tmp.root_id = root_id;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
|
|
|
while(n) {
|
|
|
|
entry = rb_entry(n, struct root_info, rb_node);
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = comp_entry_with_rootid(&tmp, entry, 0);
|
|
|
|
if (ret < 0)
|
2010-02-28 20:29:47 +00:00
|
|
|
n = n->rb_left;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
else if (ret > 0)
|
2010-02-28 20:29:47 +00:00
|
|
|
n = n->rb_right;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
else
|
2010-02-28 20:29:47 +00:00
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static int update_root(struct root_lookup *root_lookup,
|
2012-09-18 09:14:37 +00:00
|
|
|
u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
|
|
|
|
u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
|
2016-10-31 11:33:28 +00:00
|
|
|
time_t otime, u8 *uuid, u8 *puuid, u8 *ruuid)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
struct root_info *ri;
|
|
|
|
|
|
|
|
ri = root_tree_search(root_lookup, root_id);
|
|
|
|
if (!ri || ri->root_id != root_id)
|
|
|
|
return -ENOENT;
|
|
|
|
if (name && name_len > 0) {
|
2013-12-12 10:41:07 +00:00
|
|
|
free(ri->name);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
ri->name = malloc(name_len + 1);
|
|
|
|
if (!ri->name) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
strncpy(ri->name, name, name_len);
|
|
|
|
ri->name[name_len] = 0;
|
|
|
|
}
|
|
|
|
if (ref_tree)
|
|
|
|
ri->ref_tree = ref_tree;
|
|
|
|
if (root_offset)
|
|
|
|
ri->root_offset = root_offset;
|
2012-09-18 09:14:37 +00:00
|
|
|
if (flags)
|
|
|
|
ri->flags = flags;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (dir_id)
|
|
|
|
ri->dir_id = dir_id;
|
|
|
|
if (gen)
|
|
|
|
ri->gen = gen;
|
|
|
|
if (ogen)
|
|
|
|
ri->ogen = ogen;
|
|
|
|
if (!ri->ogen && root_offset)
|
|
|
|
ri->ogen = root_offset;
|
2016-10-31 11:19:50 +00:00
|
|
|
if (otime)
|
|
|
|
ri->otime = otime;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (uuid)
|
|
|
|
memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
|
2013-02-01 07:56:21 +00:00
|
|
|
if (puuid)
|
|
|
|
memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
|
2014-08-13 21:18:17 +00:00
|
|
|
if (ruuid)
|
|
|
|
memcpy(&ri->ruuid, ruuid, BTRFS_UUID_SIZE);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-02-28 20:29:47 +00:00
|
|
|
/*
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
* add_root - update the existed root, or allocate a new root and insert it
|
|
|
|
* into the lookup tree.
|
|
|
|
* root_id: object id of the root
|
|
|
|
* ref_tree: object id of the referring root.
|
|
|
|
* root_offset: offset value of the root'key
|
|
|
|
* dir_id: inode id of the directory in ref_tree where this root can be found.
|
|
|
|
* name: the name of root_id in that directory
|
|
|
|
* name_len: the length of name
|
|
|
|
* ogen: the original generation of the root
|
|
|
|
* gen: the current generation of the root
|
2016-10-31 11:19:50 +00:00
|
|
|
* otime: the original time (creation time) of the root
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
* uuid: uuid of the root
|
2013-02-01 07:56:21 +00:00
|
|
|
* puuid: uuid of the root parent if any
|
2014-08-13 21:18:17 +00:00
|
|
|
* ruuid: uuid of the received subvol, if any
|
2010-02-28 20:29:47 +00:00
|
|
|
*/
|
|
|
|
static int add_root(struct root_lookup *root_lookup,
|
2012-09-18 09:14:37 +00:00
|
|
|
u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
|
|
|
|
u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
|
2016-10-31 11:33:28 +00:00
|
|
|
time_t otime, u8 *uuid, u8 *puuid, u8 *ruuid)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
|
|
|
struct root_info *ri;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int ret;
|
|
|
|
|
2012-09-18 09:14:37 +00:00
|
|
|
ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
|
2016-10-31 11:19:50 +00:00
|
|
|
dir_id, name, name_len, ogen, gen, otime,
|
2014-08-13 21:18:17 +00:00
|
|
|
uuid, puuid, ruuid);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (!ret)
|
|
|
|
return 0;
|
|
|
|
|
2015-09-29 17:10:36 +00:00
|
|
|
ri = calloc(1, sizeof(*ri));
|
2010-02-28 20:29:47 +00:00
|
|
|
if (!ri) {
|
|
|
|
printf("memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ri->root_id = root_id;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
if (name && name_len > 0) {
|
|
|
|
ri->name = malloc(name_len + 1);
|
|
|
|
if (!ri->name) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-08-03 09:48:56 +00:00
|
|
|
strncpy(ri->name, name, name_len);
|
2012-07-05 18:58:51 +00:00
|
|
|
ri->name[name_len] = 0;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
}
|
|
|
|
if (ref_tree)
|
|
|
|
ri->ref_tree = ref_tree;
|
|
|
|
if (dir_id)
|
|
|
|
ri->dir_id = dir_id;
|
|
|
|
if (root_offset)
|
|
|
|
ri->root_offset = root_offset;
|
2012-09-18 09:14:37 +00:00
|
|
|
if (flags)
|
|
|
|
ri->flags = flags;
|
2012-08-03 09:48:56 +00:00
|
|
|
if (gen)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ri->gen = gen;
|
|
|
|
if (ogen)
|
|
|
|
ri->ogen = ogen;
|
|
|
|
if (!ri->ogen && root_offset)
|
|
|
|
ri->ogen = root_offset;
|
2016-10-31 11:19:50 +00:00
|
|
|
if (otime)
|
|
|
|
ri->otime = otime;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
2013-02-01 07:56:21 +00:00
|
|
|
if (uuid)
|
2012-08-14 06:04:06 +00:00
|
|
|
memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
|
|
|
|
|
2013-02-01 07:56:21 +00:00
|
|
|
if (puuid)
|
|
|
|
memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
|
|
|
|
|
2014-08-13 21:18:17 +00:00
|
|
|
if (ruuid)
|
|
|
|
memcpy(&ri->ruuid, ruuid, BTRFS_UUID_SIZE);
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = root_tree_insert(root_lookup, ri);
|
2016-10-31 11:53:35 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
error("failed to insert subvolume %llu to tree: %s",
|
|
|
|
(unsigned long long)root_id, strerror(-ret));
|
2010-02-28 20:29:47 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-31 11:27:08 +00:00
|
|
|
/*
|
|
|
|
* Simplified add_root for back references, omits the uuid and original info
|
|
|
|
* parameters, root offset and flags.
|
|
|
|
*/
|
|
|
|
static int add_root_backref(struct root_lookup *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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
static void free_root_info(struct rb_node *node)
|
2012-08-03 09:48:55 +00:00
|
|
|
{
|
2013-07-03 13:25:13 +00:00
|
|
|
struct root_info *ri;
|
|
|
|
|
|
|
|
ri = rb_entry(node, struct root_info, rb_node);
|
2013-12-12 10:41:07 +00:00
|
|
|
free(ri->name);
|
|
|
|
free(ri->path);
|
|
|
|
free(ri->full_path);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
free(ri);
|
|
|
|
}
|
|
|
|
|
2010-02-28 20:29:47 +00:00
|
|
|
/*
|
|
|
|
* for a given root_info, search through the root_lookup tree to construct
|
|
|
|
* the full path name to it.
|
|
|
|
*
|
|
|
|
* This can't be called until all the root_info->path fields are filled
|
|
|
|
* in by lookup_ino_path
|
|
|
|
*/
|
2012-09-27 17:04:20 +00:00
|
|
|
static int resolve_root(struct root_lookup *rl, struct root_info *ri,
|
|
|
|
u64 top_id)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
|
|
|
char *full_path = NULL;
|
|
|
|
int len = 0;
|
|
|
|
struct root_info *found;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* we go backwards from the root_info object and add pathnames
|
|
|
|
* from parent directories as we go.
|
|
|
|
*/
|
|
|
|
found = ri;
|
|
|
|
while (1) {
|
|
|
|
char *tmp;
|
|
|
|
u64 next;
|
2013-02-25 22:54:48 +00:00
|
|
|
int add_len;
|
|
|
|
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
/*
|
2016-05-11 23:50:36 +00:00
|
|
|
* ref_tree = 0 indicates the subvolume
|
2013-02-25 22:54:48 +00:00
|
|
|
* has been deleted.
|
|
|
|
*/
|
2013-02-25 22:54:47 +00:00
|
|
|
if (!found->ref_tree) {
|
|
|
|
free(full_path);
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
return -ENOENT;
|
2013-02-25 22:54:47 +00:00
|
|
|
}
|
2013-02-25 22:54:48 +00:00
|
|
|
|
|
|
|
add_len = strlen(found->path);
|
2010-02-28 20:29:47 +00:00
|
|
|
|
|
|
|
if (full_path) {
|
2013-04-09 17:08:32 +00:00
|
|
|
/* room for / and for null */
|
|
|
|
tmp = malloc(add_len + 2 + len);
|
|
|
|
if (!tmp) {
|
|
|
|
perror("malloc failed");
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-02-28 20:29:47 +00:00
|
|
|
memcpy(tmp + add_len + 1, full_path, len);
|
|
|
|
tmp[add_len] = '/';
|
|
|
|
memcpy(tmp, found->path, add_len);
|
|
|
|
tmp [add_len + len + 1] = '\0';
|
|
|
|
free(full_path);
|
|
|
|
full_path = tmp;
|
|
|
|
len += add_len + 1;
|
|
|
|
} else {
|
|
|
|
full_path = strdup(found->path);
|
|
|
|
len = add_len;
|
|
|
|
}
|
2014-01-09 12:42:12 +00:00
|
|
|
if (!ri->top_id)
|
|
|
|
ri->top_id = found->ref_tree;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
|
|
|
next = found->ref_tree;
|
2014-01-09 12:42:12 +00:00
|
|
|
if (next == top_id)
|
2012-09-27 17:04:20 +00:00
|
|
|
break;
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
/*
|
|
|
|
* if the ref_tree = BTRFS_FS_TREE_OBJECTID,
|
|
|
|
* we are at the top
|
|
|
|
*/
|
2014-01-09 12:42:12 +00:00
|
|
|
if (next == BTRFS_FS_TREE_OBJECTID)
|
2010-02-28 20:29:47 +00:00
|
|
|
break;
|
|
|
|
/*
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
* if the ref_tree wasn't in our tree of roots, the
|
|
|
|
* subvolume was deleted.
|
|
|
|
*/
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
found = root_tree_search(rl, next);
|
2013-02-25 22:54:47 +00:00
|
|
|
if (!found) {
|
|
|
|
free(full_path);
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
return -ENOENT;
|
2013-02-25 22:54:47 +00:00
|
|
|
}
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
2011-11-02 15:22:09 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ri->full_path = full_path;
|
2011-11-02 15:22:09 +00:00
|
|
|
|
2010-02-28 20:29:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* for a single root_info, ask the kernel to give us a path name
|
|
|
|
* inside it's ref_root for the dir_id where it lives.
|
|
|
|
*
|
|
|
|
* This fills in root_info->path with the path to the directory and and
|
|
|
|
* appends this root's name.
|
|
|
|
*/
|
|
|
|
static int lookup_ino_path(int fd, struct root_info *ri)
|
|
|
|
{
|
|
|
|
struct btrfs_ioctl_ino_lookup_args args;
|
2016-01-12 10:20:18 +00:00
|
|
|
int ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
|
|
|
if (ri->path)
|
|
|
|
return 0;
|
|
|
|
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
if (!ri->ref_tree)
|
|
|
|
return -ENOENT;
|
|
|
|
|
2010-01-24 17:00:05 +00:00
|
|
|
memset(&args, 0, sizeof(args));
|
2010-02-28 20:29:47 +00:00
|
|
|
args.treeid = ri->ref_tree;
|
|
|
|
args.objectid = ri->dir_id;
|
|
|
|
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
2016-01-12 12:35:50 +00:00
|
|
|
if (ret < 0) {
|
2016-01-12 10:20:18 +00:00
|
|
|
if (errno == ENOENT) {
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
ri->ref_tree = 0;
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
2016-10-31 10:32:12 +00:00
|
|
|
error("failed to lookup path for root %llu: %s",
|
|
|
|
(unsigned long long)ri->ref_tree, strerror(errno));
|
2010-03-11 20:51:36 +00:00
|
|
|
return ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (args.name[0]) {
|
|
|
|
/*
|
|
|
|
* we're in a subdirectory of ref_tree, the kernel ioctl
|
|
|
|
* puts a / in there for us
|
|
|
|
*/
|
|
|
|
ri->path = malloc(strlen(ri->name) + strlen(args.name) + 1);
|
|
|
|
if (!ri->path) {
|
|
|
|
perror("malloc failed");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
strcpy(ri->path, args.name);
|
|
|
|
strcat(ri->path, ri->name);
|
|
|
|
} else {
|
|
|
|
/* we're at the root of ref_tree */
|
|
|
|
ri->path = strdup(ri->name);
|
|
|
|
if (!ri->path) {
|
|
|
|
perror("strdup failed");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-03-18 16:32:32 +00:00
|
|
|
/* finding the generation for a given path is a two step process.
|
2016-05-11 23:50:36 +00:00
|
|
|
* First we use the inode lookup routine to find out the root id
|
2010-03-18 16:32:32 +00:00
|
|
|
*
|
|
|
|
* Then we use the tree search ioctl to scan all the root items for a
|
|
|
|
* given root id and spit out the latest generation we can find
|
|
|
|
*/
|
|
|
|
static u64 find_root_gen(int fd)
|
|
|
|
{
|
|
|
|
struct btrfs_ioctl_ino_lookup_args ino_args;
|
|
|
|
int ret;
|
|
|
|
struct btrfs_ioctl_search_args args;
|
|
|
|
struct btrfs_ioctl_search_key *sk = &args.key;
|
2012-10-21 14:34:33 +00:00
|
|
|
struct btrfs_ioctl_search_header sh;
|
2010-03-18 16:32:32 +00:00
|
|
|
unsigned long off = 0;
|
|
|
|
u64 max_found = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(&ino_args, 0, sizeof(ino_args));
|
|
|
|
ino_args.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
|
|
|
|
|
|
|
/* this ioctl fills in ino_args->treeid */
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &ino_args);
|
2016-01-12 12:35:50 +00:00
|
|
|
if (ret < 0) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("failed to lookup path for dirid %llu: %s",
|
2010-12-20 20:06:19 +00:00
|
|
|
(unsigned long long)BTRFS_FIRST_FREE_OBJECTID,
|
2016-01-12 10:20:18 +00:00
|
|
|
strerror(errno));
|
2010-03-18 16:32:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
2016-10-31 09:59:08 +00:00
|
|
|
sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
|
2010-03-18 16:32:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* there may be more than one ROOT_ITEM key if there are
|
|
|
|
* snapshots pending deletion, we have to loop through
|
|
|
|
* them.
|
|
|
|
*/
|
|
|
|
sk->min_objectid = ino_args.treeid;
|
|
|
|
sk->max_objectid = ino_args.treeid;
|
|
|
|
sk->max_type = BTRFS_ROOT_ITEM_KEY;
|
|
|
|
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
|
|
|
sk->max_offset = (u64)-1;
|
|
|
|
sk->max_transid = (u64)-1;
|
|
|
|
sk->nr_items = 4096;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
|
|
|
if (ret < 0) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("can't perform the search: %s", strerror(errno));
|
2010-03-18 16:32:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* the ioctl returns the number of item it found in nr_items */
|
|
|
|
if (sk->nr_items == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
off = 0;
|
|
|
|
for (i = 0; i < sk->nr_items; i++) {
|
|
|
|
struct btrfs_root_item *item;
|
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
memcpy(&sh, args.buf + off, sizeof(sh));
|
|
|
|
off += sizeof(sh);
|
2010-03-18 16:32:32 +00:00
|
|
|
item = (struct btrfs_root_item *)(args.buf + off);
|
2012-10-21 14:34:33 +00:00
|
|
|
off += sh.len;
|
2010-03-18 16:32:32 +00:00
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
sk->min_objectid = sh.objectid;
|
|
|
|
sk->min_type = sh.type;
|
|
|
|
sk->min_offset = sh.offset;
|
2010-03-18 16:32:32 +00:00
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
if (sh.objectid > ino_args.treeid)
|
2010-03-18 16:32:32 +00:00
|
|
|
break;
|
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
if (sh.objectid == ino_args.treeid &&
|
|
|
|
sh.type == BTRFS_ROOT_ITEM_KEY) {
|
2010-03-18 16:32:32 +00:00
|
|
|
max_found = max(max_found,
|
|
|
|
btrfs_root_generation(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sk->min_offset < (u64)-1)
|
|
|
|
sk->min_offset++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (sk->min_type != BTRFS_ROOT_ITEM_KEY)
|
|
|
|
break;
|
2013-04-09 17:08:39 +00:00
|
|
|
if (sk->min_objectid != ino_args.treeid)
|
2010-03-18 16:32:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return max_found;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* pass in a directory id and this will return
|
|
|
|
* the full path of the parent directory inside its
|
|
|
|
* subvolume root.
|
|
|
|
*
|
|
|
|
* It may return NULL if it is in the root, or an ERR_PTR if things
|
|
|
|
* go badly.
|
|
|
|
*/
|
|
|
|
static char *__ino_resolve(int fd, u64 dirid)
|
|
|
|
{
|
|
|
|
struct btrfs_ioctl_ino_lookup_args args;
|
|
|
|
int ret;
|
|
|
|
char *full;
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
args.objectid = dirid;
|
|
|
|
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
2016-01-12 12:35:50 +00:00
|
|
|
if (ret < 0) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("failed to lookup path for dirid %llu: %s",
|
2016-01-12 10:20:18 +00:00
|
|
|
(unsigned long long)dirid, strerror(errno));
|
2010-03-18 16:32:32 +00:00
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.name[0]) {
|
|
|
|
/*
|
|
|
|
* we're in a subdirectory of ref_tree, the kernel ioctl
|
|
|
|
* puts a / in there for us
|
|
|
|
*/
|
|
|
|
full = strdup(args.name);
|
|
|
|
if (!full) {
|
|
|
|
perror("malloc failed");
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* we're at the root of ref_tree */
|
|
|
|
full = NULL;
|
|
|
|
}
|
|
|
|
return full;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* simple string builder, returning a new string with both
|
|
|
|
* dirid and name
|
|
|
|
*/
|
2016-09-29 13:12:35 +00:00
|
|
|
static char *build_name(const char *dirid, const char *name)
|
2010-03-18 16:32:32 +00:00
|
|
|
{
|
|
|
|
char *full;
|
2016-09-29 13:12:35 +00:00
|
|
|
|
2010-03-18 16:32:32 +00:00
|
|
|
if (!dirid)
|
|
|
|
return strdup(name);
|
|
|
|
|
|
|
|
full = malloc(strlen(dirid) + strlen(name) + 1);
|
|
|
|
if (!full)
|
|
|
|
return NULL;
|
|
|
|
strcpy(full, dirid);
|
|
|
|
strcat(full, name);
|
|
|
|
return full;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* given an inode number, this returns the full path name inside the subvolume
|
|
|
|
* to that file/directory. cache_dirid and cache_name are used to
|
|
|
|
* cache the results so we can avoid tree searches if a later call goes
|
|
|
|
* to the same directory or file name
|
|
|
|
*/
|
|
|
|
static char *ino_resolve(int fd, u64 ino, u64 *cache_dirid, char **cache_name)
|
|
|
|
|
|
|
|
{
|
|
|
|
u64 dirid;
|
|
|
|
char *dirname;
|
|
|
|
char *name;
|
|
|
|
char *full;
|
|
|
|
int ret;
|
|
|
|
struct btrfs_ioctl_search_args args;
|
|
|
|
struct btrfs_ioctl_search_key *sk = &args.key;
|
|
|
|
struct btrfs_ioctl_search_header *sh;
|
|
|
|
unsigned long off = 0;
|
|
|
|
int namelen;
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
|
|
|
sk->tree_id = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* step one, we search for the inode back ref. We just use the first
|
|
|
|
* one
|
|
|
|
*/
|
|
|
|
sk->min_objectid = ino;
|
|
|
|
sk->max_objectid = ino;
|
|
|
|
sk->max_type = BTRFS_INODE_REF_KEY;
|
|
|
|
sk->max_offset = (u64)-1;
|
|
|
|
sk->min_type = BTRFS_INODE_REF_KEY;
|
|
|
|
sk->max_transid = (u64)-1;
|
|
|
|
sk->nr_items = 1;
|
|
|
|
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
|
|
|
if (ret < 0) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("can't perform the search: %s", strerror(errno));
|
2010-03-18 16:32:32 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* the ioctl returns the number of item it found in nr_items */
|
|
|
|
if (sk->nr_items == 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
off = 0;
|
|
|
|
sh = (struct btrfs_ioctl_search_header *)(args.buf + off);
|
|
|
|
|
2016-05-03 14:20:52 +00:00
|
|
|
if (btrfs_search_header_type(sh) == BTRFS_INODE_REF_KEY) {
|
2010-03-18 16:32:32 +00:00
|
|
|
struct btrfs_inode_ref *ref;
|
2016-05-03 14:20:52 +00:00
|
|
|
dirid = btrfs_search_header_offset(sh);
|
2010-03-18 16:32:32 +00:00
|
|
|
|
|
|
|
ref = (struct btrfs_inode_ref *)(sh + 1);
|
|
|
|
namelen = btrfs_stack_inode_ref_name_len(ref);
|
|
|
|
|
|
|
|
name = (char *)(ref + 1);
|
|
|
|
name = strndup(name, namelen);
|
|
|
|
|
|
|
|
/* use our cached value */
|
|
|
|
if (dirid == *cache_dirid && *cache_name) {
|
|
|
|
dirname = *cache_name;
|
|
|
|
goto build;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* the inode backref gives us the file name and the parent directory id.
|
|
|
|
* From here we use __ino_resolve to get the path to the parent
|
|
|
|
*/
|
|
|
|
dirname = __ino_resolve(fd, dirid);
|
|
|
|
build:
|
|
|
|
full = build_name(dirname, name);
|
|
|
|
if (*cache_name && dirname != *cache_name)
|
|
|
|
free(*cache_name);
|
|
|
|
|
|
|
|
*cache_name = dirname;
|
|
|
|
*cache_dirid = dirid;
|
|
|
|
free(name);
|
|
|
|
|
|
|
|
return full;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int btrfs_list_get_default_subvolume(int fd, u64 *default_id)
|
2012-03-12 17:17:39 +00:00
|
|
|
{
|
|
|
|
struct btrfs_ioctl_search_args args;
|
|
|
|
struct btrfs_ioctl_search_key *sk = &args.key;
|
|
|
|
struct btrfs_ioctl_search_header *sh;
|
|
|
|
u64 found = 0;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* search for a dir item with a name 'default' in the tree of
|
|
|
|
* tree roots, it should point us to a default root
|
|
|
|
*/
|
2016-10-31 09:59:08 +00:00
|
|
|
sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
|
2012-03-12 17:17:39 +00:00
|
|
|
|
|
|
|
/* don't worry about ancient format and request only one item */
|
|
|
|
sk->nr_items = 1;
|
|
|
|
|
|
|
|
sk->max_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
|
|
|
|
sk->min_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
|
|
|
|
sk->max_type = BTRFS_DIR_ITEM_KEY;
|
|
|
|
sk->min_type = BTRFS_DIR_ITEM_KEY;
|
|
|
|
sk->max_offset = (u64)-1;
|
|
|
|
sk->max_transid = (u64)-1;
|
|
|
|
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* the ioctl returns the number of items it found in nr_items */
|
|
|
|
if (sk->nr_items == 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
sh = (struct btrfs_ioctl_search_header *)args.buf;
|
|
|
|
|
2016-05-03 14:20:52 +00:00
|
|
|
if (btrfs_search_header_type(sh) == BTRFS_DIR_ITEM_KEY) {
|
2012-03-12 17:17:39 +00:00
|
|
|
struct btrfs_dir_item *di;
|
|
|
|
int name_len;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
di = (struct btrfs_dir_item *)(sh + 1);
|
|
|
|
name_len = btrfs_stack_dir_name_len(di);
|
|
|
|
name = (char *)(di + 1);
|
|
|
|
|
|
|
|
if (!strncmp("default", name, name_len))
|
|
|
|
found = btrfs_disk_key_objectid(&di->location);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
*default_id = found;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
static int list_subvol_search(int fd, struct root_lookup *root_lookup)
|
2010-02-28 20:29:47 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct btrfs_ioctl_search_args args;
|
|
|
|
struct btrfs_ioctl_search_key *sk = &args.key;
|
2012-10-21 14:34:33 +00:00
|
|
|
struct btrfs_ioctl_search_header sh;
|
2010-02-28 20:29:47 +00:00
|
|
|
struct btrfs_root_ref *ref;
|
2012-08-03 09:48:55 +00:00
|
|
|
struct btrfs_root_item *ri;
|
2016-10-31 11:15:18 +00:00
|
|
|
unsigned long off;
|
2010-02-28 20:29:47 +00:00
|
|
|
int name_len;
|
|
|
|
char *name;
|
|
|
|
u64 dir_id;
|
2012-08-03 09:48:55 +00:00
|
|
|
u64 gen = 0;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
u64 ogen;
|
2012-09-18 09:14:37 +00:00
|
|
|
u64 flags;
|
2010-02-28 20:29:47 +00:00
|
|
|
int i;
|
|
|
|
|
2016-10-31 11:44:29 +00:00
|
|
|
root_lookup->root.rb_node = NULL;
|
2011-11-02 15:22:09 +00:00
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
2016-10-31 09:59:08 +00:00
|
|
|
sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
|
2016-10-31 11:04:55 +00:00
|
|
|
/* Search both live and deleted subvolumes */
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
2016-10-31 11:15:18 +00:00
|
|
|
sk->max_type = BTRFS_ROOT_BACKREF_KEY;
|
2016-10-31 12:56:28 +00:00
|
|
|
sk->min_objectid = BTRFS_FS_TREE_OBJECTID;
|
2012-08-03 09:48:51 +00:00
|
|
|
sk->max_objectid = BTRFS_LAST_FREE_OBJECTID;
|
2010-02-28 20:29:47 +00:00
|
|
|
sk->max_offset = (u64)-1;
|
|
|
|
sk->max_transid = (u64)-1;
|
|
|
|
|
|
|
|
while(1) {
|
2016-10-31 11:15:18 +00:00
|
|
|
sk->nr_items = 4096;
|
2010-02-28 20:29:47 +00:00
|
|
|
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
2011-11-02 15:22:09 +00:00
|
|
|
if (ret < 0)
|
2010-03-11 20:51:36 +00:00
|
|
|
return ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
if (sk->nr_items == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
off = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* for each item, pull the key out of the header and then
|
|
|
|
* read the root_ref item it contains
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sk->nr_items; i++) {
|
2012-10-21 14:34:33 +00:00
|
|
|
memcpy(&sh, args.buf + off, sizeof(sh));
|
|
|
|
off += sizeof(sh);
|
|
|
|
if (sh.type == BTRFS_ROOT_BACKREF_KEY) {
|
2010-03-18 16:32:32 +00:00
|
|
|
ref = (struct btrfs_root_ref *)(args.buf + off);
|
|
|
|
name_len = btrfs_stack_root_ref_name_len(ref);
|
|
|
|
name = (char *)(ref + 1);
|
|
|
|
dir_id = btrfs_stack_root_ref_dirid(ref);
|
|
|
|
|
2016-10-31 11:27:08 +00:00
|
|
|
add_root_backref(root_lookup, sh.objectid,
|
|
|
|
sh.offset, dir_id, name,
|
|
|
|
name_len);
|
2016-10-31 12:56:28 +00:00
|
|
|
} else if (sh.type == BTRFS_ROOT_ITEM_KEY &&
|
|
|
|
(sh.objectid >= BTRFS_FIRST_FREE_OBJECTID ||
|
|
|
|
sh.objectid == BTRFS_FS_TREE_OBJECTID)) {
|
2016-10-31 11:19:50 +00:00
|
|
|
time_t otime;
|
2016-10-31 11:33:28 +00:00
|
|
|
u8 uuid[BTRFS_UUID_SIZE];
|
|
|
|
u8 puuid[BTRFS_UUID_SIZE];
|
|
|
|
u8 ruuid[BTRFS_UUID_SIZE];
|
2016-10-31 11:19:50 +00:00
|
|
|
|
2012-08-03 09:48:55 +00:00
|
|
|
ri = (struct btrfs_root_item *)(args.buf + off);
|
|
|
|
gen = btrfs_root_generation(ri);
|
2012-09-18 09:14:37 +00:00
|
|
|
flags = btrfs_root_flags(ri);
|
2012-10-21 14:34:33 +00:00
|
|
|
if(sh.len >
|
2012-09-01 08:45:30 +00:00
|
|
|
sizeof(struct btrfs_root_item_v0)) {
|
2016-10-31 11:19:50 +00:00
|
|
|
otime = btrfs_stack_timespec_sec(&ri->otime);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ogen = btrfs_root_otransid(ri);
|
2012-08-14 06:04:06 +00:00
|
|
|
memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
|
2013-02-01 07:56:21 +00:00
|
|
|
memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
|
2014-08-13 21:18:17 +00:00
|
|
|
memcpy(ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
|
2012-08-14 06:04:06 +00:00
|
|
|
} else {
|
2016-10-31 11:19:50 +00:00
|
|
|
otime = 0;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ogen = 0;
|
2012-08-14 06:04:06 +00:00
|
|
|
memset(uuid, 0, BTRFS_UUID_SIZE);
|
2013-02-01 07:56:21 +00:00
|
|
|
memset(puuid, 0, BTRFS_UUID_SIZE);
|
2014-08-13 21:18:17 +00:00
|
|
|
memset(ruuid, 0, BTRFS_UUID_SIZE);
|
2012-08-14 06:04:06 +00:00
|
|
|
}
|
2012-08-03 09:48:55 +00:00
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
add_root(root_lookup, sh.objectid, 0,
|
|
|
|
sh.offset, flags, 0, NULL, 0, ogen,
|
2016-10-31 11:19:50 +00:00
|
|
|
gen, otime, uuid, puuid, ruuid);
|
2010-03-18 16:32:32 +00:00
|
|
|
}
|
2010-02-28 20:29:47 +00:00
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
off += sh.len;
|
2010-02-28 20:29:47 +00:00
|
|
|
|
2012-10-21 14:34:33 +00:00
|
|
|
sk->min_objectid = sh.objectid;
|
|
|
|
sk->min_type = sh.type;
|
|
|
|
sk->min_offset = sh.offset;
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
sk->min_offset++;
|
2016-10-31 11:04:55 +00:00
|
|
|
if (!sk->min_offset)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
sk->min_type++;
|
2012-08-03 09:48:55 +00:00
|
|
|
else
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
continue;
|
2012-08-03 09:48:55 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (sk->min_type > BTRFS_ROOT_BACKREF_KEY) {
|
|
|
|
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
2010-02-28 20:29:47 +00:00
|
|
|
sk->min_objectid++;
|
2010-03-18 16:32:32 +00:00
|
|
|
} else
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (sk->min_objectid > sk->max_objectid)
|
2010-02-28 20:29:47 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-11-02 15:22:09 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_by_rootid(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->root_id == data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_snapshot(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return !!ri->root_offset;
|
|
|
|
}
|
|
|
|
|
2012-09-18 09:14:37 +00:00
|
|
|
static int filter_flags(struct root_info *ri, u64 flags)
|
|
|
|
{
|
|
|
|
return ri->flags & flags;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
static int filter_gen_more(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->gen >= data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_gen_less(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->gen <= data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_gen_equal(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->gen == data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_cgen_more(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->ogen >= data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_cgen_less(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->ogen <= data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int filter_cgen_equal(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->ogen == data;
|
|
|
|
}
|
|
|
|
|
2012-09-27 17:04:20 +00:00
|
|
|
static int filter_topid_equal(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->top_id == data;
|
|
|
|
}
|
|
|
|
|
2012-12-11 14:24:58 +00:00
|
|
|
static int filter_full_path(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
if (ri->full_path && ri->top_id != data) {
|
|
|
|
char *tmp;
|
|
|
|
char p[] = "<FS_TREE>";
|
|
|
|
int add_len = strlen(p);
|
|
|
|
int len = strlen(ri->full_path);
|
|
|
|
|
|
|
|
tmp = malloc(len + add_len + 2);
|
|
|
|
if (!tmp) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
memcpy(tmp + add_len + 1, ri->full_path, len);
|
|
|
|
tmp[len + add_len + 1] = '\0';
|
|
|
|
tmp[add_len] = '/';
|
|
|
|
memcpy(tmp, p, add_len);
|
|
|
|
free(ri->full_path);
|
|
|
|
ri->full_path = tmp;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-02-01 07:56:24 +00:00
|
|
|
static int filter_by_parent(struct root_info *ri, u64 data)
|
|
|
|
{
|
2013-05-07 12:24:40 +00:00
|
|
|
return !uuid_compare(ri->puuid, (u8 *)(unsigned long)data);
|
2013-02-01 07:56:24 +00:00
|
|
|
}
|
|
|
|
|
2013-10-23 17:00:09 +00:00
|
|
|
static int filter_deleted(struct root_info *ri, u64 data)
|
|
|
|
{
|
|
|
|
return ri->deleted;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static btrfs_list_filter_func all_filter_funcs[] = {
|
|
|
|
[BTRFS_LIST_FILTER_ROOTID] = filter_by_rootid,
|
|
|
|
[BTRFS_LIST_FILTER_SNAPSHOT_ONLY] = filter_snapshot,
|
2012-09-18 09:14:37 +00:00
|
|
|
[BTRFS_LIST_FILTER_FLAGS] = filter_flags,
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
[BTRFS_LIST_FILTER_GEN_MORE] = filter_gen_more,
|
|
|
|
[BTRFS_LIST_FILTER_GEN_LESS] = filter_gen_less,
|
|
|
|
[BTRFS_LIST_FILTER_GEN_EQUAL] = filter_gen_equal,
|
|
|
|
[BTRFS_LIST_FILTER_CGEN_MORE] = filter_cgen_more,
|
|
|
|
[BTRFS_LIST_FILTER_CGEN_LESS] = filter_cgen_less,
|
|
|
|
[BTRFS_LIST_FILTER_CGEN_EQUAL] = filter_cgen_equal,
|
2012-09-27 17:04:20 +00:00
|
|
|
[BTRFS_LIST_FILTER_TOPID_EQUAL] = filter_topid_equal,
|
2012-12-11 14:24:58 +00:00
|
|
|
[BTRFS_LIST_FILTER_FULL_PATH] = filter_full_path,
|
2013-02-01 07:56:24 +00:00
|
|
|
[BTRFS_LIST_FILTER_BY_PARENT] = filter_by_parent,
|
2013-10-23 17:00:09 +00:00
|
|
|
[BTRFS_LIST_FILTER_DELETED] = filter_deleted,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
|
|
|
|
{
|
|
|
|
struct btrfs_list_filter_set *set;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
size = sizeof(struct btrfs_list_filter_set) +
|
|
|
|
BTRFS_LIST_NFILTERS_INCREASE * sizeof(struct btrfs_list_filter);
|
2015-09-29 17:10:36 +00:00
|
|
|
set = calloc(1, size);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (!set) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
set->total = BTRFS_LIST_NFILTERS_INCREASE;
|
2012-08-03 09:48:55 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
return set;
|
|
|
|
}
|
2012-08-03 09:48:55 +00:00
|
|
|
|
2016-10-31 10:51:54 +00:00
|
|
|
/*
|
|
|
|
* Setup list filters. Exit if there's not enough memory, as we can't continue
|
|
|
|
* without the structures set up properly.
|
|
|
|
*/
|
|
|
|
void btrfs_list_setup_filter(struct btrfs_list_filter_set **filter_set,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
enum btrfs_list_filter_enum filter, u64 data)
|
|
|
|
{
|
|
|
|
struct btrfs_list_filter_set *set = *filter_set;
|
|
|
|
int size;
|
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(set != NULL);
|
|
|
|
ASSERT(filter < BTRFS_LIST_FILTER_MAX);
|
|
|
|
ASSERT(set->nfilters <= set->total);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
if (set->nfilters == set->total) {
|
2015-08-21 08:51:52 +00:00
|
|
|
void *tmp;
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
size = set->total + BTRFS_LIST_NFILTERS_INCREASE;
|
|
|
|
size = sizeof(*set) + size * sizeof(struct btrfs_list_filter);
|
2015-08-21 08:51:52 +00:00
|
|
|
tmp = set;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
set = realloc(set, size);
|
|
|
|
if (!set) {
|
|
|
|
fprintf(stderr, "memory allocation failed\n");
|
2015-08-21 08:51:52 +00:00
|
|
|
free(tmp);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2012-08-03 09:48:55 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
memset(&set->filters[set->total], 0,
|
|
|
|
BTRFS_LIST_NFILTERS_INCREASE *
|
|
|
|
sizeof(struct btrfs_list_filter));
|
|
|
|
set->total += BTRFS_LIST_NFILTERS_INCREASE;
|
|
|
|
*filter_set = set;
|
2012-08-03 09:48:55 +00:00
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(set->filters[set->nfilters].filter_func == NULL);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
2014-03-28 12:39:57 +00:00
|
|
|
if (filter == BTRFS_LIST_FILTER_DELETED)
|
|
|
|
set->only_deleted = 1;
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
set->filters[set->nfilters].filter_func = all_filter_funcs[filter];
|
|
|
|
set->filters[set->nfilters].data = data;
|
|
|
|
set->nfilters++;
|
2011-11-02 15:22:09 +00:00
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static int filter_root(struct root_info *ri,
|
|
|
|
struct btrfs_list_filter_set *set)
|
2012-08-03 09:48:56 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int i, ret;
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2014-03-28 12:39:57 +00:00
|
|
|
if (!set)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
return 1;
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2013-10-23 17:00:09 +00:00
|
|
|
if (set->only_deleted && !ri->deleted)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!set->only_deleted && ri->deleted)
|
|
|
|
return 0;
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
for (i = 0; i < set->nfilters; i++) {
|
|
|
|
if (!set->filters[i].filter_func)
|
2012-08-03 09:48:56 +00:00
|
|
|
break;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = set->filters[i].filter_func(ri, set->filters[i].data);
|
|
|
|
if (!ret)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
static void filter_and_sort_subvol(struct root_lookup *all_subvols,
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
struct root_lookup *sort_tree,
|
|
|
|
struct btrfs_list_filter_set *filter_set,
|
2012-09-27 17:04:20 +00:00
|
|
|
struct btrfs_list_comparer_set *comp_set,
|
2012-12-11 14:25:00 +00:00
|
|
|
u64 top_id)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
struct rb_node *n;
|
|
|
|
struct root_info *entry;
|
|
|
|
int ret;
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2016-10-31 11:44:29 +00:00
|
|
|
sort_tree->root.rb_node = NULL;
|
2012-08-14 06:04:06 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
n = rb_last(&all_subvols->root);
|
|
|
|
while (n) {
|
|
|
|
entry = rb_entry(n, struct root_info, rb_node);
|
2012-08-03 09:48:56 +00:00
|
|
|
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
ret = resolve_root(all_subvols, entry, top_id);
|
2013-10-23 17:00:09 +00:00
|
|
|
if (ret == -ENOENT) {
|
|
|
|
entry->full_path = strdup("DELETED");
|
|
|
|
entry->deleted = 1;
|
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
ret = filter_root(entry, filter_set);
|
|
|
|
if (ret)
|
|
|
|
sort_tree_insert(sort_tree, entry, comp_set);
|
|
|
|
n = rb_prev(n);
|
2012-08-03 09:48:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
static int list_subvol_fill_paths(int fd, struct root_lookup *root_lookup)
|
2011-11-02 15:22:09 +00:00
|
|
|
{
|
|
|
|
struct rb_node *n;
|
|
|
|
|
|
|
|
n = rb_first(&root_lookup->root);
|
2010-02-28 20:29:47 +00:00
|
|
|
while (n) {
|
|
|
|
struct root_info *entry;
|
2010-03-11 20:51:36 +00:00
|
|
|
int ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
entry = rb_entry(n, struct root_info, rb_node);
|
2010-03-11 20:51:36 +00:00
|
|
|
ret = lookup_ino_path(fd, entry);
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
if (ret && ret != -ENOENT)
|
2010-03-11 20:51:36 +00:00
|
|
|
return ret;
|
2010-02-28 20:29:47 +00:00
|
|
|
n = rb_next(n);
|
|
|
|
}
|
|
|
|
|
2011-11-02 15:22:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-07-12 02:48:37 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
static void print_subvolume_column(struct root_info *subv,
|
|
|
|
enum btrfs_list_column_enum column)
|
2011-11-02 15:22:09 +00:00
|
|
|
{
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
char tstr[256];
|
2013-11-04 07:17:41 +00:00
|
|
|
char uuidparse[BTRFS_UUID_UNPARSED_SIZE];
|
2011-07-12 02:48:37 +00:00
|
|
|
|
2016-09-06 11:27:03 +00:00
|
|
|
ASSERT(0 <= column && column < BTRFS_LIST_ALL);
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
|
|
|
|
switch (column) {
|
|
|
|
case BTRFS_LIST_OBJECTID:
|
|
|
|
printf("%llu", subv->root_id);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_GENERATION:
|
|
|
|
printf("%llu", subv->gen);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_OGENERATION:
|
|
|
|
printf("%llu", subv->ogen);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_PARENT:
|
|
|
|
printf("%llu", subv->ref_tree);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_TOP_LEVEL:
|
|
|
|
printf("%llu", subv->top_id);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_OTIME:
|
2013-07-09 16:39:24 +00:00
|
|
|
if (subv->otime) {
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
localtime_r(&subv->otime, &tm);
|
|
|
|
strftime(tstr, 256, "%Y-%m-%d %X", &tm);
|
|
|
|
} else
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
strcpy(tstr, "-");
|
|
|
|
printf("%s", tstr);
|
|
|
|
break;
|
|
|
|
case BTRFS_LIST_UUID:
|
|
|
|
if (uuid_is_null(subv->uuid))
|
|
|
|
strcpy(uuidparse, "-");
|
|
|
|
else
|
|
|
|
uuid_unparse(subv->uuid, uuidparse);
|
|
|
|
printf("%s", uuidparse);
|
|
|
|
break;
|
2013-02-01 07:56:21 +00:00
|
|
|
case BTRFS_LIST_PUUID:
|
|
|
|
if (uuid_is_null(subv->puuid))
|
|
|
|
strcpy(uuidparse, "-");
|
|
|
|
else
|
|
|
|
uuid_unparse(subv->puuid, uuidparse);
|
|
|
|
printf("%s", uuidparse);
|
|
|
|
break;
|
2014-08-13 21:18:17 +00:00
|
|
|
case BTRFS_LIST_RUUID:
|
|
|
|
if (uuid_is_null(subv->ruuid))
|
|
|
|
strcpy(uuidparse, "-");
|
|
|
|
else
|
|
|
|
uuid_unparse(subv->ruuid, uuidparse);
|
|
|
|
printf("%s", uuidparse);
|
|
|
|
break;
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
case BTRFS_LIST_PATH:
|
|
|
|
BUG_ON(!subv->full_path);
|
|
|
|
printf("%s", subv->full_path);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2011-07-12 02:48:37 +00:00
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
}
|
2011-07-12 02:48:37 +00:00
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
static void print_one_subvol_info_raw(struct root_info *subv,
|
2016-10-31 10:08:06 +00:00
|
|
|
const char *raw_prefix)
|
2013-02-01 07:56:28 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++) {
|
|
|
|
if (!btrfs_list_columns[i].need_print)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (raw_prefix)
|
|
|
|
printf("%s",raw_prefix);
|
|
|
|
|
|
|
|
print_subvolume_column(subv, i);
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
static void print_one_subvol_info_table(struct root_info *subv)
|
2012-09-20 11:04:22 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++) {
|
|
|
|
if (!btrfs_list_columns[i].need_print)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
print_subvolume_column(subv, i);
|
|
|
|
|
|
|
|
if (i != BTRFS_LIST_PATH)
|
|
|
|
printf("\t");
|
|
|
|
|
|
|
|
if (i == BTRFS_LIST_TOP_LEVEL)
|
|
|
|
printf("\t");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
static void print_one_subvol_info_default(struct root_info *subv)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
int i;
|
2012-03-12 17:17:39 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++) {
|
|
|
|
if (!btrfs_list_columns[i].need_print)
|
2012-03-12 17:17:39 +00:00
|
|
|
continue;
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
printf("%s ", btrfs_list_columns[i].name);
|
|
|
|
print_subvolume_column(subv, i);
|
2012-03-12 17:17:39 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (i != BTRFS_LIST_PATH)
|
|
|
|
printf(" ");
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
printf("\n");
|
|
|
|
}
|
2010-02-28 20:29:47 +00:00
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
static void print_all_subvol_info_tab_head(void)
|
2012-09-20 11:04:22 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int len;
|
|
|
|
char barrier[20];
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++) {
|
|
|
|
if (btrfs_list_columns[i].need_print)
|
|
|
|
printf("%s\t", btrfs_list_columns[i].name);
|
|
|
|
|
|
|
|
if (i == BTRFS_LIST_ALL-1)
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < BTRFS_LIST_ALL; i++) {
|
|
|
|
memset(barrier, 0, sizeof(barrier));
|
|
|
|
|
|
|
|
if (btrfs_list_columns[i].need_print) {
|
|
|
|
len = strlen(btrfs_list_columns[i].name);
|
|
|
|
while (len--)
|
|
|
|
strcat(barrier, "-");
|
|
|
|
|
|
|
|
printf("%s\t", barrier);
|
|
|
|
}
|
|
|
|
if (i == BTRFS_LIST_ALL-1)
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
static void print_all_subvol_info(struct root_lookup *sorted_tree,
|
2016-10-31 10:11:50 +00:00
|
|
|
enum btrfs_list_layout layout, const char *raw_prefix)
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
{
|
|
|
|
struct rb_node *n;
|
|
|
|
struct root_info *entry;
|
|
|
|
|
2013-02-01 07:56:26 +00:00
|
|
|
if (layout == BTRFS_LIST_LAYOUT_TABLE)
|
2016-10-31 10:17:02 +00:00
|
|
|
print_all_subvol_info_tab_head();
|
2012-09-20 11:04:22 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
n = rb_first(&sorted_tree->root);
|
|
|
|
while (n) {
|
|
|
|
entry = rb_entry(n, struct root_info, sort_node);
|
2013-02-01 07:56:26 +00:00
|
|
|
switch (layout) {
|
|
|
|
case BTRFS_LIST_LAYOUT_DEFAULT:
|
2016-10-31 10:17:02 +00:00
|
|
|
print_one_subvol_info_default(entry);
|
2013-02-01 07:56:26 +00:00
|
|
|
break;
|
|
|
|
case BTRFS_LIST_LAYOUT_TABLE:
|
2016-10-31 10:17:02 +00:00
|
|
|
print_one_subvol_info_table(entry);
|
2013-02-01 07:56:26 +00:00
|
|
|
break;
|
2013-02-01 07:56:28 +00:00
|
|
|
case BTRFS_LIST_LAYOUT_RAW:
|
2016-10-31 10:17:02 +00:00
|
|
|
print_one_subvol_info_raw(entry, raw_prefix);
|
2013-02-01 07:56:28 +00:00
|
|
|
break;
|
2013-02-01 07:56:26 +00:00
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
n = rb_next(n);
|
|
|
|
}
|
2010-02-28 20:29:47 +00:00
|
|
|
}
|
2010-03-18 16:32:32 +00:00
|
|
|
|
2013-08-09 20:20:47 +00:00
|
|
|
static int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
|
2012-08-03 09:48:56 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
ret = list_subvol_search(fd, root_lookup);
|
2012-08-03 09:48:56 +00:00
|
|
|
if (ret) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("can't perform the search: %s", strerror(errno));
|
2012-08-03 09:48:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* now we have an rbtree full of root_info objects, but we need to fill
|
|
|
|
* in their path names within the subvol that is referencing each one.
|
|
|
|
*/
|
2016-10-31 09:52:26 +00:00
|
|
|
ret = list_subvol_fill_paths(fd, root_lookup);
|
2013-02-01 07:56:20 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2013-02-01 07:56:20 +00:00
|
|
|
int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
|
|
|
|
struct btrfs_list_comparer_set *comp_set,
|
2016-10-31 10:11:50 +00:00
|
|
|
enum btrfs_list_layout layout, int full_path,
|
|
|
|
const char *raw_prefix)
|
2013-02-01 07:56:20 +00:00
|
|
|
{
|
|
|
|
struct root_lookup root_lookup;
|
|
|
|
struct root_lookup root_sort;
|
2013-02-25 22:54:37 +00:00
|
|
|
int ret = 0;
|
|
|
|
u64 top_id = 0;
|
|
|
|
|
|
|
|
if (full_path)
|
|
|
|
ret = btrfs_list_get_path_rootid(fd, &top_id);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2013-02-01 07:56:20 +00:00
|
|
|
|
|
|
|
ret = btrfs_list_subvols(fd, &root_lookup);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2016-10-31 09:52:26 +00:00
|
|
|
filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
|
2012-12-11 14:25:00 +00:00
|
|
|
comp_set, top_id);
|
2012-08-03 09:48:56 +00:00
|
|
|
|
2016-10-31 10:17:02 +00:00
|
|
|
print_all_subvol_info(&root_sort, layout, raw_prefix);
|
2016-10-31 09:52:26 +00:00
|
|
|
rb_free_nodes(&root_lookup.root, free_root_info);
|
2013-02-01 07:56:20 +00:00
|
|
|
|
|
|
|
return 0;
|
2012-08-03 09:48:56 +00:00
|
|
|
}
|
|
|
|
|
2013-08-09 20:20:47 +00:00
|
|
|
static char *strdup_or_null(const char *s)
|
2013-02-25 22:54:35 +00:00
|
|
|
{
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
return strdup(s);
|
|
|
|
}
|
|
|
|
|
2016-10-31 12:56:28 +00:00
|
|
|
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("<FS_TREE>");
|
|
|
|
the_ri->full_path = strdup_or_null("/");
|
|
|
|
rb_free_nodes(&rl.root, free_root_info);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-02-01 07:56:23 +00:00
|
|
|
int btrfs_get_subvol(int fd, struct root_info *the_ri)
|
|
|
|
{
|
2013-02-25 22:54:37 +00:00
|
|
|
int ret, rr;
|
2013-02-01 07:56:23 +00:00
|
|
|
struct root_lookup rl;
|
|
|
|
struct rb_node *rbn;
|
|
|
|
struct root_info *ri;
|
2013-02-25 22:54:37 +00:00
|
|
|
u64 root_id;
|
|
|
|
|
|
|
|
ret = btrfs_list_get_path_rootid(fd, &root_id);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2013-02-01 07:56:23 +00:00
|
|
|
|
2013-02-25 22:54:37 +00:00
|
|
|
ret = btrfs_list_subvols(fd, &rl);
|
|
|
|
if (ret)
|
2013-02-01 07:56:30 +00:00
|
|
|
return ret;
|
2013-02-01 07:56:23 +00:00
|
|
|
|
|
|
|
rbn = rb_first(&rl.root);
|
|
|
|
while(rbn) {
|
|
|
|
ri = rb_entry(rbn, struct root_info, rb_node);
|
2013-02-01 07:56:30 +00:00
|
|
|
rr = resolve_root(&rl, ri, root_id);
|
|
|
|
if (rr == -ENOENT) {
|
|
|
|
ret = -ENOENT;
|
|
|
|
rbn = rb_next(rbn);
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-12 22:47:11 +00:00
|
|
|
|
|
|
|
if (!comp_entry_with_rootid(the_ri, ri, 0) ||
|
|
|
|
!uuid_compare(the_ri->uuid, ri->uuid)) {
|
2013-02-01 07:56:23 +00:00
|
|
|
memcpy(the_ri, ri, offsetof(struct root_info, path));
|
2013-02-25 22:54:35 +00:00
|
|
|
the_ri->path = strdup_or_null(ri->path);
|
|
|
|
the_ri->name = strdup_or_null(ri->name);
|
|
|
|
the_ri->full_path = strdup_or_null(ri->full_path);
|
2013-02-01 07:56:23 +00:00
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rbn = rb_next(rbn);
|
|
|
|
}
|
2016-10-31 09:52:26 +00:00
|
|
|
rb_free_nodes(&rl.root, free_root_info);
|
2013-02-01 07:56:23 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-18 16:32:32 +00:00
|
|
|
static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
|
|
|
|
struct btrfs_file_extent_item *item,
|
|
|
|
u64 found_gen, u64 *cache_dirid,
|
|
|
|
char **cache_dir_name, u64 *cache_ino,
|
|
|
|
char **cache_full_name)
|
|
|
|
{
|
2010-09-09 05:50:26 +00:00
|
|
|
u64 len = 0;
|
|
|
|
u64 disk_start = 0;
|
|
|
|
u64 disk_offset = 0;
|
2010-03-18 16:32:32 +00:00
|
|
|
u8 type;
|
|
|
|
int compressed = 0;
|
|
|
|
int flags = 0;
|
|
|
|
char *name = NULL;
|
|
|
|
|
2016-05-03 14:20:52 +00:00
|
|
|
if (btrfs_search_header_objectid(sh) == *cache_ino) {
|
2010-03-18 16:32:32 +00:00
|
|
|
name = *cache_full_name;
|
|
|
|
} else if (*cache_full_name) {
|
|
|
|
free(*cache_full_name);
|
|
|
|
*cache_full_name = NULL;
|
|
|
|
}
|
|
|
|
if (!name) {
|
2016-05-03 14:20:52 +00:00
|
|
|
name = ino_resolve(fd, btrfs_search_header_objectid(sh),
|
|
|
|
cache_dirid,
|
2010-03-18 16:32:32 +00:00
|
|
|
cache_dir_name);
|
|
|
|
*cache_full_name = name;
|
2016-05-03 14:20:52 +00:00
|
|
|
*cache_ino = btrfs_search_header_objectid(sh);
|
2010-03-18 16:32:32 +00:00
|
|
|
}
|
|
|
|
if (!name)
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
type = btrfs_stack_file_extent_type(item);
|
|
|
|
compressed = btrfs_stack_file_extent_compression(item);
|
|
|
|
|
|
|
|
if (type == BTRFS_FILE_EXTENT_REG ||
|
|
|
|
type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
|
|
disk_start = btrfs_stack_file_extent_disk_bytenr(item);
|
|
|
|
disk_offset = btrfs_stack_file_extent_offset(item);
|
|
|
|
len = btrfs_stack_file_extent_num_bytes(item);
|
|
|
|
} else if (type == BTRFS_FILE_EXTENT_INLINE) {
|
|
|
|
disk_start = 0;
|
|
|
|
disk_offset = 0;
|
|
|
|
len = btrfs_stack_file_extent_ram_bytes(item);
|
2010-09-09 06:10:28 +00:00
|
|
|
} else {
|
2016-10-31 10:32:12 +00:00
|
|
|
error(
|
|
|
|
"unhandled extent type %d for inode %llu file offset %llu gen %llu",
|
2010-09-09 06:10:28 +00:00
|
|
|
type,
|
2016-05-03 14:20:52 +00:00
|
|
|
(unsigned long long)btrfs_search_header_objectid(sh),
|
|
|
|
(unsigned long long)btrfs_search_header_offset(sh),
|
2010-09-09 06:10:28 +00:00
|
|
|
(unsigned long long)found_gen);
|
|
|
|
|
|
|
|
return -EIO;
|
2010-03-18 16:32:32 +00:00
|
|
|
}
|
|
|
|
printf("inode %llu file offset %llu len %llu disk start %llu "
|
|
|
|
"offset %llu gen %llu flags ",
|
2016-05-03 14:20:52 +00:00
|
|
|
(unsigned long long)btrfs_search_header_objectid(sh),
|
|
|
|
(unsigned long long)btrfs_search_header_offset(sh),
|
2010-03-18 16:32:32 +00:00
|
|
|
(unsigned long long)len,
|
|
|
|
(unsigned long long)disk_start,
|
|
|
|
(unsigned long long)disk_offset,
|
|
|
|
(unsigned long long)found_gen);
|
|
|
|
|
|
|
|
if (compressed) {
|
|
|
|
printf("COMPRESS");
|
|
|
|
flags++;
|
|
|
|
}
|
|
|
|
if (type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
|
|
printf("%sPREALLOC", flags ? "|" : "");
|
|
|
|
flags++;
|
|
|
|
}
|
|
|
|
if (type == BTRFS_FILE_EXTENT_INLINE) {
|
|
|
|
printf("%sINLINE", flags ? "|" : "");
|
|
|
|
flags++;
|
|
|
|
}
|
|
|
|
if (!flags)
|
|
|
|
printf("NONE");
|
|
|
|
|
|
|
|
printf(" %s\n", name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen)
|
2010-03-18 16:32:32 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct btrfs_ioctl_search_args args;
|
|
|
|
struct btrfs_ioctl_search_key *sk = &args.key;
|
2012-10-21 14:34:33 +00:00
|
|
|
struct btrfs_ioctl_search_header sh;
|
2010-03-18 16:32:32 +00:00
|
|
|
struct btrfs_file_extent_item *item;
|
|
|
|
unsigned long off = 0;
|
|
|
|
u64 found_gen;
|
|
|
|
u64 max_found = 0;
|
|
|
|
int i;
|
|
|
|
u64 cache_dirid = 0;
|
|
|
|
u64 cache_ino = 0;
|
|
|
|
char *cache_dir_name = NULL;
|
|
|
|
char *cache_full_name = NULL;
|
|
|
|
struct btrfs_file_extent_item backup;
|
|
|
|
|
|
|
|
memset(&backup, 0, sizeof(backup));
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
|
|
|
sk->tree_id = root_id;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set all the other params to the max, we'll take any objectid
|
|
|
|
* and any trans
|
|
|
|
*/
|
|
|
|
sk->max_objectid = (u64)-1;
|
|
|
|
sk->max_offset = (u64)-1;
|
|
|
|
sk->max_transid = (u64)-1;
|
|
|
|
sk->max_type = BTRFS_EXTENT_DATA_KEY;
|
|
|
|
sk->min_transid = oldest_gen;
|
|
|
|
/* just a big number, doesn't matter much */
|
|
|
|
sk->nr_items = 4096;
|
|
|
|
|
|
|
|
max_found = find_root_gen(fd);
|
|
|
|
while(1) {
|
|
|
|
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
|
|
|
if (ret < 0) {
|
2016-10-31 10:32:12 +00:00
|
|
|
error("can't perform the search: %s", strerror(errno));
|
2013-10-07 06:36:11 +00:00
|
|
|
break;
|
2010-03-18 16:32:32 +00:00
|
|
|
}
|
|
|
|
/* the ioctl returns the number of item it found in nr_items */
|
|
|
|
if (sk->nr_items == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
off = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* for each item, pull the key out of the header and then
|
|
|
|
* read the root_ref item it contains
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sk->nr_items; i++) {
|
2012-10-21 14:34:33 +00:00
|
|
|
memcpy(&sh, args.buf + off, sizeof(sh));
|
|
|
|
off += sizeof(sh);
|
2010-03-18 16:32:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* just in case the item was too big, pass something other
|
|
|
|
* than garbage
|
|
|
|
*/
|
2012-10-21 14:34:33 +00:00
|
|
|
if (sh.len == 0)
|
2010-03-18 16:32:32 +00:00
|
|
|
item = &backup;
|
|
|
|
else
|
|
|
|
item = (struct btrfs_file_extent_item *)(args.buf +
|
|
|
|
off);
|
|
|
|
found_gen = btrfs_stack_file_extent_generation(item);
|
2012-10-21 14:34:33 +00:00
|
|
|
if (sh.type == BTRFS_EXTENT_DATA_KEY &&
|
2010-03-18 16:32:32 +00:00
|
|
|
found_gen >= oldest_gen) {
|
2012-10-21 14:34:33 +00:00
|
|
|
print_one_extent(fd, &sh, item, found_gen,
|
2010-03-18 16:32:32 +00:00
|
|
|
&cache_dirid, &cache_dir_name,
|
|
|
|
&cache_ino, &cache_full_name);
|
|
|
|
}
|
2012-10-21 14:34:33 +00:00
|
|
|
off += sh.len;
|
2010-03-18 16:32:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* record the mins in sk so we can make sure the
|
|
|
|
* next search doesn't repeat this root
|
|
|
|
*/
|
2012-10-21 14:34:33 +00:00
|
|
|
sk->min_objectid = sh.objectid;
|
|
|
|
sk->min_offset = sh.offset;
|
|
|
|
sk->min_type = sh.type;
|
2010-03-18 16:32:32 +00:00
|
|
|
}
|
|
|
|
sk->nr_items = 4096;
|
|
|
|
if (sk->min_offset < (u64)-1)
|
|
|
|
sk->min_offset++;
|
|
|
|
else if (sk->min_objectid < (u64)-1) {
|
|
|
|
sk->min_objectid++;
|
|
|
|
sk->min_offset = 0;
|
|
|
|
sk->min_type = 0;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
free(cache_dir_name);
|
|
|
|
free(cache_full_name);
|
|
|
|
printf("transid marker was %llu\n", (unsigned long long)max_found);
|
|
|
|
return ret;
|
|
|
|
}
|
2011-11-02 15:42:30 +00:00
|
|
|
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
char *btrfs_list_path_for_root(int fd, u64 root)
|
2011-11-02 15:42:30 +00:00
|
|
|
{
|
|
|
|
struct root_lookup root_lookup;
|
|
|
|
struct rb_node *n;
|
|
|
|
char *ret_path = NULL;
|
|
|
|
int ret;
|
2013-02-25 22:54:37 +00:00
|
|
|
u64 top_id;
|
|
|
|
|
|
|
|
ret = btrfs_list_get_path_rootid(fd, &top_id);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
2011-11-02 15:42:30 +00:00
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
ret = list_subvol_search(fd, &root_lookup);
|
2011-11-02 15:42:30 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
2016-10-31 09:52:26 +00:00
|
|
|
ret = list_subvol_fill_paths(fd, &root_lookup);
|
2011-11-02 15:42:30 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
n = rb_last(&root_lookup.root);
|
|
|
|
while (n) {
|
|
|
|
struct root_info *entry;
|
2012-03-12 17:17:39 +00:00
|
|
|
|
2011-11-02 15:42:30 +00:00
|
|
|
entry = rb_entry(n, struct root_info, rb_node);
|
Btrfs-progs: filter the deleted subvolumes when listing snapshots
btrfs snapshot list command will stop by the deleted subvolumes.
The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
but ROOT_ITEM still exists. The command will fail to fill the path of
the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
Fs tree
|->subv0
|->subv1
We may fill the path of subv1 firstly, after that, some user deletes subv1
and subv0, and then we fill the path of subv0. The command will fail to
fill the path of subv0 because we can not get path of subv0. And the command
also will fail to make the full path of subv1 because we don't have the path
of subv0.
Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.
For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.
Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
2013-02-01 07:56:29 +00:00
|
|
|
ret = resolve_root(&root_lookup, entry, top_id);
|
|
|
|
if (ret == -ENOENT && entry->root_id == root) {
|
|
|
|
ret_path = NULL;
|
|
|
|
break;
|
|
|
|
}
|
Btrfs-progs: restructure list_subvolumes
The current code of list_subvols() has very bad scalability, if we want to
add new filter conditions or new sort methods, we have to modify lots of code.
Beside that, the most code of list_snapshots() is similar to list_subvols(),
So I restructure list_subvols(), and split the subvolume filter function,
the subvolume sort function and the output function from list_subvols().
In order to implement it, we defined some importtant structures:
struct btrfs_list_filter {
btrfs_list_filter_func filter_func;
void *data;
};
struct btrfs_list_comparer {
btrfs_list_comp_func comp_func;
int is_descending;
};
struct {
char *name;
char *column_name;
int need_print;
} btrfs_list_columns[];
If we want to add a new filter condition, we can choose a suitable filter
function, or implement a new filter function[1], and add it into a set of
the filters, and then pass the filter set into list_subvols(). We also can
mix several filters (just add those filters into the set, and pass the set
into list_subvols()) if the users specify two or more filter conditions.
The subvolume sort function is similar to the subvolume filter function. The
differentiation is the order of comparers in the array which is passed into
list_subvols() show us the priority of the sort methods.
The output function is different with the above two functions, we define a
array to manage all the columns that can be outputed, and use a member variant
(->need_print) to control the output of the relative column. Some columns are
outputed by default. But we can change it according to the requirement of the
users.
After appling this patch, we needn't implement a independent list_snapshots()
function, just pass a filter function which is used to identify the snapshot
into list_subvols().
[1]: If we implement new filter functions or compare functions, we must add
them into the array all_filter_funcs or the array all_comp_funcs, and modify
the relative enum variants(btrfs_list_filter_enum, btrfs_list_comp_enum).
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-18 06:51:49 +00:00
|
|
|
if (entry->root_id == root) {
|
|
|
|
ret_path = entry->full_path;
|
|
|
|
entry->full_path = NULL;
|
|
|
|
}
|
2012-03-12 17:17:39 +00:00
|
|
|
|
2011-11-02 15:42:30 +00:00
|
|
|
n = rb_prev(n);
|
|
|
|
}
|
2016-10-31 09:52:26 +00:00
|
|
|
rb_free_nodes(&root_lookup.root, free_root_info);
|
2011-11-02 15:42:30 +00:00
|
|
|
|
|
|
|
return ret_path;
|
|
|
|
}
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
|
2013-09-09 22:06:24 +00:00
|
|
|
int btrfs_list_parse_sort_string(char *opt_arg,
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
struct btrfs_list_comparer_set **comps)
|
|
|
|
{
|
|
|
|
int order;
|
|
|
|
int flag;
|
|
|
|
char *p;
|
|
|
|
char **ptr_argv;
|
|
|
|
int what_to_sort;
|
|
|
|
|
2013-09-09 22:06:24 +00:00
|
|
|
while ((p = strtok(opt_arg, ",")) != NULL) {
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
flag = 0;
|
|
|
|
ptr_argv = all_sort_items;
|
|
|
|
|
|
|
|
while (*ptr_argv) {
|
|
|
|
if (strcmp(*ptr_argv, p) == 0) {
|
|
|
|
flag = 1;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
p++;
|
|
|
|
if (strcmp(*ptr_argv, p) == 0) {
|
|
|
|
flag = 1;
|
|
|
|
p--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p--;
|
|
|
|
}
|
|
|
|
ptr_argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else {
|
|
|
|
if (*p == '+') {
|
|
|
|
order = 0;
|
|
|
|
p++;
|
|
|
|
} else if (*p == '-') {
|
|
|
|
order = 1;
|
|
|
|
p++;
|
|
|
|
} else
|
|
|
|
order = 0;
|
|
|
|
|
|
|
|
what_to_sort = btrfs_list_get_sort_item(p);
|
|
|
|
btrfs_list_setup_comparer(comps, what_to_sort, order);
|
|
|
|
}
|
2013-09-09 22:06:24 +00:00
|
|
|
opt_arg = NULL;
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function is used to parse the argument of filter condition.
|
|
|
|
*
|
|
|
|
* type is the filter object.
|
|
|
|
*/
|
2013-09-09 22:06:24 +00:00
|
|
|
int btrfs_list_parse_filter_string(char *opt_arg,
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
struct btrfs_list_filter_set **filters,
|
|
|
|
enum btrfs_list_filter_enum type)
|
|
|
|
{
|
|
|
|
|
|
|
|
u64 arg;
|
|
|
|
|
2013-09-09 22:06:24 +00:00
|
|
|
switch (*(opt_arg++)) {
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
case '+':
|
2014-02-20 01:30:50 +00:00
|
|
|
arg = arg_strtou64(opt_arg);
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
type += 2;
|
|
|
|
|
|
|
|
btrfs_list_setup_filter(filters, type, arg);
|
|
|
|
break;
|
|
|
|
case '-':
|
2014-02-20 01:30:50 +00:00
|
|
|
arg = arg_strtou64(opt_arg);
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
type += 1;
|
|
|
|
|
|
|
|
btrfs_list_setup_filter(filters, type, arg);
|
|
|
|
break;
|
|
|
|
default:
|
2013-09-09 22:06:24 +00:00
|
|
|
opt_arg--;
|
2014-02-20 01:30:50 +00:00
|
|
|
arg = arg_strtou64(opt_arg);
|
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options
The option '-g' can help you filter the subvolumes by the generation, you may
use it just like:
btrfs subvol list -g +/-value <path>
'+' means the generation of the subvolumes should >= the value you specified.
'-' means the generation should <= the value
If you don't input either '+' nor '-', this command will list the subvolumes
that their generation equals to the value.
However if you want to find gengeration between value1 and value2
you may use the above like:
btrfs sub list -g -value1 -g +value2 <path>
The option '-c' can help you filter the subvolumes by the ogeneration, you may
use it just like:
btrfs subvol list -c +/-value <path>
The usage is the same to '-g'
You might want to list subvolumes in order of some items, such as root id, gen
and so on, you can use '--sort'. Now you can sort the subvolumes by root id,
gen, ogen and path.
For example:
If you want to list subvolumes in order of rootid, you can use the option like
that:
btrfs sub list --sort=+/-rooid <path>
Here, '+' means the result is sorted by ascending order. '-' is by descending
order. If you don't specify either '+' nor '-', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs sub list --sort=-rootid,+path,ogen,gen <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
2012-09-19 09:21:51 +00:00
|
|
|
|
|
|
|
btrfs_list_setup_filter(filters, type, arg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-02-25 22:54:37 +00:00
|
|
|
int btrfs_list_get_path_rootid(int fd, u64 *treeid)
|
2012-09-27 17:04:20 +00:00
|
|
|
{
|
2016-10-31 09:38:31 +00:00
|
|
|
int ret;
|
2012-09-27 17:04:20 +00:00
|
|
|
|
2016-10-31 09:38:31 +00:00
|
|
|
ret = lookup_path_rootid(fd, treeid);
|
|
|
|
if (ret < 0)
|
|
|
|
error("cannot resolve rootid for path: %s",
|
2012-09-27 17:04:20 +00:00
|
|
|
strerror(errno));
|
2016-10-31 09:38:31 +00:00
|
|
|
|
|
|
|
return ret;
|
2012-09-27 17:04:20 +00:00
|
|
|
}
|