public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2009-09-28 17:46 agk
  0 siblings, 0 replies; 8+ messages in thread
From: agk @ 2009-09-28 17:46 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2009-09-28 17:46:16

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: import_export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : lv_manip.c metadata.h 

Log message:
	Consolidate LV allocation into alloc_lv().

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1275&r2=1.1276
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.109&r2=1.110
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/import_export.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.64&r2=1.65
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.183&r2=1.184
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.198&r2=1.199

--- LVM2/WHATS_NEW	2009/09/28 16:36:03	1.1275
+++ LVM2/WHATS_NEW	2009/09/28 17:46:15	1.1276
@@ -1,5 +1,6 @@
 Version 2.02.54 -
 =====================================
+  Consolidate LV allocation into alloc_lv().
   Treat input units of both 's' and 'S' as 512-byte sectors.  (2.02.49)
   Use standard output units for 'PE Size' and 'Stripe size' in pv/lvdisplay.
   Add configure --enable-units-compat to set si_unit_consistency off by default.
--- LVM2/lib/format1/import-export.c	2009/09/15 18:35:14	1.109
+++ LVM2/lib/format1/import-export.c	2009/09/28 17:46:16	1.110
@@ -337,12 +337,6 @@
 	lv->size = lvd->lv_size;
 	lv->le_count = lvd->lv_allocated_le;
 
-	lv->snapshot = NULL;
-	dm_list_init(&lv->snapshot_segs);
-	dm_list_init(&lv->segments);
-	dm_list_init(&lv->tags);
-	dm_list_init(&lv->segs_using_this_lv);
-
 	return 1;
 }
 
@@ -457,7 +451,7 @@
 {
 	struct logical_volume *lv;
 
-	if (!(lv = dm_pool_zalloc(mem, sizeof(*lv))))
+	if (!(lv = alloc_lv(mem)))
 		return_NULL;
 
 	lvid_from_lvnum(&lv->lvid, &vg->id, lvd->lv_number);
--- LVM2/lib/format_pool/import_export.c	2009/05/13 21:25:02	1.27
+++ LVM2/lib/format_pool/import_export.c	2009/09/28 17:46:16	1.28
@@ -59,10 +59,8 @@
 	struct pool_list *pl;
 	struct logical_volume *lv;
 
-	if (!(lv = dm_pool_zalloc(mem, sizeof(*lv)))) {
-		log_error("Unable to allocate logical volume structure");
-		return 0;
-	}
+	if (!(lv = alloc_lv(mem)))
+		return_0;
 
 	lv->status = 0;
 	lv->alloc = ALLOC_NORMAL;
@@ -70,11 +68,6 @@
 	lv->name = NULL;
 	lv->le_count = 0;
 	lv->read_ahead = vg->cmd->default_settings.read_ahead;
-	lv->snapshot = NULL;
-	dm_list_init(&lv->snapshot_segs);
-	dm_list_init(&lv->segments);
-	dm_list_init(&lv->tags);
-	dm_list_init(&lv->segs_using_this_lv);
 
 	dm_list_iterate_items(pl, pls) {
 		lv->size += pl->pd.pl_blocks;
@@ -99,10 +92,6 @@
 		} else {
 			lv->minor = -1;
 		}
-		lv->snapshot = NULL;
-		dm_list_init(&lv->snapshot_segs);
-		dm_list_init(&lv->segments);
-		dm_list_init(&lv->tags);
 	}
 
 	lv->le_count = lv->size / POOL_PE_SIZE;
--- LVM2/lib/format_text/import_vsn1.c	2009/07/27 17:43:40	1.64
+++ LVM2/lib/format_text/import_vsn1.c	2009/09/28 17:46:16	1.65
@@ -495,7 +495,7 @@
 	struct logical_volume *lv;
 	struct config_node *cn;
 
-	if (!(lv = dm_pool_zalloc(mem, sizeof(*lv))))
+	if (!(lv = alloc_lv(mem)))
 		return_0;
 
 	if (!(lv->name = dm_pool_strdup(mem, lvn->key)))
@@ -541,12 +541,6 @@
 		}
 	}
 
-	lv->snapshot = NULL;
-	dm_list_init(&lv->snapshot_segs);
-	dm_list_init(&lv->segments);
-	dm_list_init(&lv->tags);
-	dm_list_init(&lv->segs_using_this_lv);
-
 	/* Optional tags */
 	if ((cn = find_config_node(lvn, "tags")) &&
 	    !(read_tags(mem, &lv->tags, cn->v))) {
--- LVM2/lib/metadata/lv_manip.c	2009/07/26 02:33:35	1.183
+++ LVM2/lib/metadata/lv_manip.c	2009/09/28 17:46:16	1.184
@@ -1862,6 +1862,24 @@
 	return 1;
 }
 
+struct logical_volume *alloc_lv(struct dm_pool *mem)
+{
+	struct logical_volume *lv;
+
+	if (!(lv = dm_pool_zalloc(mem, sizeof(*lv)))) {
+		log_error("Unable to allocate logical volume structure");
+		return NULL;
+	}
+
+	lv->snapshot = NULL;
+	dm_list_init(&lv->snapshot_segs);
+	dm_list_init(&lv->segments);
+	dm_list_init(&lv->tags);
+	dm_list_init(&lv->segs_using_this_lv);
+
+	return lv;
+}
+
 /*
  * Create a new empty LV.
  */
@@ -1891,7 +1909,7 @@
 
 	log_verbose("Creating logical volume %s", name);
 
-	if (!(lv = dm_pool_zalloc(vg->vgmem, sizeof(*lv))))
+	if (!(lv = alloc_lv(vg->vgmem)))
 		return_NULL;
 
 	if (!(lv->name = dm_pool_strdup(vg->vgmem, name)))
@@ -1904,11 +1922,6 @@
 	lv->minor = -1;
 	lv->size = UINT64_C(0);
 	lv->le_count = 0;
-	lv->snapshot = NULL;
-	dm_list_init(&lv->snapshot_segs);
-	dm_list_init(&lv->segments);
-	dm_list_init(&lv->tags);
-	dm_list_init(&lv->segs_using_this_lv);
 
 	if (lvid)
 		lv->lvid = *lvid;
--- LVM2/lib/metadata/metadata.h	2009/07/30 17:45:29	1.198
+++ LVM2/lib/metadata/metadata.h	2009/09/28 17:46:16	1.199
@@ -316,6 +316,8 @@
  */
 const char *strip_dir(const char *vg_name, const char *dir);
 
+struct logical_volume *alloc_lv(struct dm_pool *mem);
+
 /*
  * Checks that an lv has no gaps or overlapping segments.
  * Set complete_vg to perform additional VG level checks.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2009-05-13 21:25 mbroz
  0 siblings, 0 replies; 8+ messages in thread
From: mbroz @ 2009-05-13 21:25 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2009-05-13 21:25:02

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: import_export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : lv_manip.c metadata-exported.h 

Log message:
	Introduce link_lv_to_vg and unlink_lv_from_vg functions.
	
	link_lv_to_vg and unlink_lv_from_vg are the only functions
	for adding/removing logical volume from volume group.
	
	Only these function should manipulate with vg->lvs list.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1105&r2=1.1106
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.104&r2=1.105
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/import_export.c.diff?cvsroot=lvm2&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.60&r2=1.61
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.167&r2=1.168
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.68&r2=1.69

--- LVM2/WHATS_NEW	2009/05/13 21:22:57	1.1105
+++ LVM2/WHATS_NEW	2009/05/13 21:25:01	1.1106
@@ -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.
--- LVM2/lib/format1/import-export.c	2009/05/13 21:24:12	1.104
+++ LVM2/lib/format1/import-export.c	2009/05/13 21:25:01	1.105
@@ -455,25 +455,23 @@
 				      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)
--- LVM2/lib/format_pool/import_export.c	2009/05/13 21:22:57	1.26
+++ LVM2/lib/format_pool/import_export.c	2009/05/13 21:25:02	1.27
@@ -57,22 +57,14 @@
 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 @@
 	}
 
 	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,
--- LVM2/lib/format_text/import_vsn1.c	2009/05/13 21:22:57	1.60
+++ LVM2/lib/format_text/import_vsn1.c	2009/05/13 21:25:02	1.61
@@ -495,15 +495,11 @@
 			 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 @@
 		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)),
--- LVM2/lib/metadata/lv_manip.c	2009/05/13 21:22:57	1.167
+++ LVM2/lib/metadata/lv_manip.c	2009/05/13 21:25:02	1.168
@@ -402,7 +402,6 @@
  */
 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 @@
 		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 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 @@
 	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 @@
 	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 @@
 	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)
 {
--- LVM2/lib/metadata/metadata-exported.h	2009/05/13 21:22:57	1.68
+++ LVM2/lib/metadata/metadata-exported.h	2009/05/13 21:25:02	1.69
@@ -368,6 +368,12 @@
 				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);


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2009-05-13 21:22 mbroz
  0 siblings, 0 replies; 8+ messages in thread
