Bug#691271: lvm2: diff for NMU version 2.02.95-4.1

tobi at coldtobi.de tobi at coldtobi.de
Sun Nov 18 13:21:27 UTC 2012


Am Sonntag, den 18.11.2012, 13:52 +0100 schrieb Bastian Blank:
On Sun, Nov 18, 2012 at 12:27:12PM +0100, tobi at coldtobi.de wrote:
> > I've prepared an NMU for lvm2 (versioned as 2.02.95-4.1) and
> > will be uploaded via my sponsor to DELAYED/5. Please feel free to tell me if I
> > should delay it longer.
>
> How does this work without any change except of the changelog? Or is the
> patch incomplete?
>
> Bastian
> 
No, of course not.
It seems, that I was unable to use nmudiff properly ...
However, lets retry:

diff -Nru lvm2-2.02.95/debian/changelog lvm2-2.02.95/debian/changelog
--- lvm2-2.02.95/debian/changelog	2012-05-27 19:05:43.000000000 +0200
+++ lvm2-2.02.95/debian/changelog	2012-11-18 12:29:14.000000000 +0100
@@ -1,3 +1,11 @@
+lvm2 (2.02.95-4.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix "Losing data when moving LV between regular HD -> SSD"
+    Applied upstream patch (from 2.02.97) (Closes: #691271)
+
+ -- Tobias Frost <tobi at coldtobi.de>  Sun, 18 Nov 2012 12:12:22 +0100
+
 lvm2 (2.02.95-4) unstable; urgency=low
 
   * Force building with -j1.
diff -Nru lvm2-2.02.95/debian/patches/lvm-patch-691271.patch lvm2-2.02.95/debian/patches/lvm-patch-691271.patch
--- lvm2-2.02.95/debian/patches/lvm-patch-691271.patch	1970-01-01 01:00:00.000000000 +0100
+++ lvm2-2.02.95/debian/patches/lvm-patch-691271.patch	2012-11-18 11:43:09.000000000 +0100
@@ -0,0 +1,280 @@
+# Subject: pmmove leads to data-loss when used with issue_discards=1
+# Bug: https://bugzilla.redhat.com/show_bug.cgi?id=832392
+# Origin: https://lists.fedorahosted.org/pipermail/lvm2-commits/2012-June/000037.html
+#  https://lists.fedorahosted.org/pipermail/lvm2-commits/2012-June/000038.html
+#  https://lists.fedorahosted.org/pipermail/lvm2-commits/2012-June/000039.html
+# Applied-Upstream: lvm2-2.02.97-2
+--- a/lib/metadata/lv_alloc.h
++++ b/lib/metadata/lv_alloc.h
+@@ -40,8 +40,9 @@
+ 			   uint64_t status);
+ 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,
+-			     uint32_t area_reduction);
++int release_lv_segment_area(struct lv_segment *seg, uint32_t s,
++			    uint32_t area_reduction);
++int release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction);
+ 
+ struct alloc_handle;
+ struct alloc_handle *allocate_extents(struct volume_group *vg,
+--- a/lib/metadata/lv_manip.c
++++ b/lib/metadata/lv_manip.c
+@@ -299,24 +299,30 @@
+ 	return seg;
+ }
+ 
+-void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
+-			     uint32_t area_reduction)
++static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s,
++						uint32_t area_reduction, int with_discard)
+ {
+ 	if (seg_type(seg, s) == AREA_UNASSIGNED)
+-		return;
++		return 1;
+ 
+ 	if (seg_type(seg, s) == AREA_PV) {
+-		if (release_pv_segment(seg_pvseg(seg, s), area_reduction) &&
+-		    seg->area_len == area_reduction)
++		if (with_discard && !discard_pv_segment(seg_pvseg(seg, s), area_reduction))
++			return_0;
++
++		if (!release_pv_segment(seg_pvseg(seg, s), area_reduction))
++			return_0;
++
++		if (seg->area_len == area_reduction)
+ 			seg_type(seg, s) = AREA_UNASSIGNED;
+-		return;
++
++		return 1;
+ 	}
+ 
+ 	if ((seg_lv(seg, s)->status & MIRROR_IMAGE) ||
+ 	    (seg_lv(seg, s)->status & THIN_POOL_DATA)) {
+ 		if (!lv_reduce(seg_lv(seg, s), area_reduction))
+-			stack; /* FIXME: any upper level reporting */
+-		return;
++			return_0; /* FIXME: any upper level reporting */
++		return 1;
+ 	}
+ 
+ 	if (seg_lv(seg, s)->status & RAID_IMAGE) {
+@@ -328,12 +334,12 @@
+ 		*/
+ 		if (area_reduction != seg->area_len) {
+ 			log_error("Unable to reduce RAID LV - operation not implemented.");
+-			return;
++			return_0;
+ 		} else {
+ 			if (!lv_remove(seg_lv(seg, s))) {
+ 				log_error("Failed to remove RAID image %s",
+ 					  seg_lv(seg, s)->name);
+-				return;
++				return 0;
+ 			}
+ 		}
+ 
+@@ -343,10 +349,10 @@
+ 				       seg_metalv(seg, s)->le_count)) {
+ 				log_error("Failed to remove RAID meta-device %s",
+ 					  seg_metalv(seg, s)->name);
+-				return;
++				return 0;
+ 			}
+ 		}
+-		return;
++		return 1;
+ 	}
+ 
+ 	if (area_reduction == seg->area_len) {
+@@ -360,6 +366,18 @@
+ 		seg_le(seg, s) = 0;
+ 		seg_type(seg, s) = AREA_UNASSIGNED;
+ 	}
++
++	return 1;
++}
++
++int release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction)
++{
++	return _release_and_discard_lv_segment_area(seg, s, area_reduction, 1);
++}
++
++int release_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction)
++{
++	return _release_and_discard_lv_segment_area(seg, s, area_reduction, 0);
+ }
+ 
+ /*
+@@ -377,9 +395,11 @@
+ 		pv = seg_pv(seg_from, area_from);
+ 		pe = seg_pe(seg_from, area_from);
+ 
+-		release_lv_segment_area(seg_from, area_from,
+-					seg_from->area_len);
+-		release_lv_segment_area(seg_to, area_to, seg_to->area_len);
++		if (!release_lv_segment_area(seg_from, area_from, seg_from->area_len))
++			return_0;
++
++		if (!release_lv_segment_area(seg_to, area_to, seg_to->area_len))
++			return_0;
+ 
+ 		if (!set_lv_segment_area_pv(seg_to, area_to, pv, pe))
+ 			return_0;
+@@ -390,9 +410,11 @@
+ 		lv = seg_lv(seg_from, area_from);
+ 		le = seg_le(seg_from, area_from);
+ 
+-		release_lv_segment_area(seg_from, area_from,
+-					seg_from->area_len);
+-		release_lv_segment_area(seg_to, area_to, seg_to->area_len);
++		if (!release_lv_segment_area(seg_from, area_from, seg_from->area_len))
++			return_0;
++
++		if (!release_lv_segment_area(seg_to, area_to, seg_to->area_len))
++			return_0;
+ 
+ 		if (!set_lv_segment_area_lv(seg_to, area_to, lv, le, 0))
+ 			return_0;
+@@ -400,7 +422,8 @@
+ 		break;
+ 
+ 	case AREA_UNASSIGNED:
+-		release_lv_segment_area(seg_to, area_to, seg_to->area_len);
++		if (!release_lv_segment_area(seg_to, area_to, seg_to->area_len))
++			return_0;
+ 	}
+ 
+ 	return 1;
+@@ -493,7 +516,8 @@
+ 		area_reduction = reduction;
+ 
+ 	for (s = 0; s < seg->area_count; s++)
+-		release_lv_segment_area(seg, s, area_reduction);
++		if (!release_and_discard_lv_segment_area(seg, s, area_reduction))
++			return_0;
+ 
+ 	seg->len -= reduction;
+ 	seg->area_len -= area_reduction;
+--- a/lib/metadata/mirror.c
++++ b/lib/metadata/mirror.c
+@@ -645,8 +645,8 @@
+ 		sub_lv = seg_lv(mirrored_seg, mirrored_seg->area_count);
+ 
+ 		sub_lv->status &= ~MIRROR_IMAGE;
+-		release_lv_segment_area(mirrored_seg, mirrored_seg->area_count,
+-					mirrored_seg->area_len);
++		if (!release_lv_segment_area(mirrored_seg, mirrored_seg->area_count, mirrored_seg->area_len))
++			return_0;
+ 
+ 		log_very_verbose("%s assigned to be split", sub_lv->name);
+ 
+@@ -906,7 +906,8 @@
+ 		}
+ 		lvl->lv = seg_lv(mirrored_seg, m);
+ 		dm_list_add(&tmp_orphan_lvs, &lvl->list);
+-		release_lv_segment_area(mirrored_seg, m, mirrored_seg->area_len);
++		if (!release_lv_segment_area(mirrored_seg, m, mirrored_seg->area_len))
++			return_0;
+ 	}
+ 	mirrored_seg->area_count = new_area_count;
+ 
+@@ -1468,7 +1469,8 @@
+ 		}
+ 
+ 		for (s = new_mirrors + 1; s < seg->area_count; s++)
+-			release_lv_segment_area(seg, s, seg->area_len);
++			if (!release_and_discard_lv_segment_area(seg, s, seg->area_len))
++				return_0;
+ 
+ 		seg->area_count = new_mirrors + 1;
+ 
+--- a/lib/metadata/pv_alloc.h
++++ b/lib/metadata/pv_alloc.h
+@@ -23,6 +23,7 @@
+ int pv_split_segment(struct dm_pool *mem,
+ 		     struct physical_volume *pv, uint32_t pe,
+ 		     struct pv_segment **pvseg_allocated);
++int discard_pv_segment(struct pv_segment *peg, uint32_t discard_area_reduction);
+ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction);
+ int check_pv_segments(struct volume_group *vg);
+ void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2);
+--- a/lib/metadata/pv_manip.c
++++ b/lib/metadata/pv_manip.c
+@@ -189,14 +189,13 @@
+ 	return peg;
+ }
+ 
+-int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
++int discard_pv_segment(struct pv_segment *peg, uint32_t discard_area_reduction)
+ {
+ 	uint64_t discard_offset_sectors;
+ 	uint64_t pe_start = peg->pv->pe_start;
+-	uint64_t discard_area_reduction = area_reduction;
+ 
+ 	if (!peg->lvseg) {
+-		log_error("release_pv_segment with unallocated segment: "
++		log_error("discard_pv_segment with unallocated segment: "
+ 			  "%s PE %" PRIu32, pv_dev_name(peg->pv), peg->pe);
+ 		return 0;
+ 	}
+@@ -205,26 +204,39 @@
+ 	 * Only issue discards if enabled in lvm.conf and both
+ 	 * the device and kernel (>= 2.6.35) supports discards.
+ 	 */
+-	if (find_config_tree_bool(peg->pv->fmt->cmd,
+-				  "devices/issue_discards", DEFAULT_ISSUE_DISCARDS) &&
+-	    dev_discard_max_bytes(peg->pv->fmt->cmd->sysfs_dir, peg->pv->dev) &&
+-	    dev_discard_granularity(peg->pv->fmt->cmd->sysfs_dir, peg->pv->dev)) {
+-		discard_offset_sectors = (peg->pe + peg->lvseg->area_len - area_reduction) *
+-			(uint64_t) peg->pv->vg->extent_size + pe_start;
+-		if (!discard_offset_sectors) {
+-			/*
+-			 * pe_start=0 and the PV's first extent contains the label.
+-			 * Must skip past the first extent.
+-			 */
+-			discard_offset_sectors = peg->pv->vg->extent_size;
+-			discard_area_reduction--;
+-		}
+-		log_debug("Discarding %" PRIu64 " extents offset %" PRIu64 " sectors on %s.",
+-			  discard_area_reduction, discard_offset_sectors, dev_name(peg->pv->dev));
+-		if (discard_area_reduction &&
+-		    !dev_discard_blocks(peg->pv->dev, discard_offset_sectors << SECTOR_SHIFT,
+-					discard_area_reduction * (uint64_t) peg->pv->vg->extent_size * SECTOR_SIZE))
+-			return_0;
++	if (!find_config_tree_bool(peg->pv->fmt->cmd,
++				   "devices/issue_discards", DEFAULT_ISSUE_DISCARDS) ||
++	    !dev_discard_max_bytes(peg->pv->fmt->cmd->sysfs_dir, peg->pv->dev) ||
++	    !dev_discard_granularity(peg->pv->fmt->cmd->sysfs_dir, peg->pv->dev))
++		return 1;
++
++	discard_offset_sectors = (peg->pe + peg->lvseg->area_len - discard_area_reduction) *
++				 (uint64_t) peg->pv->vg->extent_size + pe_start;
++	if (!discard_offset_sectors) {
++		/*
++		 * pe_start=0 and the PV's first extent contains the label.
++		 * Must skip past the first extent.
++		 */
++		discard_offset_sectors = peg->pv->vg->extent_size;
++		discard_area_reduction--;
++	}
++
++	log_debug("Discarding %" PRIu32 " extents offset %" PRIu64 " sectors on %s.",
++		  discard_area_reduction, discard_offset_sectors, dev_name(peg->pv->dev));
++	if (discard_area_reduction &&
++	    !dev_discard_blocks(peg->pv->dev, discard_offset_sectors << SECTOR_SHIFT,
++				discard_area_reduction * (uint64_t) peg->pv->vg->extent_size * SECTOR_SIZE))
++		return_0;
++
++	return 1;
++}
++
++int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
++{
++	if (!peg->lvseg) {
++		log_error("release_pv_segment with unallocated segment: "
++			  "%s PE %" PRIu32, pv_dev_name(peg->pv), peg->pe);
++		return 0;
+ 	}
+ 
+ 	if (peg->lvseg->area_len == area_reduction) {
diff -Nru lvm2-2.02.95/debian/patches/series lvm2-2.02.95/debian/patches/series
--- lvm2-2.02.95/debian/patches/series	2012-05-27 14:27:52.000000000 +0200
+++ lvm2-2.02.95/debian/patches/series	2012-11-18 11:31:32.000000000 +0100
@@ -6,3 +6,4 @@
 implicit-pointer.patch
 dm-event-api.patch
 monitoring-default-off.patch
+lvm-patch-691271.patch



More information about the pkg-lvm-maintainers mailing list