All of lore.kernel.org
 help / color / mirror / Atom feed
From: prajnoha@sourceware.org <prajnoha@sourceware.org>
To: lvm-devel@redhat.com
Subject: LVM2/lib/format_text format-text.c
Date: 25 Feb 2011 13:50:04 -0000	[thread overview]
Message-ID: <20110225135004.26736.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha at sourceware.org	2011-02-25 13:50:03

Modified files:
	lib/format_text: format-text.c 

Log message:
	Fix a bug in metadata location calculation, cleanup pv_add_metadata_area fn.
	
	This bug (a missing line) caused the 2nd MDA area location to be calculated
	incorrectly and it didn't fit the disk size properly.
	
	(https://www.redhat.com/archives/lvm-devel/2011-February/msg00127.html)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.166&r2=1.167

--- LVM2/lib/format_text/format-text.c	2011/02/21 12:31:28	1.166
+++ LVM2/lib/format_text/format-text.c	2011/02/25 13:50:02	1.167
@@ -1884,11 +1884,13 @@
 	uint64_t alignment, alignment_offset;
 	uint64_t disk_size;
 	uint64_t mda_start;
-	uint64_t adjustment, limit;
+	uint64_t adjustment, limit, tmp_mda_size;
 	uint64_t wipe_size = 8 << SECTOR_SHIFT;
 	size_t page_size = lvm_getpagesize();
 	struct metadata_area *mda;
 	struct mda_context *mdac;
+	const char *limit_name;
+	int limit_applied = 0;
 
 	if (mda_index >= FMT_TEXT_MAX_MDAS_PER_PV) {
 		log_error(INTERNAL_ERROR "invalid index of value %u used "
@@ -1917,13 +1919,19 @@
 		 * is locked. If it's not locked, count with any existing MDA1.
 		 * If there's no MDA1, just use disk size as the limit.
 		 */
-		if (pe_start_locked)
+		if (pe_start_locked) {
 			limit = pe_start;
+			limit_name = "pe_start";
+		}
 		else if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 1)) &&
-			 (mdac = mda->metadata_locn))
+			 (mdac = mda->metadata_locn)) {
 			limit = mdac->area.start;
-		else
+			limit_name = "MDA1 start";
+		}
+		else {
 			limit = disk_size;
+			limit_name = "disk size";
+		}
 
 		if (limit > disk_size)
 			goto bad;
@@ -1937,29 +1945,22 @@
 		}
 
 		/* Align MDA0 end position with given alignment if possible. */
-		if (alignment) {
-			if ((adjustment = (mda_start + mda_size) % alignment)) {
-				mda_size += (alignment - adjustment);
-				if (mda_start + mda_size > limit)
-					mda_size -= (alignment - adjustment);
-			}
+		if (alignment &&
+		    (adjustment = (mda_start + mda_size) % alignment)) {
+			tmp_mda_size = mda_size + alignment - adjustment;
+			if (mda_start + tmp_mda_size <= limit)
+				mda_size = tmp_mda_size;
 		}
 
 		/* Align MDA0 end position with given alignment offset if possible. */
 		if (alignment_offset &&
 		    (((mda_start + mda_size) % alignment) == 0)) {
-			mda_size += alignment_offset;
-			if (mda_start + mda_size > limit)
-				mda_size -= alignment_offset;
+			tmp_mda_size = mda_size + alignment_offset;
+			if (mda_start + tmp_mda_size <= limit)
+				mda_size = tmp_mda_size;
 		}
 
 		if (mda_start + mda_size > limit) {
-			log_warn("WARNING: metadata area size outreaches "
-				 "a limit on PV %s specified by its %s. "
-				 "Trying to adjust metadata area size.",
-				  pv_dev_name(pv),
-				  pe_start_locked ? "PE start" : "disk size");
-
 			/*
 			 * Try to decrease the MDA0 size with twice the
 			 * alignment and then align with given alignment.
@@ -1982,6 +1983,8 @@
 			/* FIXME: We should probably check for some minimum MDA size here. */
 			else
 				mda_size = limit - mda_start;
+
+			limit_applied = 1;
 		}
 
 		/*
@@ -1997,41 +2000,54 @@
 	else {
 		/*
 		 * Try to fit MDA1 start within given pe_end or pe_start limit
-		 * if it's locked. If pe_start and pe_end are not defined yet,
-		 * count with any existing MDA0 and pe_start. If MDA0 does not
-		 * exist, just use LABEL_SCAN_SIZE.
+		 * if defined or locked. If pe_start is not defined yet, count
+		 * with any existing MDA0. If MDA0 does not exist, just use
+		 * LABEL_SCAN_SIZE.
 		 */
 		pe_end = pv->pe_count ? (pv->pe_start +
 					 pv->pe_count * pv->pe_size - 1) << SECTOR_SHIFT
 				      : 0;
-		if (pe_start_locked)
+
+		if (pe_start || pe_start_locked) {
 			limit = pe_end ? pe_end : pe_start;
-		else if (pe_start)
-			limit = pe_start;
-		/*
-		 * Normally MDA0's start + size should be pe_start.
-		 * The statemet here is probably useless since the
-		 * situation is covered by previous statement.
-		 */
+			limit_name = pe_end ? "pe_end" : "pe_start";
+		}
 		else if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 0)) &&