From: mbroz @ 2009-05-13 21:22 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2009-05-13 21:21:59

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : metadata-exported.h snapshot_manip.c 
	lib/snapshot   : snapshot.c 
	tools          : lvconvert.c lvcreate.c 

Log message:
	Fix snapshot segment import to not use duplicate segments & replace.
	
	The snapshot segment (snapshotX) is created twice
	during the text metadata segment processing.
	
	This can cause temporary violation of max_lv count.
	
	Simplify the code, snapshot segment is properly initialized
	in init_snapshot_seg function now and do not need to be replaced
	by vg_add_snapshot call.
	
	The vg_add_snapshot() is now usefull only for adding new
	snapshot and it shares the same initialization function.
	
	The snapshot name is always generated, name paramater can be
	removed from function call.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1103&r2=1.1104
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.101&r2=1.102
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.58&r2=1.59
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.66&r2=1.67
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/snapshot_manip.c.diff?cvsroot=lvm2&r1=1.36&r2=1.37
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/snapshot/snapshot.c.diff?cvsroot=lvm2&r1=1.36&r2=1.37
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.72&r2=1.73
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.185&r2=1.186

--- LVM2/WHATS_NEW	2009/05/13 14:13:54	1.1103
+++ LVM2/WHATS_NEW	2009/05/13 21:21:58	1.1104
@@ -1,5 +1,6 @@
 Version 2.02.46 - 
 ================================
+  Fix snapshot segment import to not use duplicate segments & replace.
   Do not query nonexistent devices for readahead.
   Remove NON_BLOCKING lock flag from tools and set a policy to auto-set.
   Remove snapshot_count from VG and use function instead.
--- LVM2/lib/format1/import-export.c	2009/05/12 19:12:09	1.101
+++ LVM2/lib/format1/import-export.c	2009/05/13 21:21:58	1.102
@@ -616,7 +616,7 @@
 				continue;
 
 			/* insert the snapshot */
-			if (!vg_add_snapshot(NULL, org, cow, NULL,
+			if (!vg_add_snapshot(org, cow, NULL,
 					     org->le_count,
 					     lvd->lv_chunk_size)) {
 				log_err("Couldn't add snapshot.");
--- LVM2/lib/format_text/import_vsn1.c	2009/04/10 09:59:19	1.58
+++ LVM2/lib/format_text/import_vsn1.c	2009/05/13 21:21:58	1.59
@@ -603,16 +603,6 @@
 
 	lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
 
-	/*
-	 * FIXME We now have 2 LVs for each snapshot. The real one was
-	 * created by vg_add_snapshot from the segment text_import.
-	 */
-	if (lv->status & SNAPSHOT) {
-		vg->lv_count--;
-		dm_list_del(&lvl->list);
-		return 1;
-	}
-
 	lv->minor = -1;
 	if ((lv->status & FIXED_MINOR) &&
 	    !_read_int32(lvn, "minor", &lv->minor)) {
--- LVM2/lib/metadata/metadata-exported.h	2009/05/12 19:12:09	1.66
+++ LVM2/lib/metadata/metadata-exported.h	2009/05/13 21:21:58	1.67
@@ -545,8 +545,10 @@
 /* Given a cow LV, return its origin */
 struct logical_volume *origin_from_cow(const struct logical_volume *lv);
 
-int vg_add_snapshot(const char *name,
-		    struct logical_volume *origin, struct logical_volume *cow,
+void init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
+		       struct logical_volume *cow, uint32_t chunk_size);
+
+int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
 		    union lvid *lvid, uint32_t extent_count,
 		    uint32_t chunk_size);
 
--- LVM2/lib/metadata/snapshot_manip.c	2009/05/12 19:12:10	1.36
+++ LVM2/lib/metadata/snapshot_manip.c	2009/05/13 21:21:58	1.37
@@ -62,7 +62,31 @@
 	return lv->snapshot->origin;
 }
 
-int vg_add_snapshot(const char *name, struct logical_volume *origin,
+void init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
+		       struct logical_volume *cow, uint32_t chunk_size)
+{
+	seg->chunk_size = chunk_size;
+	seg->origin = origin;
+	seg->cow = cow;
+
+	// FIXME: direct count manipulation to be removed later
+	cow->status &= ~VISIBLE_LV;
+	cow->vg->lv_count--;
+	cow->snapshot = seg;
+
+	origin->origin_count++;
+	origin->vg->lv_count--;
+
+	/* FIXME Assumes an invisible origin belongs to a sparse device */
+	if (!lv_is_visible(origin))
+		origin->status |= VIRTUAL_ORIGIN;
+
+	seg->lv->status |= (SNAPSHOT | VIRTUAL);
+
+	dm_list_add(&origin->snapshot_segs, &seg->origin_list);
+}
+
+int vg_add_snapshot(struct logical_volume *origin,
 		    struct logical_volume *cow, union lvid *lvid,
 		    uint32_t extent_count, uint32_t chunk_size)
 {
@@ -82,39 +106,18 @@
 		return 0;
 	}
 
-	/*
-	 * Set origin lv count in advance to prevent fail because
-	 * of temporary violation of LV limits.
-	 */
-	origin->vg->lv_count--;
-
-	if (!(snap = lv_create_empty(name ? name : "snapshot%d",
+	if (!(snap = lv_create_empty("snapshot%d",
 				     lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
-				     ALLOC_INHERIT, 1, origin->vg))) {
-		origin->vg->lv_count++;
+				     ALLOC_INHERIT, 1, origin->vg)))
 		return_0;
-	}
 
 	snap->le_count = extent_count;
 
 	if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
 		return_0;
 
-	seg->chunk_size = chunk_size;
-	seg->origin = origin;
-	seg->cow = cow;
-	seg->lv->status |= SNAPSHOT;
-
-	origin->origin_count++;
-	cow->snapshot = seg;
-
-	cow->status &= ~VISIBLE_LV;
-
-        /* FIXME Assumes an invisible origin belongs to a sparse device */
-        if (!lv_is_visible(origin))
-                origin->status |= VIRTUAL_ORIGIN;
-
-	dm_list_add(&origin->snapshot_segs, &seg->origin_list);
+	origin->vg->lv_count++;
+	init_snapshot_seg(seg, origin, cow, chunk_size);
 
 	return 1;
 }
--- LVM2/lib/snapshot/snapshot.c	2009/04/02 21:34:41	1.36
+++ LVM2/lib/snapshot/snapshot.c	2009/05/13 21:21:58	1.37
@@ -39,8 +39,6 @@
 	struct logical_volume *org, *cow;
 	int old_suppress;
 
-	seg->lv->status |= SNAPSHOT;
-
 	if (!get_config_uint32(sn, "chunk_size", &chunk_size)) {
 		log_error("Couldn't read chunk size for snapshot.");
 		return 0;
@@ -74,9 +72,7 @@
 		return 0;
 	}
 
-	if (!vg_add_snapshot(seg->lv->name, org, cow,
-			     &seg->lv->lvid, seg->len, chunk_size))
-		return_0;
+	init_snapshot_seg(seg, org, cow, chunk_size);
 
 	return 1;
 }
--- LVM2/tools/lvconvert.c	2009/04/29 20:11:46	1.72
+++ LVM2/tools/lvconvert.c	2009/05/13 21:21:59	1.73
@@ -760,8 +760,7 @@
 		return 0;
 	}
 
