[lvm-devel] [PATCH 2/3] Introduce find_shared_cow() and lv_is_shared_cow() wrappers.

Mike Snitzer snitzer at redhat.com
Fri Feb 26 21:04:21 UTC 2010


Signed-off-by: Mike Snitzer <snitzer at redhat.com>
---
 lib/activate/dev_manager.c       |   11 +++++----
 lib/metadata/metadata-exported.h |    3 ++
 lib/metadata/snapshot_manip.c    |   39 ++++++++++++++++++++++++++++++-------
 lib/report/report.c              |    8 +++---
 tools/lvresize.c                 |    3 +-
 5 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 47de5d9..0d4a01e 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1211,8 +1211,8 @@ static int _add_origin_target_to_dtree(struct dev_manager *dm,
 		}
 		if (!dm_tree_node_add_snapshot_shared_target(dnode, lv->size,
 				real_dlid, cow_dlid,
-				lv->shared_snapshot->exception_store,
-				lv->shared_snapshot->chunk_size,
+				find_shared_cow(lv)->exception_store,
+				find_shared_cow(lv)->chunk_size,
 				n, snapids))
 			return_0;
 	} else {
@@ -1261,7 +1261,7 @@ static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
 		return 0;
 	}
 
-	if (snap_seg->status & SNAPSHOT_SHARED)
+	if (lv_is_shared_cow(lv))
 		return 1;
 
 	if (!(origin_dlid = build_dlid(dm, snap_seg->origin->lvid.s, "real")))
@@ -1346,7 +1346,8 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
 			return 0;
 		}
 		if (lv_is_multisnap_origin(seg->lv)) {
-			if (!_add_new_lv_to_dtree(dm, dtree, seg->lv->shared_snapshot->cow, seg->lv, "cow"))
+			if (!_add_new_lv_to_dtree(dm, dtree,
+			    find_shared_cow(seg->lv)->cow, seg->lv, "cow"))
 				return_0;
 		} else if (lv_is_merging_origin(seg->lv)) {
 			if (!_add_new_lv_to_dtree(dm, dtree,
@@ -1432,7 +1433,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
 		}
 	}
 
-	if (lv_is_cow(lv) && find_cow(lv)->status & SNAPSHOT_SHARED && !layer)
+	if (lv_is_shared_cow(lv) && !layer)
 		return 1;
 
 	if (!identity_lv)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 5e5bcb7..c6ad213 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -633,6 +633,7 @@ int lv_is_merging_origin(const struct logical_volume *origin);
 int lv_is_merging_cow(const struct logical_volume *snapshot);
 int lv_is_multisnap_origin(const struct logical_volume *lv);
 int lv_is_multisnap_cow(const struct logical_volume *lv);
+int lv_is_shared_cow(const struct logical_volume *lv);
 
 /* Test if given LV is visible from user's perspective */
 int lv_is_visible(const struct logical_volume *lv);
@@ -641,6 +642,8 @@ int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
 
 struct lv_segment *find_merging_cow(const struct logical_volume *origin);
 
+struct lv_segment *find_shared_cow(const struct logical_volume *origin);
+
 /* Given a cow LV, return return the snapshot lv_segment that uses it */
 struct lv_segment *find_cow(const struct logical_volume *lv);
 
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
index 717b11a..66adfeb 100644
--- a/lib/metadata/snapshot_manip.c
+++ b/lib/metadata/snapshot_manip.c
@@ -41,6 +41,11 @@ int lv_is_multisnap_cow(const struct logical_volume *lv)
 	return seg && seg_is_virtual(seg) && seg->origin;
 }
 
+int lv_is_shared_cow(const struct logical_volume *lv)
+{
+	return lv_is_cow(lv) && (find_cow(lv)->status & SNAPSHOT_SHARED);
+}
+
 int lv_is_visible(const struct logical_volume *lv)
 {
 	if (lv->status & SNAPSHOT)
@@ -89,12 +94,31 @@ struct lv_segment *find_cow(const struct logical_volume *lv)
 	return lv->snapshot;
 }
 
