linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
To: jes@trained-monkey.org
Cc: linux-raid@vger.kernel.org, colyli@suse.de
Subject: [PATCH 6/6] imsm: fix free space calculations
Date: Mon, 29 May 2023 15:52:38 +0200	[thread overview]
Message-ID: <20230529135238.18602-7-mariusz.tkaczyk@linux.intel.com> (raw)
In-Reply-To: <20230529135238.18602-1-mariusz.tkaczyk@linux.intel.com>

Between two volumes or between last volume and metadata at least
IMSM_RESERVED_SECTORS gap must exist. Currently the gap can be doubled
because metadata reservation contains IMSM_RESERVED_SECTORS too.

Divide reserve variable into pre_reservation and post_reservation to be
more flexible and decide separately if each reservation is needed.

Pre_reservation is needed only when a volume is created and it is not a
real first volume in a container (we can check that by extent_idx).
This type of reservation is not needed for expand.

Post_reservation is not needed only if real last volume is created or
expanded because reservation is done with the metadata.

The volume index in metadata cannot be trusted, because the real volume
order can be reversed. It is safer to use extent table, it is sorted by
start position.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
 super-intel.c | 50 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 20 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 1559c837..c012b220 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6861,8 +6861,11 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
 	int sum_extents = 0;
 	unsigned long long pos = 0;
 	unsigned long long start = 0;
-	unsigned long long maxsize = 0;
-	unsigned long reserve;
+	unsigned long long free_size = 0;
+
+	unsigned long pre_reservation = 0;
+	unsigned long post_reservation = IMSM_RESERVED_SECTORS;
+	unsigned long reservation_size;
 
 	for (dl = super->disks; dl; dl = dl->next)
 		if (dl->e)
@@ -6897,8 +6900,8 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
 	do {
 		unsigned long long esize = e[i].start - pos;
 
-		if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) {
-			maxsize = esize;
+		if (expanding ? pos_vol_idx == super->current_vol : esize >= free_size) {
+			free_size = esize;
 			start = pos;
 			extent_idx = i;
 		}
@@ -6908,28 +6911,35 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
 
 		i++;
 	} while (e[i-1].size);
-	free(e);
 
-	if (maxsize == 0)
+	if (free_size == 0) {
+		dprintf("imsm: Cannot find free size.\n");
+		free(e);
 		return 0;
+	}
 
-	/* FIXME assumes volume at offset 0 is the first volume in a
-	 * container
-	 */
-	if (extent_idx > 0)
-		reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
-	else
-		reserve = 0;
+	if (!expanding && extent_idx != 0)
+		/*
+		 * Not a real first volume in a container is created, pre_reservation is needed.
+		 */
+		pre_reservation = IMSM_RESERVED_SECTORS;
 
-	if (maxsize < reserve)
-		return 0;
+	if (e[extent_idx].size == 0)
+		/*
+		 * extent_idx points to the metadata, post_reservation is allready done.
+		 */
+		post_reservation = 0;
+	free(e);
 
-	super->create_offset = ~((unsigned long long) 0);
-	if (start + reserve > super->create_offset)
-		return 0; /* start overflows create_offset */
-	super->create_offset = start + reserve;
+	reservation_size = pre_reservation + post_reservation;
+
+	if (free_size < reservation_size) {
+		dprintf("imsm: Reservation size is greater than free space.\n");
+		return 0;
+	}
 
-	return maxsize - reserve;
+	super->create_offset = start + pre_reservation;
+	return free_size - reservation_size;
 }
 
 static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
-- 
2.26.2


  parent reply	other threads:[~2023-05-29 13:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-29 13:52 [PATCH 0/6] imsm: expand improvements Mariusz Tkaczyk
2023-05-29 13:52 ` [PATCH 1/6] imsm: move sum_extents calculations to merge_extents() Mariusz Tkaczyk
2023-05-29 13:52 ` [PATCH 2/6] imsm: imsm_get_free_size() refactor Mariusz Tkaczyk
2023-05-29 13:52 ` [PATCH 3/6] imsm: introduce round_member_size_to_mb() Mariusz Tkaczyk
2023-05-29 13:52 ` [PATCH 4/6] imsm: move expand verification code into new function Mariusz Tkaczyk
2023-05-29 13:52 ` [PATCH 5/6] imsm: return free space after volume for expand Mariusz Tkaczyk
2023-05-29 13:52 ` Mariusz Tkaczyk [this message]
2023-09-01 15:37 ` [PATCH 0/6] imsm: expand improvements Jes Sorensen
2023-05-31 15:21 Mariusz Tkaczyk
2023-05-31 15:21 ` [PATCH 6/6] imsm: fix free space calculations Mariusz Tkaczyk

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=20230529135238.18602-7-mariusz.tkaczyk@linux.intel.com \
    --to=mariusz.tkaczyk@linux.intel.com \
    --cc=colyli@suse.de \
    --cc=jes@trained-monkey.org \
    --cc=linux-raid@vger.kernel.org \
    /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 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 NNTP newsgroup(s).