-	if (!vg_add_snapshot(NULL, org, lv, NULL, org->le_count,
-			     lp->chunk_size)) {
+	if (!vg_add_snapshot(org, lv, NULL, org->le_count, lp->chunk_size)) {
 		log_error("Couldn't create snapshot.");
 		return 0;
 	}
--- LVM2/tools/lvcreate.c	2009/04/29 20:14:21	1.185
+++ LVM2/tools/lvcreate.c	2009/05/13 21:21:59	1.186
@@ -918,7 +918,7 @@
 
 		/* cow LV remains active and becomes snapshot LV */
 
-		if (!vg_add_snapshot(NULL, org, lv, NULL,
+		if (!vg_add_snapshot(org, lv, NULL,
 				     org->le_count, lp->chunk_size)) {
 			log_error("Couldn't create snapshot.");
 			goto deactivate_and_revert_new_lv;


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2009-05-13 21:22 mbroz
  0 siblings, 0 replies; 8+ messages in thread
From: mbroz @ 2009-05-13 21:22 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2009-05-13 21:22:58

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: format_pool.c import_export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : lv_manip.c metadata-exported.h metadata.c 
	                 snapshot_manip.c 
	tools          : vgchange.c vgmerge.c vgsplit.c 

Log message:
	Remove vg->lv_count and use counter function.
	
	This should not cause problems but simplifies code a lot.
	
	(the volumes_count is merged and renamed with lvs_visible
	function by following patch.)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1104&r2=1.1105
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.102&r2=1.103
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/format_pool.c.diff?cvsroot=lvm2&r1=1.22&r2=1.23
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/import_export.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.59&r2=1.60
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.166&r2=1.167
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.67&r2=1.68
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.216&r2=1.217
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/snapshot_manip.c.diff?cvsroot=lvm2&r1=1.37&r2=1.38
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgchange.c.diff?cvsroot=lvm2&r1=1.69&r2=1.70
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgmerge.c.diff?cvsroot=lvm2&r1=1.53&r2=1.54
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgsplit.c.diff?cvsroot=lvm2&r1=1.72&r2=1.73

--- LVM2/WHATS_NEW	2009/05/13 21:21:58	1.1104
+++ LVM2/WHATS_NEW	2009/05/13 21:22:57	1.1105
@@ -1,5 +1,6 @@
 Version 2.02.46 - 
 ================================
+  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.
   Remove NON_BLOCKING lock flag from tools and set a policy to auto-set.
--- LVM2/lib/format1/import-export.c	2009/05/13 21:21:58	1.102
+++ LVM2/lib/format1/import-export.c	2009/05/13 21:22:57	1.103
@@ -282,7 +282,7 @@
 		vgd->vg_status |= VG_EXTENDABLE;
 
 	vgd->lv_max = vg->max_lv;
-	vgd->lv_cur = vg->lv_count + snapshot_count(vg);
+	vgd->lv_cur = volumes_count(vg) + snapshot_count(vg);
 
 	vgd->pv_max = vg->max_pv;
 	vgd->pv_cur = vg->pv_count;
@@ -469,7 +469,6 @@
 		return_NULL;
 
 	dm_list_add(&vg->lvs, &ll->list);
-	vg->lv_count++;
 
 	return lv;
 }
--- LVM2/lib/format_pool/format_pool.c	2009/05/12 19:12:09	1.22
+++ LVM2/lib/format_pool/format_pool.c	2009/05/13 21:22:57	1.23
@@ -119,7 +119,6 @@
 	vg->status = 0;
 	vg->extent_count = 0;
 	vg->pv_count = 0;
-	vg->lv_count = 0;
 	vg->seqno = 1;
 	vg->system_id = NULL;
 	dm_list_init(&vg->pvs);
--- LVM2/lib/format_pool/import_export.c	2008/11/03 22:14:28	1.25
+++ LVM2/lib/format_pool/import_export.c	2009/05/13 21:22:57	1.26
@@ -49,7 +49,6 @@
 		vg->max_lv = 1;
 		vg->max_pv = POOL_MAX_DEVICES;
 		vg->alloc = ALLOC_NORMAL;
-		vg->lv_count = 0;
 	}
 
 	return 1;
@@ -117,7 +116,6 @@
 	lv->le_count = lv->size / POOL_PE_SIZE;
 	lvl->lv = lv;
 	dm_list_add(&vg->lvs, &lvl->list);
-	vg->lv_count++;
 
 	return 1;
 }
--- LVM2/lib/format_text/import_vsn1.c	2009/05/13 21:21:58	1.59
+++ LVM2/lib/format_text/import_vsn1.c	2009/05/13 21:22:57	1.60
@@ -562,7 +562,6 @@
 	}
 
 	lv->vg = vg;
-	vg->lv_count++;
 	dm_list_add(&vg->lvs, &lvl->list);
 
 	return 1;
--- LVM2/lib/metadata/lv_manip.c	2009/04/21 14:31:58	1.166
+++ LVM2/lib/metadata/lv_manip.c	2009/05/13 21:22:57	1.167
@@ -438,9 +438,6 @@
 			return_0;
 
 		dm_list_del(&lvl->list);
-
-		if (!(lv->status & SNAPSHOT))
-			lv->vg->lv_count--;
 	} else if (lv->vg->fid->fmt->ops->lv_setup &&
 		   !lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv))
 		return_0;
@@ -1827,7 +1824,7 @@
 	struct logical_volume *lv;
 	char dname[NAME_LEN];
 
-	if (vg->max_lv && (vg->max_lv == vg->lv_count)) {
+	if (vg->max_lv && (vg->max_lv == volumes_count(vg))) {
 		log_error("Maximum number of logical volumes (%u) reached "
 			  "in volume group %s", vg->max_lv, vg->name);
 		return NULL;
@@ -1883,9 +1880,6 @@
 		return_NULL;
 	}
 
-	if (!import)
-		vg->lv_count++;
-
 	dm_list_add(&vg->lvs, &ll->list);
 
 	return lv;
--- LVM2/lib/metadata/metadata-exported.h	2009/05/13 21:21:58	1.67
+++ LVM2/lib/metadata/metadata-exported.h	2009/05/13 21:22:57	1.68
@@ -251,7 +251,6 @@
 	 * - one for the user-visible mirror LV
 	 * all of the instances are reflected in lv_count.
 	 */
-	uint32_t lv_count;
 	struct dm_list lvs;
 
 	struct dm_list tags;
@@ -556,6 +555,8 @@
 
 int vg_check_status(const struct volume_group *vg, uint32_t status);
 
+unsigned volumes_count(const struct volume_group *vg);
+
 /*
 * Mirroring functions
 */
--- LVM2/lib/metadata/metadata.c	2009/05/13 01:48:18	1.216
+++ LVM2/lib/metadata/metadata.c	2009/05/13 21:22:57	1.217
@@ -571,7 +571,6 @@
 	vg->pv_count = 0;
 	dm_list_init(&vg->pvs);
 
-	vg->lv_count = 0;
 	dm_list_init(&vg->lvs);
 
 	dm_list_init(&vg->tags);
@@ -1165,6 +1164,22 @@
 	return num_snapshots;
 }
 
+unsigned volumes_count(const struct volume_group *vg)
+{
+	struct lv_list *lvl;
+	unsigned lv_count = 0;
+
+	dm_list_iterate_items(lvl, &vg->lvs) {
+		if (lv_is_cow(lvl->lv))
+			continue;
+		if (lvl->lv->status & SNAPSHOT)
+			continue;
+		lv_count++;
+	}
+
+	return lv_count;
+}
+
 /*
  * Determine whether two vgs are compatible for merging.
  */
@@ -1199,7 +1214,7 @@
 	}
 
 	if (vg_to->max_lv &&
-	    (vg_to->max_lv < vg_to->lv_count + vg_from->lv_count)) {
+	    (vg_to->max_lv < volumes_count(vg_to) + volumes_count(vg_from))) {
 		log_error("Maximum number of logical volumes (%d) exceeded "
 			  " for \"%s\" and \"%s\"", vg_to->max_lv, vg_to->name,
 			  vg_from->name);
@@ -1455,10 +1470,10 @@
 	}
 
 	if ((lv_count = (uint32_t) dm_list_size(&vg->lvs)) !=
-	    vg->lv_count + 2 * snapshot_count(vg)) {
+	    volumes_count(vg) + 2 * snapshot_count(vg)) {
 		log_error("Internal error: #internal LVs (%u) != #LVs (%"
 			  PRIu32 ") + 2 * #snapshots (%" PRIu32 ") in VG %s",
-			  dm_list_size(&vg->lvs), vg->lv_count,
+			  dm_list_size(&vg->lvs), volumes_count(vg),
 			  snapshot_count(vg), vg->name);
 		r = 0;
 	}
