[lvm-devel] master - cache: add validate_lv_cache_create

Zdenek Kabelac zkabelac at fedoraproject.org
Mon Oct 6 13:32:57 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5a366918432bf4f825d2ddbb00780943c0761a0d
Commit:        5a366918432bf4f825d2ddbb00780943c0761a0d
Parent:        a8497e329b3c70c88feb5f0121e05464d32b2433
Author:        Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate:    Fri Oct 3 18:37:11 2014 +0200
Committer:     Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Mon Oct 6 15:18:05 2014 +0200

cache: add validate_lv_cache_create

Move validation tests into separate function.
---
 lib/metadata/cache_manip.c       |   98 +++++++++++++++++++++++++-------------
 lib/metadata/metadata-exported.h |    2 +
 2 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index a44bba8..80214c9 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -90,6 +90,63 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
 }
 
 /*
+ * Validate arguments for converting origin into cached volume with given cache pool.
+ *
+ * Always validates origin_lv, and when it is known also cache pool_lv
+ */
+int validate_lv_cache_create(const struct logical_volume *pool_lv,
+			     const struct logical_volume *origin_lv)
+{
+	struct lv_segment *seg;
+
+	if (pool_lv) {
+		if (!lv_is_cache_pool(pool_lv)) {
+			log_error("Logical volume %s is not a cache pool.",
+				  display_lvname(pool_lv));
+			return 0;
+		}
+
+		if (origin_lv == pool_lv) {
+			log_error("Can't use same LV %s for cache pool and cache volume.",
+				  display_lvname(pool_lv));
+			return 0;
+		}
+
+		if (!dm_list_empty(&pool_lv->segs_using_this_lv)) {
+			seg = get_only_segment_using_this_lv(pool_lv);
+			log_error("Logical volume %s is already in use by %s",
+				  display_lvname(pool_lv),
+				  seg ? display_lvname(seg->lv) : "another LV");
+			return 0;
+		}
+	}
+
+	/* For now we only support conversion of thin pool data volume */
+	if (!lv_is_visible(origin_lv) && !lv_is_thin_pool_data(origin_lv)) {
+		log_error("Can't convert internal LV %s.", display_lvname(origin_lv));
+		return 0;
+	}
+
+	/*
+	 * Only linear, striped or raid supported.
+	 * FIXME Tidy up all these type restrictions.
+	 */
+	if (lv_is_cache_type(origin_lv) ||
+	    lv_is_mirror_type(origin_lv) ||
+	    lv_is_thin_volume(origin_lv) || lv_is_thin_pool_metadata(origin_lv) ||
+	    lv_is_origin(origin_lv) || lv_is_merging_origin(origin_lv) ||
+	    lv_is_cow(origin_lv) || lv_is_merging_cow(origin_lv) ||
+	    lv_is_external_origin(origin_lv) ||
+	    lv_is_virtual(origin_lv)) {
+		log_error("Cache is not supported with origin LV %s type.",
+			  display_lvname(origin_lv));
+		return 0;
+	}
+
+	return 1;
+}
+
+/*
  * lv_cache_create
  * @pool
  * @origin
@@ -99,57 +156,32 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
  *
  * Returns: cache LV on success, NULL on failure
  */
-struct logical_volume *lv_cache_create(struct logical_volume *pool,
-				       struct logical_volume *origin)
+struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
+				       struct logical_volume *origin_lv)
 {
 	const struct segment_type *segtype;
-	struct cmd_context *cmd = pool->vg->cmd;
-	struct logical_volume *cache_lv;
+	struct cmd_context *cmd = pool_lv->vg->cmd;
+	struct logical_volume *cache_lv = origin_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("Creating a cache LV from an existing cache LV is"
-			  "not yet supported.");
-		return NULL;
-	}
+	if (!validate_lv_cache_create(pool_lv, origin_lv))
+		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")))
+	if (!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))
+	if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
 		return_NULL;
 
 	return cache_lv;
 }
 
-
 /*
  * Cleanup orphan device in the table with temporary activation
  * since in the suspend() we can't deactivate unused nodes
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index b392bde..d04d987 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1074,6 +1074,8 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
 			     int passed_args, uint32_t data_extents,
 			     uint64_t *pool_metadata_size,
 			     int *chunk_size_calc_method, uint32_t *chunk_size);
+int validate_lv_cache_create(const struct logical_volume *pool_lv,
+			     const struct logical_volume *origin_lv);
 struct logical_volume *lv_cache_create(struct logical_volume *pool,
 				       struct logical_volume *origin);
 int lv_cache_remove(struct logical_volume *cache_lv);




More information about the lvm-devel mailing list