-			 (mdac = mda->metadata_locn))
+			 (mdac = mda->metadata_locn)) {
 			limit = mdac->area.start + mdac->area.size;
-		else
+			limit_name = "MDA0 end";
+		}
+		else {
 			limit = LABEL_SCAN_SIZE;
+			limit_name = "label scan size";
+		}
 
-		if (limit > disk_size || mda_size > disk_size)
+		if (limit > disk_size)
 			goto bad;
 
-		mda_start = disk_size - mda_size;
-
-		if (alignment) {
-			adjustment = mda_start % alignment;
-			if (adjustment)
-				mda_size += adjustment;
+		if (mda_size > disk_size) {
+			mda_size = disk_size - limit;
+			limit_applied = 1;
 		}
 
-		if (disk_size - mda_size < limit)
+		mda_start = disk_size - mda_size;
+
+		/* If MDA1 size is too big, just take any usable space. */
+		if (disk_size - mda_size < limit) {
 			mda_size = disk_size - limit;
+			mda_start = disk_size - mda_size;
+			limit_applied = 1;
+		}
+		/* Otherwise, try to align MDA1 start if possible. */
+		else if (alignment &&
+		    (adjustment = mda_start % alignment)) {
+			tmp_mda_size = mda_size + adjustment;
+			if (tmp_mda_size < disk_size &&
+			    disk_size - tmp_mda_size >= limit) {
+				mda_size = tmp_mda_size;
+				mda_start = disk_size - mda_size;
+			}
+		}
 
 		/*
 		 * If PV's pe_end not set yet, set it to the end of the
@@ -2044,6 +2060,12 @@
 		}*/
 	}
 
+	if (limit_applied)
+		log_very_verbose("Using limited metadata area size on %s "
+				 "with value %" PRIu64 " (limited by %s of "
+				 "%" PRIu64 ").", pv_dev_name(pv),
+				  mda_size, limit_name, limit);
+
 	if (mda_size) {
 		/* Wipe metadata area with zeroes. */
 		if (!dev_set((struct device *) pv->dev, mda_start,



             reply	other threads:[~2011-02-25 13:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-25 13:50 prajnoha [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-02-27  9:54 LVM2/lib/format_text format-text.c zkabelac
2011-03-02 10:23 prajnoha
2011-02-28 17:05 prajnoha
2011-02-21 12:25 prajnoha
2010-11-29 11:16 zkabelac
2010-08-26 12:22 mbroz
2010-06-29 13:29 wysochanski
2010-06-28 20:30 wysochanski
2009-07-31 14:23 snitzer
2009-07-30 17:41 snitzer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110225135004.26736.qmail@sourceware.org \
    --to=prajnoha@sourceware.org \
    --cc=lvm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.