@@ -1502,10 +1517,10 @@
 		r = 0;
 	}
 
-	if (vg->max_lv && (vg->max_lv < vg->lv_count)) {
+	if (vg->max_lv && (vg->max_lv < volumes_count(vg))) {
 		log_error("Internal error: Volume group %s contains %u volumes"
 			  " but the limit is set to %u.",
-			  vg->name, vg->lv_count, vg->max_lv);
+			  vg->name, volumes_count(vg), vg->max_lv);
 		r = 0;
 	}
 
--- LVM2/lib/metadata/snapshot_manip.c	2009/05/13 21:21:58	1.37
+++ LVM2/lib/metadata/snapshot_manip.c	2009/05/13 21:22:57	1.38
@@ -69,13 +69,10 @@
 	seg->origin = origin;
 	seg->cow = cow;
 
-	// FIXME: direct count manipulation to be removed later
 	cow->status &= ~VISIBLE_LV;
-	cow->vg->lv_count--;
 	cow->snapshot = seg;
 
 	origin->origin_count++;
-	origin->vg->lv_count--;
 
 	/* FIXME Assumes an invisible origin belongs to a sparse device */
 	if (!lv_is_visible(origin))
@@ -116,7 +113,6 @@
 	if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
 		return_0;
 
-	origin->vg->lv_count++;
 	init_snapshot_seg(seg, origin, cow, chunk_size);
 
 	return 1;
@@ -134,8 +130,6 @@
 	}
 
 	cow->snapshot = NULL;
-
-	cow->vg->lv_count++;
 	cow->status |= VISIBLE_LV;
 
 	return 1;
--- LVM2/tools/vgchange.c	2009/04/10 10:01:38	1.69
+++ LVM2/tools/vgchange.c	2009/05/13 21:22:57	1.70
@@ -308,9 +308,9 @@
 		}
 	}
 
-	if (max_lv && max_lv < vg->lv_count) {
+	if (max_lv && max_lv < volumes_count(vg)) {
 		log_error("MaxLogicalVolume is less than the current number "
-			  "%d of LVs for \"%s\"", vg->lv_count,
+			  "%d of LVs for %s", volumes_count(vg),
 			  vg->name);
 		return ECMD_FAILED;
 	}
--- LVM2/tools/vgmerge.c	2009/05/13 13:02:56	1.53
+++ LVM2/tools/vgmerge.c	2009/05/13 21:22:57	1.54
@@ -101,7 +101,6 @@
 		dm_list_move(&vg_to->fid->metadata_areas, mdah);
 	}
 
-	vg_to->lv_count += vg_from->lv_count;
 	vg_to->extent_count += vg_from->extent_count;
 	vg_to->free_count += vg_from->free_count;
 
--- LVM2/tools/vgsplit.c	2009/05/13 13:02:56	1.72
+++ LVM2/tools/vgsplit.c	2009/05/13 21:22:57	1.73
@@ -106,12 +106,8 @@
 		return 0;
 	}
 
-	if (!(lv->status & SNAPSHOT) && !lv_is_cow(lv)) {
-		vg_from->lv_count--;
-		vg_to->lv_count++;
-	}
 	return 1;
-}	
+}
 
 static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
 {


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2009-05-12 19:12 mbroz
  0 siblings, 0 replies; 8+ messages in thread
From: mbroz @ 2009-05-12 19:12 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2009-05-12 19:12:10

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: format_pool.c 
	lib/metadata   : metadata-exported.h metadata.c metadata.h 
	                 snapshot_manip.c 
	lib/report     : columns.h report.c 
	tools          : vgmerge.c vgsplit.c 

Log message:
	Remove snapshot_count from VG and use function instead.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1100&r2=1.1101
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.100&r2=1.101
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/format_pool.c.diff?cvsroot=lvm2&r1=1.21&r2=1.22
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.65&r2=1.66
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.214&r2=1.215
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.192&r2=1.193
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/snapshot_manip.c.diff?cvsroot=lvm2&r1=1.35&r2=1.36
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/columns.h.diff?cvsroot=lvm2&r1=1.35&r2=1.36
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.97&r2=1.98
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgmerge.c.diff?cvsroot=lvm2&r1=1.51&r2=1.52
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgsplit.c.diff?cvsroot=lvm2&r1=1.70&r2=1.71

--- LVM2/WHATS_NEW	2009/05/12 19:09:21	1.1100
+++ LVM2/WHATS_NEW	2009/05/12 19:12:09	1.1101
@@ -1,5 +1,6 @@
 Version 2.02.46 - 
 ================================
+  Remove snapshot_count from VG and use function instead.
   Fix first_seg() call for empty segment list.
   Add make install_lvm2 as complement to device-mapper install.
   Reject missing PVs from allocation in toollib.
--- LVM2/lib/format1/import-export.c	2008/11/03 22:14:28	1.100
+++ LVM2/lib/format1/import-export.c	2009/05/12 19:12:09	1.101
@@ -282,7 +282,7 @@
 		vgd->vg_status |= VG_EXTENDABLE;
 
 	vgd->lv_max = vg->max_lv;
-	vgd->lv_cur = vg->lv_count + vg->snapshot_count;
+	vgd->lv_cur = vg->lv_count + snapshot_count(vg);
 
 	vgd->pv_max = vg->max_pv;
 	vgd->pv_cur = vg->pv_count;
--- LVM2/lib/format_pool/format_pool.c	2009/04/10 09:59:18	1.21
+++ LVM2/lib/format_pool/format_pool.c	2009/05/12 19:12:09	1.22
@@ -120,7 +120,6 @@
 	vg->extent_count = 0;
 	vg->pv_count = 0;
 	vg->lv_count = 0;
-	vg->snapshot_count = 0;
 	vg->seqno = 1;
 	vg->system_id = NULL;
 	dm_list_init(&vg->pvs);
--- LVM2/lib/metadata/metadata-exported.h	2009/04/25 01:17:59	1.65
+++ LVM2/lib/metadata/metadata-exported.h	2009/05/12 19:12:09	1.66
@@ -243,8 +243,7 @@
 	 * Snapshots consist of 2 instances of "struct logical_volume":
 	 * - cow (lv_name is visible to the user)
 	 * - snapshot (lv_name is 'snapshotN')
-	 * Neither of these instances is reflected in lv_count, but we
-	 * multiply the snapshot_count by 2.
+	 * Neither of these instances is reflected in lv_count.
 	 *
 	 * Mirrors consist of multiple instances of "struct logical_volume":
 	 * - one for the mirror log
@@ -253,7 +252,6 @@
 	 * all of the instances are reflected in lv_count.
 	 */
 	uint32_t lv_count;
-	uint32_t snapshot_count;
 	struct dm_list lvs;
 
 	struct dm_list tags;
--- LVM2/lib/metadata/metadata.c	2009/05/12 19:09:21	1.214
+++ LVM2/lib/metadata/metadata.c	2009/05/12 19:12:09	1.215
@@ -574,8 +574,6 @@
 	vg->lv_count = 0;
 	dm_list_init(&vg->lvs);
 
-	vg->snapshot_count = 0;
-
 	dm_list_init(&vg->tags);
 
 	if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name,
@@ -1155,6 +1153,18 @@
 	return lv_count;
 }
 
+unsigned snapshot_count(const struct volume_group *vg)
+{
+	struct lv_list *lvl;
+	unsigned lv_count = 0;
+
+	dm_list_iterate_items(lvl, &vg->lvs)
+		if (lv_is_cow(lvl->lv))
+			lv_count++;
+
+	return lv_count;
+}
+
 /*
  * Determine whether two vgs are compatible for merging.
  */
@@ -1445,11 +1455,11 @@
 	}
 
 	if ((lv_count = (uint32_t) dm_list_size(&vg->lvs)) !=
-	    vg->lv_count + 2 * vg->snapshot_count) {
+	    vg->lv_count + 2 * snapshot_count(vg)) {
 		log_error("Internal error: #internal LVs (%u) != #LVs (%"
 			  PRIu32 ") + 2 * #snapshots (%" PRIu32 ") in VG %s",
 			  dm_list_size(&vg->lvs), vg->lv_count,
-			  vg->snapshot_count, vg->name);
+			  snapshot_count(vg), vg->name);
 		r = 0;
 	}
 
