Пример #1
0
/*
 * _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;
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
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;
}