mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
vg: add radix_tree for lv uuids
When searching for committed LV by uuid, this search can be expensive for commands like 'vgremove' - so for this part introduce 'lv_uuids' radix_tree that is build with first access to lv_committed().
This commit is contained in:
parent
db0f1b799f
commit
c2afa7a116
@ -1667,6 +1667,13 @@ struct logical_volume *find_lv_in_vg_by_lvid(const struct volume_group *vg,
|
|||||||
if (memcmp(&lvid->id[0], &vg->id, ID_LEN))
|
if (memcmp(&lvid->id[0], &vg->id, ID_LEN))
|
||||||
return NULL; /* Check VG does not match */
|
return NULL; /* Check VG does not match */
|
||||||
|
|
||||||
|
if (vg->lv_uuids)
|
||||||
|
/* Used only for committed read-only VG (which happens to be
|
||||||
|
* the only user of this 'find' function.
|
||||||
|
* ATM we do NOT update this radix_tree when LV is added/removed! */
|
||||||
|
return radix_tree_lookup_ptr(vg->lv_uuids, &lvid->id[1],
|
||||||
|
sizeof(lvid->id[1]));
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &vg->lvs)
|
dm_list_iterate_items(lvl, &vg->lvs)
|
||||||
if (!memcmp(&lvid->id[1], &lvl->lv->lvid.id[1], sizeof(lvid->id[1])))
|
if (!memcmp(&lvid->id[1], &lvl->lv->lvid.id[1], sizeof(lvid->id[1])))
|
||||||
return lvl->lv; /* LV uuid match */
|
return lvl->lv; /* LV uuid match */
|
||||||
@ -4349,6 +4356,8 @@ const struct logical_volume *lv_committed(const struct logical_volume *lv)
|
|||||||
{
|
{
|
||||||
struct volume_group *vg;
|
struct volume_group *vg;
|
||||||
const struct logical_volume *found_lv;
|
const struct logical_volume *found_lv;
|
||||||
|
struct lv_list *lvl;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!lv)
|
if (!lv)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4358,6 +4367,24 @@ const struct logical_volume *lv_committed(const struct logical_volume *lv)
|
|||||||
|
|
||||||
vg = lv->vg->vg_committed;
|
vg = lv->vg->vg_committed;
|
||||||
|
|
||||||
|
if (!vg->lv_uuids &&
|
||||||
|
(vg->lv_uuids = radix_tree_create(NULL, NULL)))
|
||||||
|
/* Create radix_tree for the 'committed' VG, that should
|
||||||
|
* never be modified and is only used for 'activation'
|
||||||
|
* so the tree need to constructed just once. */
|
||||||
|
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||||
|
if (!(r = radix_tree_uniq_insert_ptr(vg->lv_uuids,
|
||||||
|
&lvl->lv->lvid.id[1],
|
||||||
|
sizeof(lvl->lv->lvid.id[1]),
|
||||||
|
lvl->lv))) {
|
||||||
|
radix_tree_destroy(vg->lv_uuids);
|
||||||
|
vg->lv_uuids = NULL; /* fallback to linear search */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (r != 1) /* There is duplicate ID, but continue with 'best' effort */
|
||||||
|
log_warn("WARNING: Duplicate id found!");
|
||||||
|
}
|
||||||
|
|
||||||
if (!(found_lv = find_lv_in_vg_by_lvid(vg, &lv->lvid))) {
|
if (!(found_lv = find_lv_in_vg_by_lvid(vg, &lv->lvid))) {
|
||||||
log_error(INTERNAL_ERROR "LV %s (UUID %s) not found in committed metadata.",
|
log_error(INTERNAL_ERROR "LV %s (UUID %s) not found in committed metadata.",
|
||||||
display_lvname(lv), lv->lvid.s);
|
display_lvname(lv), lv->lvid.s);
|
||||||
|
@ -81,6 +81,9 @@ static void _free_vg(struct volume_group *vg)
|
|||||||
if (vg->lv_names)
|
if (vg->lv_names)
|
||||||
radix_tree_destroy(vg->lv_names);
|
radix_tree_destroy(vg->lv_names);
|
||||||
|
|
||||||
|
if (vg->lv_uuids)
|
||||||
|
radix_tree_destroy(vg->lv_uuids);
|
||||||
|
|
||||||
if (vg->pv_names)
|
if (vg->pv_names)
|
||||||
radix_tree_destroy(vg->pv_names);
|
radix_tree_destroy(vg->pv_names);
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ struct volume_group {
|
|||||||
uint64_t status;
|
uint64_t status;
|
||||||
|
|
||||||
struct radix_tree *lv_names; /* maintained tree for LV names within VG */
|
struct radix_tree *lv_names; /* maintained tree for LV names within VG */
|
||||||
|
struct radix_tree *lv_uuids; /* LV uuid (when searching committed metadata) */
|
||||||
struct radix_tree *pv_names; /* PV names used for metadata import */
|
struct radix_tree *pv_names; /* PV names used for metadata import */
|
||||||
|
|
||||||
struct id id;
|
struct id id;
|
||||||
|
Loading…
Reference in New Issue
Block a user