--- LVM2/lib/metadata/metadata.h	2009/04/25 01:18:00	1.192
+++ LVM2/lib/metadata/metadata.h	2009/05/12 19:12:10	1.193
@@ -345,6 +345,11 @@
 unsigned displayable_lvs_in_vg(const struct volume_group *vg);
 
 /*
+ * Count snapshot LVs.
+ */
+unsigned snapshot_count(const struct volume_group *vg);
+
+/*
  * For internal metadata caching.
  */
 int export_vg_to_buffer(struct volume_group *vg, char **buf);
--- LVM2/lib/metadata/snapshot_manip.c	2009/04/25 01:18:00	1.35
+++ LVM2/lib/metadata/snapshot_manip.c	2009/05/12 19:12:10	1.36
@@ -106,7 +106,6 @@
 	seg->lv->status |= SNAPSHOT;
 
 	origin->origin_count++;
-	origin->vg->snapshot_count++;
 	cow->snapshot = seg;
 
 	cow->status &= ~VISIBLE_LV;
@@ -133,7 +132,6 @@
 
 	cow->snapshot = NULL;
 
-	cow->vg->snapshot_count--;
 	cow->vg->lv_count++;
 	cow->status |= VISIBLE_LV;
 
--- LVM2/lib/report/columns.h	2009/05/06 15:25:23	1.35
+++ LVM2/lib/report/columns.h	2009/05/12 19:12:10	1.36
@@ -108,7 +108,7 @@
 FIELD(VGS, vg, NUM, "MaxPV", max_pv, 5, uint32, "max_pv", "Maximum number of PVs allowed in VG or 0 if unlimited.")
 FIELD(VGS, vg, NUM, "#PV", pv_count, 3, uint32, "pv_count", "Number of PVs.")
 FIELD(VGS, vg, NUM, "#LV", cmd, 3, lvcount, "lv_count", "Number of LVs.")
-FIELD(VGS, vg, NUM, "#SN", snapshot_count, 3, uint32, "snap_count", "Number of snapshots.")
+FIELD(VGS, vg, NUM, "#SN", cmd, 3, snapcount, "snap_count", "Number of snapshots.")
 FIELD(VGS, vg, NUM, "Seq", seqno, 3, uint32, "vg_seqno", "Revision number of internal metadata.  Incremented whenever it changes.")
 FIELD(VGS, vg, STR, "VG Tags", tags, 7, tags, "vg_tags", "Tags, if any.")
 FIELD(VGS, vg, NUM, "#VMda", cmd, 5, vgmdas, "vg_mda_count", "Number of metadata areas in use by this VG.")
--- LVM2/lib/report/report.c	2009/04/25 01:18:00	1.97
+++ LVM2/lib/report/report.c	2009/05/12 19:12:10	1.98
@@ -991,6 +991,18 @@
 	return _uint32_disp(rh, mem, field, &count, private);
 }
 
+static int _snapcount_disp(struct dm_report *rh, struct dm_pool *mem,
+			   struct dm_report_field *field,
+			   const void *data, void *private)
+{
+	const struct volume_group *vg = (const struct volume_group *) data;
+	uint32_t count;
+
+	count = snapshot_count(vg);
+
+	return _uint32_disp(rh, mem, field, &count, private);
+}
+
 static int _snpercent_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
 			   struct dm_report_field *field,
 			   const void *data, void *private __attribute((unused)))
--- LVM2/tools/vgmerge.c	2009/04/10 10:01:39	1.51
+++ LVM2/tools/vgmerge.c	2009/05/12 19:12:10	1.52
@@ -102,8 +102,6 @@
 	}
 
 	vg_to->lv_count += vg_from->lv_count;
-	vg_to->snapshot_count += vg_from->snapshot_count;
-
 	vg_to->extent_count += vg_from->extent_count;
 	vg_to->free_count += vg_from->free_count;
 
--- LVM2/tools/vgsplit.c	2009/04/10 10:01:39	1.70
+++ LVM2/tools/vgsplit.c	2009/05/12 19:12:10	1.71
@@ -106,10 +106,7 @@
 		return 0;
 	}
 
-	if (lv->status & SNAPSHOT) {
-		vg_from->snapshot_count--;
-		vg_to->snapshot_count++;
-	} else if (!lv_is_cow(lv)) {
+	if (!(lv->status & SNAPSHOT) && !lv_is_cow(lv)) {
 		vg_from->lv_count--;
 		vg_to->lv_count++;
 	}


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2008-01-16 19:01 agk
  0 siblings, 0 replies; 8+ messages in thread
From: agk @ 2008-01-16 19:01 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2008-01-16 19:01:00

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: import_export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : lv_alloc.h lv_manip.c merge.c 
	                 metadata-exported.h metadata.h mirror.c 
	lib/report     : report.c 
	tools          : vgreduce.c 

Log message:
	Maintain lists of stacked LV segments using each LV.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.763&r2=1.764
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.91&r2=1.92
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/import_export.c.diff?cvsroot=lvm2&r1=1.18&r2=1.19
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.46&r2=1.47
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_alloc.h.diff?cvsroot=lvm2&r1=1.20&r2=1.21
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.140&r2=1.141
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/merge.c.diff?cvsroot=lvm2&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.34&r2=1.35
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.176&r2=1.177
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.52&r2=1.53
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.71&r2=1.72
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgreduce.c.diff?cvsroot=lvm2&r1=1.72&r2=1.73

--- LVM2/WHATS_NEW	2008/01/16 18:15:26	1.763
+++ LVM2/WHATS_NEW	2008/01/16 19:00:58	1.764
@@ -1,5 +1,7 @@
 Version 2.02.30 -
 ===================================
+  Maintain lists of stacked LV segments using each LV.
+  Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes.
   Fix process_all_pvs to detect non-orphans with no MDAs correctly.
   Don't use block_on_error with mirror targets version 1.12 and above.
   Update vgsplit to include vgcreate-style options when new VG is destination.
--- LVM2/lib/format1/import-export.c	2007/11/09 16:51:53	1.91
+++ LVM2/lib/format1/import-export.c	2008/01/16 19:00:59	1.92
@@ -361,6 +361,7 @@
 	list_init(&lv->snapshot_segs);
 	list_init(&lv->segments);
 	list_init(&lv->tags);
+	list_init(&lv->segs_using_this_lv);
 
 	return 1;
 }
--- LVM2/lib/format_pool/import_export.c	2007/11/09 16:51:53	1.18
+++ LVM2/lib/format_pool/import_export.c	2008/01/16 19:00:59	1.19
@@ -83,6 +83,7 @@
 	list_init(&lv->snapshot_segs);
 	list_init(&lv->segments);
 	list_init(&lv->tags);
+	list_init(&lv->segs_using_this_lv);
 
 	list_iterate_items(pl, pls) {
 		lv->size += pl->pd.pl_blocks;
--- LVM2/lib/format_text/import_vsn1.c	2008/01/10 18:35:50	1.46
+++ LVM2/lib/format_text/import_vsn1.c	2008/01/16 19:00:59	1.47
@@ -408,8 +408,10 @@
 				return 0;
 			}
 		} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
-			set_lv_segment_area_lv(seg, s, lv1, (uint32_t) cv->next->v.i,
-					       flags);
+			if (!set_lv_segment_area_lv(seg, s, lv1,
+						    (uint32_t) cv->next->v.i,
+						    flags))
+				return_0;
 		} else {
 			log_error("Couldn't find volume '%s' "
 				  "for segment '%s'.",
@@ -562,6 +564,7 @@
 	list_init(&lv->snapshot_segs);
 	list_init(&lv->segments);
 	list_init(&lv->tags);
+	list_init(&lv->segs_using_this_lv);
 
 	/* Optional tags */
 	if ((cn = find_config_node(lvn, "tags")) &&
--- LVM2/lib/metadata/lv_alloc.h	2007/12/20 15:42:55	1.20
+++ LVM2/lib/metadata/lv_alloc.h	2008/01/16 19:00:59	1.21
@@ -33,9 +33,9 @@
 
 int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
 			   struct physical_volume *pv, uint32_t pe);
-void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
-			    struct logical_volume *lv, uint32_t le,
-			    uint32_t flags);
+int set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
+			   struct logical_volume *lv, uint32_t le,
+			   uint32_t flags);
 int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
 			 struct lv_segment *seg_from, uint32_t area_from);
 void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