+struct lv_segment *find_shared_cow(const struct logical_volume *origin)
+{
+	if (!lv_is_multisnap_origin(origin))
+		return NULL;
+
+	return origin->shared_snapshot;
+}
+
 /* Given a cow LV, return its origin */
 struct logical_volume *origin_from_cow(const struct logical_volume *lv)
 {
 	return lv->snapshot->origin;
 }
 
+static void init_shared_snapshot(struct lv_segment *cow_seg,
+				 struct logical_volume *origin)
+{
+	origin->shared_snapshot = cow_seg;
+}
+
+static void clear_shared_snapshot(struct logical_volume *origin)
+{
+	origin->shared_snapshot = NULL;
+}
+
 int init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
 		      struct logical_volume *cow, const char *exception_store,
 		      uint32_t chunk_size, int merge)
@@ -128,12 +152,11 @@ int init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
 		init_snapshot_merge(seg, origin);
 
 	if (seg->status & SNAPSHOT_SHARED) {
-		if (!origin->shared_snapshot) {
-			origin->shared_snapshot = seg;
-		} else {
-			log_err("Origin '%s' has already a shared snapshot.", origin->name);
+		if (lv_is_multisnap_origin(origin)) {
+			log_err("Origin '%s' already has a shared snapshot.", origin->name);
 			return_0;
 		}
+		init_shared_snapshot(seg, origin);
 	}
 
 	dm_list_add(&origin->snapshot_segs, &seg->origin_list);
@@ -189,8 +212,8 @@ int vg_add_snapshot(struct logical_volume *origin,
 		return 0;
 	}
 
-	if (snapshot_flags & SNAPSHOT_SHARED && origin->shared_snapshot) {
-		log_error("Origin has already a shared snapshot.");
+	if (snapshot_flags & SNAPSHOT_SHARED && lv_is_multisnap_origin(origin)) {
+		log_error("Origin already has a shared snapshot.");
 		return 0;
 	}
 
@@ -228,8 +251,8 @@ int vg_remove_snapshot(struct logical_volume *cow)
 		preload_origin = 1;
 	}
 
-	if (cow->snapshot->origin->shared_snapshot == cow->snapshot)
-		cow->snapshot->origin->shared_snapshot = NULL;
+	if (find_shared_cow(origin) == find_cow(cow))
+		clear_shared_snapshot(origin);
 
 	if (!lv_remove(cow->snapshot->lv)) {
 		log_error("Failed to remove internal snapshot LV %s",
diff --git a/lib/report/report.c b/lib/report/report.c
index 51ba7bc..f3f7209 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -383,8 +383,8 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
 		repstr[5] = '-';
 	}
 
-	if (lv_is_cow(lv) && lv->snapshot->status & SNAPSHOT_SHARED)
-		lv = lv->snapshot->origin;
+	if (lv_is_shared_cow(lv))
+		lv = origin_from_cow(lv);
 	else if (lv_is_multisnap_cow(lv))
 		lv = first_seg(lv)->origin;
 	else
@@ -1044,8 +1044,8 @@ report_empty:
 		return 1;
 	}
 
-	if (lv->snapshot->status & SNAPSHOT_SHARED)
-		lv = lv->snapshot->origin;
+	if (lv_is_shared_cow(lv))
+		lv = origin_from_cow(lv);
 
 	if (lv_info(lv->vg->cmd, lv, &info, 0, 0) && !info.exists)
 		goto report_empty;
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 7df48d3..60e30b2 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -575,8 +575,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
 			return ECMD_FAILED;
 		}
 	}
-	if (lp->resize == LV_REDUCE &&
-	    lv_is_cow(lv) && lv->snapshot->status & SNAPSHOT_SHARED) {
+	if (lp->resize == LV_REDUCE && lv_is_shared_cow(lv)) {
 		log_error("Shared snapshot cannot be reduced.");
 		return ECMD_FAILED;
 	}
-- 
1.6.5.2




More information about the lvm-devel mailing list