diff --git a/WHATS_NEW b/WHATS_NEW index 523858eec..6df377862 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.46 - ================================ + Introduce link_lv_to_vg and unlink_lv_from_vg functions. Remove lv_count from VG and use counter function instead. Fix snapshot segment import to not use duplicate segments & replace. Do not query nonexistent devices for readahead. diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index b32a3458b..5250e4843 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -455,25 +455,23 @@ static struct logical_volume *_add_lv(struct dm_pool *mem, struct volume_group *vg, struct lv_disk *lvd) { - struct lv_list *ll; struct logical_volume *lv; - if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) || - !(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) + if (!(lv = dm_pool_zalloc(mem, sizeof(*lv)))) return_NULL; - lv = ll->lv; - lv->vg = vg; lvid_from_lvnum(&lv->lvid, &vg->id, lvd->lv_number); - if (!import_lv(vg->cmd, mem, lv, lvd)) { - dm_pool_free(mem, ll); - return_NULL; - } + if (!import_lv(vg->cmd, mem, lv, lvd)) + goto_bad; - dm_list_add(&vg->lvs, &ll->list); + if (!link_lv_to_vg(vg, lv)) + goto_bad; return lv; +bad: + dm_pool_free(mem, lv); + return NULL; } int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds) diff --git a/lib/format_pool/import_export.c b/lib/format_pool/import_export.c index 25d53e714..0ddf8812d 100644 --- a/lib/format_pool/import_export.c +++ b/lib/format_pool/import_export.c @@ -57,22 +57,14 @@ int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct dm_list int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls) { struct pool_list *pl; - struct lv_list *lvl = dm_pool_zalloc(mem, sizeof(*lvl)); struct logical_volume *lv; - if (!lvl) { - log_error("Unable to allocate lv list structure"); - return 0; - } - - if (!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) { + if (!(lv = dm_pool_zalloc(mem, sizeof(*lv)))) { log_error("Unable to allocate logical volume structure"); return 0; } - lv = lvl->lv; lv->status = 0; - lv->vg = vg; lv->alloc = ALLOC_NORMAL; lv->size = 0; lv->name = NULL; @@ -114,10 +106,8 @@ int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct dm_list } lv->le_count = lv->size / POOL_PE_SIZE; - lvl->lv = lv; - dm_list_add(&vg->lvs, &lvl->list); - return 1; + return link_lv_to_vg(vg, lv); } int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg, diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c index 8f0d07c11..d8d8fcbf2 100644 --- a/lib/format_text/import_vsn1.c +++ b/lib/format_text/import_vsn1.c @@ -495,15 +495,11 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)), struct dm_hash_table *pv_hash __attribute((unused))) { struct logical_volume *lv; - struct lv_list *lvl; struct config_node *cn; - if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) || - !(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) + if (!(lv = dm_pool_zalloc(mem, sizeof(*lv)))) return_0; - lv = lvl->lv; - if (!(lv->name = dm_pool_strdup(mem, lvn->key))) return_0; @@ -561,10 +557,7 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)), return 0; } - lv->vg = vg; - dm_list_add(&vg->lvs, &lvl->list); - - return 1; + return link_lv_to_vg(vg, lv); } static int _read_lvsegs(struct format_instance *fid __attribute((unused)), diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 64419d1a5..446278c96 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -402,7 +402,6 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction) */ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete) { - struct lv_list *lvl; struct lv_segment *seg; uint32_t count = extents; uint32_t reduction; @@ -433,12 +432,9 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete) return 1; /* Remove the LV if it is now empty */ - if (!lv->le_count) { - if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) - return_0; - - dm_list_del(&lvl->list); - } else if (lv->vg->fid->fmt->ops->lv_setup && + if (!lv->le_count && !unlink_lv_from_vg(lv)) + return_0; + else if (lv->vg->fid->fmt->ops->lv_setup && !lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) return_0; @@ -1819,8 +1815,6 @@ struct logical_volume *lv_create_empty(const char *name, struct volume_group *vg) { struct format_instance *fi = vg->fid; - struct cmd_context *cmd = vg->cmd; - struct lv_list *ll = NULL; struct logical_volume *lv; char dname[NAME_LEN]; @@ -1840,23 +1834,11 @@ struct logical_volume *lv_create_empty(const char *name, if (!import) log_verbose("Creating logical volume %s", name); - if (!(ll = dm_pool_zalloc(cmd->mem, sizeof(*ll))) || - !(ll->lv = dm_pool_zalloc(cmd->mem, sizeof(*ll->lv)))) { - log_error("lv_list allocation failed"); - if (ll) - dm_pool_free(cmd->mem, ll); - return NULL; - } + if (!(lv = dm_pool_zalloc(vg->vgmem, sizeof(*lv)))) + return_NULL; - lv = ll->lv; - lv->vg = vg; - - if (!(lv->name = dm_pool_strdup(cmd->mem, name))) { - log_error("lv name strdup failed"); - if (ll) - dm_pool_free(cmd->mem, ll); - return NULL; - } + if (!(lv->name = dm_pool_strdup(vg->vgmem, name))) + goto_bad; lv->status = status; lv->alloc = alloc; @@ -1874,15 +1856,16 @@ struct logical_volume *lv_create_empty(const char *name, if (lvid) lv->lvid = *lvid; - if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) { - if (ll) - dm_pool_free(cmd->mem, ll); - return_NULL; - } - - dm_list_add(&vg->lvs, &ll->list); - + if (!link_lv_to_vg(vg, lv)) + goto_bad; + + if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) + goto_bad; + return lv; +bad: + dm_pool_free(vg->vgmem, lv); + return NULL; } static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, @@ -1951,6 +1934,32 @@ struct dm_list *build_parallel_areas_from_lv(struct cmd_context *cmd, return parallel_areas; } +int link_lv_to_vg(struct volume_group *vg, struct logical_volume *lv) +{ + struct lv_list *lvl; + + if (!(lvl = dm_pool_zalloc(vg->vgmem, sizeof(*lvl)))) + return_0; + + lvl->lv = lv; + lv->vg = vg; + dm_list_add(&vg->lvs, &lvl->list); + + return 1; +} + +int unlink_lv_from_vg(struct logical_volume *lv) +{ + struct lv_list *lvl; + + if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) + return_0; + + dm_list_del(&lvl->list); + + return 1; +} + int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, const force_t force) { diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 2970b9c42..77cddccb6 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -368,6 +368,12 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name, int warnings, int scan_label_only); struct dm_list *get_pvs(struct cmd_context *cmd); +/* + * Add/remove LV to/from volume group + */ +int link_lv_to_vg(struct volume_group *vg, struct logical_volume *lv); +int unlink_lv_from_vg(struct logical_volume *lv); + /* Set full_scan to 1 to re-read every (filtered) device label */ struct dm_list *get_vgnames(struct cmd_context *cmd, int full_scan); struct dm_list *get_vgids(struct cmd_context *cmd, int full_scan);