--- LVM2/lib/metadata/lv_manip.c	2007/12/20 23:12:27	1.140
+++ LVM2/lib/metadata/lv_manip.c	2008/01/16 19:00:59	1.141
@@ -31,6 +31,69 @@
 	const char *new;
 };
 
+int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg)
+{
+	struct seg_list *sl;
+
+	list_iterate_items(sl, &lv->segs_using_this_lv) {
+		if (sl->seg == seg) {
+			sl->count++;
+			return 1;
+		}
+	}
+
+	if (!(sl = dm_pool_zalloc(lv->vg->cmd->mem, sizeof(*sl)))) {
+		log_error("Failed to allocate segment list");
+		return 0;
+	}
+
+	sl->count = 1;
+	sl->seg = seg;
+	list_add(&lv->segs_using_this_lv, &sl->list);
+
+	return 1;
+}
+
+int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg)
+{
+	struct seg_list *sl;
+
+	list_iterate_items(sl, &lv->segs_using_this_lv) {
+		if (sl->seg != seg)
+			continue;
+		if (sl->count > 1)
+			sl->count--;
+		else
+			list_del(&sl->list);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * This is a function specialized for the common case where there is
+ * only one segment which uses the LV.
+ * e.g. the LV is a layer inserted by insert_layer_for_lv().
+ *
+ * In general, walk through lv->segs_using_this_lv.
+ */
+struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv)
+{
+	struct seg_list *sl;
+
+	if (list_size(&lv->segs_using_this_lv) != 1) {
+		log_error("%s is expected to have only one segment using it, "
+			  "while it has %d", lv->name,
+			  list_size(&lv->segs_using_this_lv));
+		return NULL;
+	}
+
+	sl = list_item(list_first(&lv->segs_using_this_lv), struct seg_list);
+
+	return sl->seg;
+}
+
 /*
  * PVs used by a segment of an LV
  */
@@ -127,12 +190,12 @@
 	seg->region_size = region_size;
 	seg->extents_copied = extents_copied;
 	seg->log_lv = log_lv;
-	seg->mirror_seg = NULL;
 	list_init(&seg->tags);
 
 	if (log_lv) {
 		log_lv->status |= MIRROR_LOG;
-		first_seg(log_lv)->mirror_seg = seg;
+		if (!add_seg_to_segs_using_this_lv(log_lv, seg))
+			return_NULL;
 	}
 
 	return seg;
@@ -183,6 +246,7 @@
 	}
 
 	if (area_reduction == seg->area_len) {
+		remove_seg_from_segs_using_this_lv(seg_lv(seg, s), seg);
 		seg_lv(seg, s) = NULL;
 		seg_le(seg, s) = 0;
 		seg_type(seg, s) = AREA_UNASSIGNED;
@@ -223,7 +287,8 @@
 					seg_from->area_len);
 		release_lv_segment_area(seg_to, area_to, seg_to->area_len);
 
-		set_lv_segment_area_lv(seg_to, area_to, lv, le, 0);
+		if (!set_lv_segment_area_lv(seg_to, area_to, lv, le, 0))
+			return_0;
 
 		break;
 
@@ -254,14 +319,19 @@
 /*
  * Link one LV segment to another.  Assumes sizes already match.
  */
-void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
-			    struct logical_volume *lv, uint32_t le,
-			    uint32_t flags)
+int set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
+			   struct logical_volume *lv, uint32_t le,
+			   uint32_t flags)
 {
 	seg->areas[area_num].type = AREA_LV;
 	seg_lv(seg, area_num) = lv;
 	seg_le(seg, area_num) = le;
 	lv->status |= flags;
+
+	if (!add_seg_to_segs_using_this_lv(lv, seg))
+		return_0;
+
+	return 1;
 }
 
 /*
@@ -1399,14 +1469,13 @@
 		return 0;
 	}
 
-	for (m = 0; m < old_area_count; m++) {
+	for (m = 0; m < old_area_count; m++)
 		seg_lv(seg, m)->status |= status;
-		first_seg(seg_lv(seg, m))->mirror_seg = seg;
-	}
 
 	for (m = old_area_count; m < new_area_count; m++) {
-		set_lv_segment_area_lv(seg, m, sub_lvs[m - old_area_count], 0, status);
-		first_seg(sub_lvs[m - old_area_count])->mirror_seg = seg;
+		if (!set_lv_segment_area_lv(seg, m, sub_lvs[m - old_area_count],
+					    0, status))
+			return_0;
 		sub_lvs[m - old_area_count]->status &= ~VISIBLE_LV;
 	}
 
@@ -1780,6 +1849,7 @@
 	list_init(&lv->snapshot_segs);
 	list_init(&lv->segments);
 	list_init(&lv->tags);
+	list_init(&lv->segs_using_this_lv);
 
 	if (lvid)
 		lv->lvid = *lvid;
@@ -2212,53 +2282,29 @@
 	return 1;
 }
 
-/*
- * Find a parent LV for the layer_lv in the lv
- */
-struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
-                                            struct logical_volume *layer_lv)
-{
-	struct logical_volume *parent;
-	struct lv_segment *seg;
-	uint32_t s;
-
-	list_iterate_items(seg, &lv->segments) {
-		for (s = 0; s < seg->area_count; s++) {
-			if (seg_type(seg, s) != AREA_LV)
-				continue;
-			if (seg_lv(seg, s) == layer_lv)
-				return lv;
-			parent = find_parent_for_layer(seg_lv(seg, s),
-						       layer_lv);
-			if (parent)
-				return parent;
-		}
-	}
-	return NULL;
-}
-
 /* Remove a layer from the LV */
 int remove_layer_from_lv(struct logical_volume *lv,
 			 struct logical_volume *layer_lv)
 {
 	struct logical_volume *parent;
+	struct lv_segment *parent_seg;
 	struct segment_type *segtype;
 
-	parent = find_parent_for_layer(lv, layer_lv);
-	if (!parent) {
+	if (!(parent_seg = get_only_segment_using_this_lv(layer_lv))) {
 		log_error("Failed to find layer %s in %s",
 		layer_lv->name, lv->name);
 		return 0;
 	}
+	parent = parent_seg->lv;
 
 	/*
 	 * Before removal, the layer should be cleaned up,
 	 * i.e. additional segments and areas should have been removed.
 	 */
 	if (list_size(&parent->segments) != 1 ||
-	    first_seg(parent)->area_count != 1 ||
-	    seg_type(first_seg(parent), 0) != AREA_LV ||
-	    layer_lv != seg_lv(first_seg(parent), 0) ||
+	    parent_seg->area_count != 1 ||
+	    seg_type(parent_seg, 0) != AREA_LV ||
+	    layer_lv != seg_lv(parent_seg, 0) ||
 	    parent->le_count != layer_lv->le_count)
 		return_0;
 
@@ -2328,7 +2374,8 @@
 		return_NULL;
 
 	/* map the new segment to the original underlying are */
-	set_lv_segment_area_lv(mapseg, 0, layer_lv, 0, 0);
+	if (!set_lv_segment_area_lv(mapseg, 0, layer_lv, 0, 0))
+		return_NULL;
 
 	/* add the new segment to the layer LV */
 	list_add(&lv_where->segments, &mapseg->list);
@@ -2379,7 +2426,8 @@
 	layer_lv->size += seg->area_len * layer_lv->vg->extent_size;
 
 	/* map the original area to the new segment */
-	set_lv_segment_area_lv(seg, s, layer_lv, mapseg->le, 0);
+	if (!set_lv_segment_area_lv(seg, s, layer_lv, mapseg->le, 0))
+		return_0;
 
 	return 1;
 }
--- LVM2/lib/metadata/merge.c	2007/11/07 16:33:11	1.30
+++ LVM2/lib/metadata/merge.c	2008/01/16 19:00:59	1.31
@@ -62,9 +62,10 @@
 {
 	struct lv_segment *seg, *seg2;
 	uint32_t le = 0;
-	unsigned seg_count = 0;
+	unsigned seg_count = 0, seg_found;
 	int r = 1;
 	uint32_t area_multiplier, s;
+	struct seg_list *sl;
 
 	list_iterate_items(seg, &lv->segments) {
 		seg_count++;
@@ -101,7 +102,7 @@
 			}
 
 			if (!(seg2 = first_seg(seg->log_lv)) ||
-			    seg2->mirror_seg != seg) {
+			    find_mirror_seg(seg2) != seg) {
 				log_error("LV %s: segment %u log LV does not "
 					  "point back to mirror segment",
 					   lv->name, seg_count);
@@ -110,8 +111,8 @@
 		}
 
 		if (complete_vg && seg->status & MIRROR_IMAGE) {
-			if (!seg->mirror_seg ||
-			    !seg_is_mirrored(seg->mirror_seg)) {
+			if (!find_mirror_seg(seg) ||
+			    !seg_is_mirrored(find_mirror_seg(seg))) {
 				log_error("LV %s: segment %u mirror image "
 					  "is not mirrored",
 					  lv->name, seg_count);
@@ -157,7 +158,7 @@
 				    (seg_lv(seg, s)->status & MIRROR_IMAGE) &&
 				    (!(seg2 = find_seg_by_le(seg_lv(seg, s),
 							    seg_le(seg, s))) ||
-				     seg2->mirror_seg != seg)) {
+				     find_mirror_seg(seg2) != seg)) {
 					log_error("LV %s: segment %u mirror "
 						  "image %u missing mirror ptr",
 						  lv->name, seg_count, s);
@@ -173,12 +174,57 @@
 					r = 0;
 				}
  */
+				seg_found = 0;
+				list_iterate_items(sl, &seg_lv(seg, s)->segs_using_this_lv)
+					if (sl->seg == seg)
+						seg_found++;
+				if (!seg_found) {
+					log_error("LV %s segment %d uses LV %s,"
+						  " but missing ptr from %s to %s",
+						  lv->name, seg_count,
+						  seg_lv(seg, s)->name,
+						  seg_lv(seg, s)->name, lv->name);
+					r = 0;
+				} else if (seg_found > 1) {
+					log_error("LV %s has duplicated links "
+						  "to LV %s segment %d",
+						  seg_lv(seg, s)->name,
+						  lv->name, seg_count);
+					r = 0;
+				}
 			}
 		}
 
 		le += seg->len;
 	}
 
