diff options
author | Peter Rajnoha <prajnoha@redhat.com> | 2016-03-01 15:19:57 +0100 |
---|---|---|
committer | Peter Rajnoha <prajnoha@redhat.com> | 2016-03-03 11:26:51 +0100 |
commit | eeaa5a4481e04c0131152fd88e6ea2651949ae35 (patch) | |
tree | 58ac274d9a4c9e869c3d17f47bfb2d4346dad8ce | |
parent | 937f72b168302c9d8acb1a8e06525106df00fe2f (diff) | |
download | lvm2-eeaa5a4481e04c0131152fd88e6ea2651949ae35.tar.gz |
metadata: add add_glv_to_indirect_glvs and remove_glv_from_indirect_glvs
The add_glv_to_indirect_glvs is a helper function that registers a
volume represented by struct generic_logical_volume instance ("glv")
as an indirect user of another volume ("origin_glv") and vice versa -
it also registers the other volume ("origin_glv") as indirect_origin
of user volume ("glv").
The remove_glv_from_indirect_glvs does the opposite.
-rw-r--r-- | lib/metadata/lv_manip.c | 58 | ||||
-rw-r--r-- | lib/metadata/metadata.h | 6 |
2 files changed, 64 insertions, 0 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index da6077085..399668ccb 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -5343,6 +5343,64 @@ struct glv_list *get_or_create_glvl(struct dm_pool *mem, struct logical_volume * return glvl; } +int add_glv_to_indirect_glvs(struct dm_pool *mem, + struct generic_logical_volume *origin_glv, + struct generic_logical_volume *glv) +{ + struct glv_list *glvl; + + if (!(glvl = dm_pool_zalloc(mem, sizeof(struct glv_list)))) { + log_error("Failed to allocate generic volume list item " + "for indirect glv %s", glv->is_historical ? glv->historical->name + : glv->live->name); + return 0; + } + + glvl->glv = glv; + + if (glv->is_historical) + glv->historical->indirect_origin = origin_glv; + else + first_seg(glv->live)->indirect_origin = origin_glv; + + if (origin_glv) { + if (origin_glv->is_historical) + dm_list_add(&origin_glv->historical->indirect_glvs, &glvl->list); + else + dm_list_add(&origin_glv->live->indirect_glvs, &glvl->list); + } + + return 1; +} + +int remove_glv_from_indirect_glvs(struct generic_logical_volume *origin_glv, + struct generic_logical_volume *glv) +{ + struct glv_list *glvl, *tglvl; + struct dm_list *list = origin_glv->is_historical ? &origin_glv->historical->indirect_glvs + : &origin_glv->live->indirect_glvs; + + dm_list_iterate_items_safe(glvl, tglvl, list) { + if (glvl->glv != glv) + continue; + + dm_list_del(&glvl->list); + + if (glvl->glv->is_historical) + glvl->glv->historical->indirect_origin = NULL; + else + first_seg(glvl->glv->live)->indirect_origin = NULL; + + return 1; + } + + log_error(INTERNAL_ERROR "%s logical volume %s is not a user of %s.", + glv->is_historical ? "historical" : "Live", + glv->is_historical ? glv->historical->name : glv->live->name, + origin_glv->is_historical ? origin_glv->historical->name : origin_glv->live->name); + return 0; +} + struct logical_volume *alloc_lv(struct dm_pool *mem) { struct logical_volume *lv; diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 91e596138..33cbfa649 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -440,6 +440,12 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le); int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg); int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg); +int add_glv_to_indirect_glvs(struct dm_pool *mem, + struct generic_logical_volume *origin_glv, + struct generic_logical_volume *user_glv); +int remove_glv_from_indirect_glvs(struct generic_logical_volume *glv, + struct generic_logical_volume *user_glv); + int for_each_sub_lv_except_pools(struct logical_volume *lv, int (*fn)(struct logical_volume *lv, void *data), void *data); |