/* * _determine_cache_argument * @vg * @lp * * 'lp->origin' is set with an LV that could be either the origin * or the cache_pool of the cached LV which is being created. This * function determines which it is and sets 'lp->origin' or * 'lp->pool' appropriately. */ static int _determine_cache_argument(struct volume_group *vg, struct lvcreate_params *lp) { struct lv_list *lvl; if (!seg_is_cache(lp)) { log_error(INTERNAL_ERROR "Unable to determine cache argument on %s segtype", lp->segtype->name); return 0; } if (!lp->origin) { log_error(INTERNAL_ERROR "Origin LV is not defined."); return 0; } if (!(lvl = find_lv_in_vg(vg, lp->origin))) { log_error("LV %s not found in Volume group %s.", lp->origin, vg->name); return 0; } if (lv_is_cache_pool(lvl->lv)) { lp->pool = lp->origin; lp->origin = NULL; } else { lp->pool = NULL; lp->create_pool = 1; } return 1; }
/* * lv_cache_create * @pool * @origin * * Given a cache_pool and an origin, link the two and create a * cached LV. * * Returns: cache LV on success, NULL on failure */ struct logical_volume *lv_cache_create(struct logical_volume *pool, struct logical_volume *origin) { const struct segment_type *segtype; struct cmd_context *cmd = pool->vg->cmd; struct logical_volume *cache_lv; struct lv_segment *seg; if (!lv_is_cache_pool(pool)) { log_error(INTERNAL_ERROR "%s is not a cache_pool LV", pool->name); return NULL; } if (!dm_list_empty(&pool->segs_using_this_lv)) { seg = get_only_segment_using_this_lv(pool); log_error("%s is already in use by %s", pool->name, seg ? seg->lv->name : "another LV"); return NULL; } if (lv_is_cache_type(origin)) { /* * FIXME: We can layer caches, insert_layer_for_lv() would * have to do a better job renaming the LVs in the stack * first so that there isn't a name collision with <name>_corig. * The origin under the origin would become *_corig_corig * before renaming the origin above to *_corig. */ log_error(INTERNAL_ERROR "The origin, %s, cannot be of cache type", origin->name); return NULL; } if (!(segtype = get_segtype_from_string(cmd, "cache"))) return_NULL; cache_lv = origin; if (!(origin = insert_layer_for_lv(cmd, cache_lv, CACHE, "_corig"))) return_NULL; seg = first_seg(cache_lv); seg->segtype = segtype; if (!attach_pool_lv(seg, pool, NULL, NULL)) return_NULL; return cache_lv; }
static dm_percent_t _metadata_percent(const struct logical_volume *lv) { dm_percent_t percent; struct lv_status_cache *status; if (lv_is_cache(lv) || lv_is_cache_pool(lv)) { if (!lv_cache_status(lv, &status)) { stack; return DM_PERCENT_INVALID; } percent = status->dirty_usage; dm_pool_destroy(status->mem); return percent; } if (lv_is_thin_pool(lv)) return lv_thin_pool_percent(lv, 1, &percent) ? percent : DM_PERCENT_INVALID; return DM_PERCENT_INVALID; }