+	list_iterate_items(sl, &lv->segs_using_this_lv) {
+		seg = sl->seg;
+		seg_found = 0;
+		for (s = 0; s < seg->area_count; s++) {
+			if (seg_type(seg, s) != AREA_LV)
+				continue;
+			if (lv == seg_lv(seg, s))
+				seg_found++;
+		}
+		if (seg->log_lv == lv)
+			seg_found++;
+		if (!seg_found) {
+			log_error("LV %s is used by LV %s:%" PRIu32 ", "
+				  "but missing ptr from %s to %s",
+				  lv->name, seg->lv->name, seg->le,
+				  seg->lv->name, lv->name);
+			r = 0;
+		} else if (seg_found != sl->count) {
+			log_error("Reference count mismatch: LV %s has %d "
+				  "links to LV %s:%" PRIu32
+				  ", which has %d links",
+				  lv->name, sl->count,
+				  seg->lv->name, seg->le, seg_found);
+			r = 0;
+		}
+	}
+
 	if (le != lv->le_count) {
 		log_error("LV %s: inconsistent LE count %u != %u",
 			  lv->name, le, lv->le_count);
@@ -243,9 +289,9 @@
 		/* Split area at the offset */
 		switch (seg_type(seg, s)) {
 		case AREA_LV:
-			seg_lv(split_seg, s) = seg_lv(seg, s);
-			seg_le(split_seg, s) =
-			    seg_le(seg, s) + seg->area_len;
+			if (!set_lv_segment_area_lv(split_seg, s, seg_lv(seg, s),
+						    seg_le(seg, s) + seg->area_len, 0))
+				return_0;
 			log_debug("Split %s:%u[%u] at %u: %s LE %u", lv->name,
 				  seg->le, s, le, seg_lv(seg, s)->name,
 				  seg_le(split_seg, s));
--- LVM2/lib/metadata/metadata-exported.h	2008/01/16 18:15:26	1.34
+++ LVM2/lib/metadata/metadata-exported.h	2008/01/16 19:00:59	1.35
@@ -242,7 +242,6 @@
 	uint32_t region_size;	/* For mirrors - in sectors */
 	uint32_t extents_copied;
 	struct logical_volume *log_lv;
-	struct lv_segment *mirror_seg;
 
 	struct list tags;
 
@@ -274,6 +273,7 @@
 
 	struct list segments;
 	struct list tags;
+	struct list segs_using_this_lv;
 };
 
 struct pe_range {
@@ -412,8 +412,6 @@
 				   struct list *lvs_changed);
 int split_parent_segments_for_layer(struct cmd_context *cmd,
 				    struct logical_volume *layer_lv);
-struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
-					     struct logical_volume *layer_lv);
 int remove_layer_from_lv(struct logical_volume *lv,
 			 struct logical_volume *layer_lv);
 struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
@@ -464,6 +462,7 @@
 /*
 * Mirroring functions
 */
+struct lv_segment *find_mirror_seg(struct lv_segment *seg);
 int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
 		   uint32_t mirrors, uint32_t stripes,
 		   uint32_t region_size, uint32_t log_count,
--- LVM2/lib/metadata/metadata.h	2007/12/20 18:55:46	1.176
+++ LVM2/lib/metadata/metadata.h	2008/01/16 19:00:59	1.177
@@ -158,6 +158,12 @@
 	struct pv_segment *peg;
 };
 
+struct seg_list {
+	struct list list;
+	unsigned count;
+	struct lv_segment *seg;
+};
+
 /*
  * Ownership of objects passes to caller.
  */
@@ -293,13 +299,20 @@
 int lv_split_segment(struct logical_volume *lv, uint32_t le);
 
 /*
+ * Add/remove upward link from underlying LV to the segment using it
+ * FIXME: ridiculously long name
+ */
+int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
+int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
+struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
+
+/*
  * Mirroring functions
  */
 
 /*
  * Given mirror image or mirror log segment, find corresponding mirror segment 
  */
-struct lv_segment *find_mirror_seg(struct lv_segment *seg);
 int fixup_imported_mirrors(struct volume_group *vg);
 
 /*
--- LVM2/lib/metadata/mirror.c	2008/01/10 18:35:50	1.52
+++ LVM2/lib/metadata/mirror.c	2008/01/16 19:00:59	1.53
@@ -76,7 +76,22 @@
 
 struct lv_segment *find_mirror_seg(struct lv_segment *seg)
 {
-	return seg->mirror_seg;
+	struct lv_segment *mirror_seg;
+
+	mirror_seg = get_only_segment_using_this_lv(seg->lv);
+
+	if (!mirror_seg) {
+		log_error("Failed to find mirror_seg for %s", seg->lv->name);
+		return NULL;
+	}
+
+	if (!seg_is_mirrored(mirror_seg)) {
+		log_error("%s on %s is not a mirror segments",
+			  mirror_seg->lv->name, seg->lv->name);
+		return NULL;
+	}
+
+	return mirror_seg;
 }
 
 /*
@@ -155,6 +170,20 @@
 				 MIRROR_IMAGE, first_seg(lv)->region_size);
 }
 
+/* Unlink the relationship between the segment and its log_lv */
+static void _remove_mirror_log(struct lv_segment *mirrored_seg)
+{
+	struct logical_volume *log_lv;
+
+	if (!mirrored_seg->log_lv)
+		return;
+
+	log_lv = mirrored_seg->log_lv;
+	mirrored_seg->log_lv = NULL;
+	log_lv->status &= ~MIRROR_LOG;
+	remove_seg_from_segs_using_this_lv(log_lv, mirrored_seg);
+}
+
 /*
  * Remove num_removed images from mirrored_seg
  */
@@ -244,6 +273,7 @@
 		}
 		lvl->lv = seg_lv(mirrored_seg, m);
 		list_add(&tmp_orphan_lvs, &lvl->list);
+		release_lv_segment_area(mirrored_seg, m, mirrored_seg->area_len);
 	}
 	mirrored_seg->area_count = new_area_count;
 
