linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: benh@kernel.crashing.org
To: linuxppc-dev@ozlabs.org
Cc: jkensito@us.ibm.com
Subject: [PATCH 07/13] powerpc/nvram: Improve partition removal
Date: Tue, 30 Nov 2010 16:47:37 +1100	[thread overview]
Message-ID: <1291096063-14386-7-git-send-email-benh@kernel.crashing.org> (raw)
In-Reply-To: <1291096063-14386-1-git-send-email-benh@kernel.crashing.org>

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Existing code is nasty, has bugs etc... rewrite the function
more simply, and make it take the signature and optional
name of the partitions to remove as arguments, thus making
it a more generic utility.

We also try to remove a log partition that we find and is too
small rather than creating a duplicate.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/nvram_64.c |   91 +++++++++++++++++++---------------------
 1 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index eabee7c..6dd2700 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -247,61 +247,54 @@ static unsigned char __init nvram_checksum(struct nvram_header *p)
 	return c_sum;
 }
 
-static int __init nvram_remove_os_partition(void)
+/**
+ * nvram_remove_partition - Remove one or more partitions in nvram
+ * @name: name of the partition to remove, or NULL for a
+ *        signature only match
+ * @sig: signature of the partition(s) to remove
+ */
+
+static int __init nvram_remove_partition(const char *name, int sig)
 {
-	struct list_head *i;
-	struct list_head *j;
-	struct nvram_partition * part;
-	struct nvram_partition * cur_part;
+	struct nvram_partition *part, *prev, *tmp;
 	int rc;
 
-	list_for_each(i, &nvram_part->partition) {
-		part = list_entry(i, struct nvram_partition, partition);
-		if (part->header.signature != NVRAM_SIG_OS)
+	list_for_each_entry(part, &nvram_part->partition, partition) {
+		if (part->header.signature != sig)
 			continue;
-		
-		/* Make os partition a free partition */
+		if (name && strncmp(name, part->header.name, 12))
+			continue;
+
+		/* Make partition a free partition */
 		part->header.signature = NVRAM_SIG_FREE;
 		sprintf(part->header.name, "wwwwwwwwwwww");
 		part->header.checksum = nvram_checksum(&part->header);
-
-		/* Merge contiguous free partitions backwards */
-		list_for_each_prev(j, &part->partition) {
-			cur_part = list_entry(j, struct nvram_partition, partition);
-			if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
-				break;
-			}
-			
-			part->header.length += cur_part->header.length;
-			part->header.checksum = nvram_checksum(&part->header);
-			part->index = cur_part->index;
-
-			list_del(&cur_part->partition);
-			kfree(cur_part);
-			j = &part->partition; /* fixup our loop */
-		}
-		
-		/* Merge contiguous free partitions forwards */
-		list_for_each(j, &part->partition) {
-			cur_part = list_entry(j, struct nvram_partition, partition);
-			if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
-				break;
-			}
-
-			part->header.length += cur_part->header.length;
-			part->header.checksum = nvram_checksum(&part->header);
-
-			list_del(&cur_part->partition);
-			kfree(cur_part);
-			j = &part->partition; /* fixup our loop */
-		}
-		
 		rc = nvram_write_header(part);
 		if (rc <= 0) {
-			printk(KERN_ERR "nvram_remove_os_partition: nvram_write failed (%d)\n", rc);
+			printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
 			return rc;
 		}
+	}
 
+	/* Merge contiguous ones */
+	prev = NULL;
+	list_for_each_entry_safe(part, tmp, &nvram_part->partition, partition) {
+		if (part->header.signature != NVRAM_SIG_FREE) {
+			prev = NULL;
+			continue;
+		}
+		if (prev) {
+			prev->header.length += part->header.length;
+			prev->header.checksum = nvram_checksum(&part->header);
+			rc = nvram_write_header(part);
+			if (rc <= 0) {
+				printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
+				return rc;
+			}
+			list_del(&part->partition);
+			kfree(part);
+		} else
+			prev = part;
 	}
 	
 	return 0;
@@ -484,17 +477,19 @@ static int __init nvram_setup_partition(void)
 						NVRAM_BLOCK_LEN) - sizeof(struct err_log_info);
 			return 0;
 		}
+
+		/* Found one but it's too small, remove it */
+		nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS);
 	}
 	
 	/* try creating a partition with the free space we have */
 	rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
 				       NVRAM_MAX_REQ, NVRAM_MIN_REQ);
 	if (rc < 0) {
-		/* need to free up some space */
-		rc = nvram_remove_os_partition();
-		if (rc)
-			return rc;	
-		/* create a partition in this new space */
+		/* need to free up some space, remove any "OS" partition */
+		nvram_remove_partition(NULL, NVRAM_SIG_OS);
+	
+		/* Try again */
 		rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
 					    NVRAM_MAX_REQ, NVRAM_MIN_REQ);
 		if (rc < 0) {
-- 
1.7.1

  parent reply	other threads:[~2010-11-30  5:47 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-30  5:47 [PATCH 01/13] powerpc/nvram: Move things out of asm/nvram.h benh
2010-11-30  5:47 ` [PATCH 02/13] powerpc/nvram: More flexible nvram_create_partition() benh
2010-11-30  5:47 ` [PATCH 03/13] powerpc/nvram: nvram_create_partitions() now uses bytes benh
2010-11-30  5:47 ` [PATCH 04/13] powerpc/nvram: Ensure that the partition header/block size is right benh
2010-11-30  5:47 ` [PATCH 05/13] powerpc/nvram: Completely clear a new partition benh
2010-11-30  5:47 ` [PATCH 06/13] powerpc/nvram: Shuffle code around in nvram_create_partition() benh
2010-11-30  5:47 ` benh [this message]
2010-11-30  5:47 ` [PATCH 08/13] powerpc/nvram: Add nvram_find_partition() benh
2010-11-30  5:47 ` [PATCH 09/13] powerpc/nvram: Change nvram_setup_partition() to use new helper benh
2010-11-30  5:47 ` [PATCH 10/13] powerpc/nvram: Move the log partition stuff to pseries benh
2010-11-30  5:47 ` [PATCH 11/13] powerpc/nvram: Rename ppc64, linux partition to ibm, rtas-log benh
2010-11-30  5:47 ` [PATCH 12/13] powerpc/nvram: Fix NVRAM partition list setup benh
2010-11-30  5:47 ` [PATCH 13/13] powerpc/nvram: Handle partition names >= 12 chars benh
2010-12-01  7:24 ` [PATCH 01/13] powerpc/nvram: Move things out of asm/nvram.h Jim Keniston

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=1291096063-14386-7-git-send-email-benh@kernel.crashing.org \
    --to=benh@kernel.crashing.org \
    --cc=jkensito@us.ibm.com \
    --cc=linuxppc-dev@ozlabs.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).