@@ -254,7 +284,7 @@
 	/* If no more mirrors, remove mirror layer */
 	if (new_area_count == 1) {
 		lv1 = seg_lv(mirrored_seg, 0);
-		mirrored_seg->log_lv = NULL;
+		_remove_mirror_log(mirrored_seg);
 		if (!remove_layer_from_lv(lv, lv1))
 			return_0;
 		lv->status &= ~MIRRORED;
@@ -265,12 +295,10 @@
 			return 0;
 		}
 	} else if (remove_log)
-		mirrored_seg->log_lv = NULL;
+		_remove_mirror_log(mirrored_seg);
 
-	if (remove_log && log_lv) {
-		log_lv->status &= ~MIRROR_LOG;
+	if (remove_log && log_lv)
 		log_lv->status |= VISIBLE_LV;
-	}
 
 	/*
 	 * To successfully remove these unwanted LVs we need to
@@ -395,18 +423,25 @@
  */
 int collapse_mirrored_lv(struct logical_volume *lv)
 {
-	struct logical_volume *tmp_lv, *parent_lv;
+	struct logical_volume *tmp_lv;
+	struct lv_segment *mirror_seg;
 
 	while ((tmp_lv = _find_tmp_mirror(lv))) {
-		parent_lv = find_parent_for_layer(lv, tmp_lv);
-		if (!_mirrored_lv_in_sync(parent_lv)) {
+		mirror_seg = find_mirror_seg(first_seg(tmp_lv));
+		if (!mirror_seg) {
+			log_error("Failed to find mirrored LV for %s",
+				  tmp_lv->name);
+			return 0;
+		}
+
+		if (!_mirrored_lv_in_sync(mirror_seg->lv)) {
 			log_verbose("Not collapsing %s: out-of-sync",
-				    parent_lv->name);
+				    mirror_seg->lv->name);
 			return 1;
 		}
 
-		if (!_remove_mirror_images(parent_lv,
-					   first_seg(parent_lv)->area_count - 1,
+		if (!_remove_mirror_images(mirror_seg->lv,
+					   mirror_seg->area_count - 1,
 					   NULL, 1, 1)) {
 			log_error("Failed to release mirror images");
 			return 0;
@@ -801,7 +836,6 @@
 {
 	struct lv_list *lvl;
 	struct lv_segment *seg;
-	uint32_t s;
 
 	list_iterate_items(lvl, &vg->lvs) {
 		list_iterate_items(seg, &lvl->lv->segments) {
@@ -809,12 +843,8 @@
 			    get_segtype_from_string(vg->cmd, "mirror"))
 				continue;
 
-			if (seg->log_lv)
-				first_seg(seg->log_lv)->mirror_seg = seg;
-			for (s = 0; s < seg->area_count; s++)
-				if (seg_type(seg, s) == AREA_LV)
-					first_seg(seg_lv(seg, s))->mirror_seg
-					    = seg;
+			if (seg->log_lv && !add_seg_to_segs_using_this_lv(seg->log_lv, seg))
+				return_0;
 		}
 	}
 
@@ -1103,7 +1133,7 @@
 {
 	first_seg(lv)->log_lv = log_lv;
 	log_lv->status |= MIRROR_LOG;
-	first_seg(log_lv)->mirror_seg = first_seg(lv);
+	add_seg_to_segs_using_this_lv(log_lv, first_seg(lv));
 }
 
 int add_mirror_log(struct cmd_context *cmd,
--- LVM2/lib/report/report.c	2008/01/10 18:35:51	1.71
+++ LVM2/lib/report/report.c	2008/01/16 19:00:59	1.72
@@ -275,13 +275,12 @@
 static int _lv_mimage_in_sync(const struct logical_volume *lv)
 {
 	float percent;
-	struct lv_segment *seg = first_seg(lv);
+	struct lv_segment *mirror_seg = find_mirror_seg(first_seg(lv));
 
-	if (!(lv->status & MIRROR_IMAGE) || !seg->mirror_seg)
+	if (!(lv->status & MIRROR_IMAGE) || !mirror_seg)
 		return_0;
 
-	if (!lv_mirror_percent(lv->vg->cmd, seg->mirror_seg->lv, 0,
-			       &percent, NULL))
+	if (!lv_mirror_percent(lv->vg->cmd, mirror_seg->lv, 0, &percent, NULL))
 		return_0;
 
 	if (percent >= 100.0)
--- LVM2/tools/vgreduce.c	2007/11/19 18:24:08	1.72
+++ LVM2/tools/vgreduce.c	2008/01/16 19:00:59	1.73
@@ -50,7 +50,7 @@
 static int _remove_lv(struct cmd_context *cmd, struct logical_volume *lv,
 		      int *list_unsafe, struct list *lvs_changed)
 {
-	struct lv_segment *snap_seg, *mirror_seg;
+	struct lv_segment *snap_seg;
 	struct list *snh, *snht;
 	struct logical_volume *cow;
 	struct lv_list *lvl;
@@ -117,9 +117,8 @@
 	 * Clean-up is currently done by caller (_make_vg_consistent()).
 	 */
 	if ((lv_info(cmd, lv, &info, 0, 0) && info.exists)
-	    || first_seg(lv)->mirror_seg) {
+	    || find_mirror_seg(first_seg(lv))) {
 		extents = lv->le_count;
-		mirror_seg = first_seg(lv)->mirror_seg;
 		if (!lv_empty(lv)) {
 			stack;
 			return 0;
@@ -130,10 +129,6 @@
 			stack;
 			return 0;
 		}
-		if (mirror_seg) {
-			first_seg(lv)->status |= MIRROR_IMAGE;
-			first_seg(lv)->mirror_seg = mirror_seg;
-		}
 
 		if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
 			log_error("lv_list alloc failed");


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2005-05-11 15:02 agk
  0 siblings, 0 replies; 8+ messages in thread
From: agk @ 2005-05-11 15:02 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2005-05-11 15:02:49

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/format_pool: import_export.c 
	lib/format_text: import_vsn1.c 
	lib/metadata   : lv_manip.c metadata.c metadata.h pv_alloc.h 
	                 pv_manip.c pv_map.c pv_map.h 
	tools          : toollib.c 

Log message:
	Remove lists of free PV segments.
	Simplify pv_maps code and remove slow bitset algorithm.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.239&r2=1.240
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.73&r2=1.74
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/format_pool/import_export.c.diff?cvsroot=lvm2&r1=1.10&r2=1.11
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.24&r2=1.25
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.70&r2=1.71
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.76&r2=1.77
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.119&r2=1.120
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv_alloc.h.diff?cvsroot=lvm2&r1=1.2&r2=1.3
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv_manip.c.diff?cvsroot=lvm2&r1=1.2&r2=1.3
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv_map.c.diff?cvsroot=lvm2&r1=1.23&r2=1.24
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/pv_map.h.diff?cvsroot=lvm2&r1=1.5&r2=1.6
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.66&r2=1.67


^ permalink raw reply	[flat|nested] 8+ messages in thread

* LVM2 ./WHATS_NEW lib/format1/import-export.c l ...
@ 2005-04-07 12:27 agk
  0 siblings, 0 replies; 8+ messages in thread
From: agk @ 2005-04-07 12:27 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2005-04-07 12:27:57

Modified files:
	.              : WHATS_NEW 
	lib/format1    : import-export.c 
	lib/metadata   : metadata.h snapshot_manip.c 
	lib/snapshot   : snapshot.c 
	tools          : lvcreate.c 

Log message:
	Remove unused internal non-persistent snapshot option.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.224&r2=1.225
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.69&r2=1.70
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.111&r2=1.112
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/snapshot_manip.c.diff?cvsroot=lvm2&r1=1.17&r2=1.18
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/snapshot/snapshot.c.diff?cvsroot=lvm2&r1=1.8&r2=1.9
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.88&r2=1.89


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-09-28 17:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-28 17:46 LVM2 ./WHATS_NEW lib/format1/import-export.c l agk
  -- strict thread matches above, loose matches on Subject: below --
2009-05-13 21:25 mbroz
2009-05-13 21:22 mbroz
2009-05-13 21:22 mbroz
2009-05-12 19:12 mbroz
2008-01-16 19:01 agk
2005-05-11 15:02 agk
2005-04-07 12:27 agk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).