linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: linuxppc-dev@ozlabs.org
Subject: [PATCH 06/11] powerpc/nvram: Shuffle code around in nvram_create_partition()
Date: Mon,  2 Aug 2010 10:55:17 +1000	[thread overview]
Message-ID: <1280710522-6362-7-git-send-email-benh@kernel.crashing.org> (raw)
In-Reply-To: <1280710522-6362-6-git-send-email-benh@kernel.crashing.org>

This error log stuff is really pseries specific. As a first step we move
the initialization of these variables to the caller of
nvram_create_partition(), which is also slightly reorganized so we
setup the free partition before we clear the new partition, so the
chance of an error during clear leaving us with invalid headers
is lessened.

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

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 7ddeaa6..10f4b82 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -313,9 +313,15 @@ static int __init nvram_remove_os_partition(void)
  * @sig: signature of the partition to create
  * @req_size: size of data to allocate in bytes
  * @min_size: minimum acceptable size (0 means req_size)
+ *
+ * Returns a negative error code or a positive nvram index
+ * of the beginning of the data area of the newly created
+ * partition. If you provided a min_size smaller than req_size
+ * you need to query for the actual size yourself after the
+ * call using nvram_partition_get_size().
  */
-static int __init nvram_create_partition(const char *name, int sig,
-					 int req_size, int min_size)
+static loff_t __init nvram_create_partition(const char *name, int sig,
+					    int req_size, int min_size)
 {
 	struct nvram_partition *part;
 	struct nvram_partition *new_part;
@@ -334,6 +340,8 @@ static int __init nvram_create_partition(const char *name, int sig,
 	 */
 	if (min_size == 0)
 		min_size = req_size;
+	if (min_size > req_size)
+		return -EINVAL;
 
 	/* Now add one block to each for the header */
 	req_size += 1;
@@ -362,7 +370,7 @@ static int __init nvram_create_partition(const char *name, int sig,
 	/* Create our OS partition */
 	new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
 	if (!new_part) {
-		printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n");
+		pr_err("nvram_create_os_partition: kmalloc failed\n");
 		return -ENOMEM;
 	}
 
@@ -374,12 +382,29 @@ static int __init nvram_create_partition(const char *name, int sig,
 
 	rc = nvram_write_header(new_part);
 	if (rc <= 0) {
-		printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
-				"failed (%d)\n", rc);
+		pr_err("nvram_create_os_partition: nvram_write_header "
+		       "failed (%d)\n", rc);
 		return rc;
 	}
+	list_add_tail(&new_part->partition, &free_part->partition);
 
-	/* Clear the partition */
+	/* Adjust or remove the partition we stole the space from */
+	if (free_part->header.length > size) {
+		free_part->index += size * NVRAM_BLOCK_LEN;
+		free_part->header.length -= size;
+		free_part->header.checksum = nvram_checksum(&free_part->header);
+		rc = nvram_write_header(free_part);
+		if (rc <= 0) {
+			pr_err("nvram_create_os_partition: nvram_write_header "
+			       "failed (%d)\n", rc);
+			return rc;
+		}
+	} else {
+		list_del(&free_part->partition);
+		kfree(free_part);
+	} 
+
+	/* Clear the new partition */
 	for (tmp_index = new_part->index + NVRAM_HEADER_LEN;
 	     tmp_index <  ((size - 1) * NVRAM_BLOCK_LEN);
 	     tmp_index += NVRAM_BLOCK_LEN) {
@@ -390,31 +415,24 @@ static int __init nvram_create_partition(const char *name, int sig,
 		}
 	}
 	
-	nvram_error_log_index = new_part->index + NVRAM_HEADER_LEN;
-	nvram_error_log_size = ((part->header.length - 1) *
-				NVRAM_BLOCK_LEN) - sizeof(struct err_log_info);
-	
-	list_add_tail(&new_part->partition, &free_part->partition);
-
-	if (free_part->header.length <= size) {
-		list_del(&free_part->partition);
-		kfree(free_part);
-		return 0;
-	} 
+	return new_part->index + NVRAM_HEADER_LEN;
+}
 
-	/* Adjust the partition we stole the space from */
-	free_part->index += size * NVRAM_BLOCK_LEN;
-	free_part->header.length -= size;
-	free_part->header.checksum = nvram_checksum(&free_part->header);
+/**
+ * nvram_get_partition_size - Get the data size of an nvram partition
+ * @data_index: This is the offset of the start of the data of
+ *              the partition. The same value that is returned by
+ *              nvram_create_partition().
+ */
+static int nvram_get_partition_size(loff_t data_index)
+{
+	struct nvram_partition *part;
 	
-	rc = nvram_write_header(free_part);
-	if (rc <= 0) {
-		printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
-		       "failed (%d)\n", rc);
-		return rc;
+	list_for_each_entry(part, &nvram_part->partition, partition) {
+		if (part->index + NVRAM_HEADER_LEN == data_index)
+			return (part->header.length - 1) * NVRAM_BLOCK_LEN;
 	}
-
-	return 0;
+	return -1;
 }
 
 
@@ -469,30 +487,29 @@ static int __init nvram_setup_partition(void)
 	}
 	
 	/* try creating a partition with the free space we have */
-	rc = 	nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
+	rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
 				       NVRAM_MIN_REQ, NVRAM_MAX_REQ);
-	if (!rc)
-		return 0;
-		
-	/* need to free up some space */
-	rc = nvram_remove_os_partition();
-	if (rc) {
-		return rc;
+	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 */
+		rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
+					    NVRAM_MIN_REQ, NVRAM_MAX_REQ);
+		if (rc < 0) {
+			pr_err("nvram_create_partition: Could not find"
+			       " enough space in NVRAM for partition\n");
+			return rc;
+		}
 	}
 	
-	/* create a partition in this new space */
-	rc = 	nvram_create_partition("ppc64,linux", NVRAM_SIG_OS,
-				       NVRAM_MIN_REQ, NVRAM_MAX_REQ);
-	if (rc) {
-		printk(KERN_ERR "nvram_create_partition: Could not find a "
-		       "NVRAM partition large enough\n");
-		return rc;
-	}
+	nvram_error_log_index = rc;	
+	nvram_error_log_size = nvram_get_partition_size(rc) - sizeof(struct err_log_info);
 	
 	return 0;
 }
 
-
 static int __init nvram_scan_partitions(void)
 {
 	loff_t cur_index = 0;
-- 
1.6.3.3

  reply	other threads:[~2010-08-02  0:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-02  0:55 [RFC] Clean up ppc64 nvram code Benjamin Herrenschmidt
2010-08-02  0:55 ` [PATCH 01/11] powerpc/nvram: Move things out of asm/nvram.h Benjamin Herrenschmidt
2010-08-02  0:55   ` [PATCH 02/11] powerpc/nvram: More flexible nvram_create_partition() Benjamin Herrenschmidt
2010-08-02  0:55     ` [PATCH 03/11] powerpc/nvram: nvram_create_partitions() now uses bytes Benjamin Herrenschmidt
2010-08-02  0:55       ` [PATCH 04/11] powerpc/nvram: Ensure that the partition header/block size is right Benjamin Herrenschmidt
2010-08-02  0:55         ` [PATCH 05/11] powerpc/nvram: Completely clear a new partition Benjamin Herrenschmidt
2010-08-02  0:55           ` Benjamin Herrenschmidt [this message]
2010-08-02  0:55             ` [PATCH 07/11] powerpc/nvram: Improve partition removal Benjamin Herrenschmidt
2010-08-02  0:55               ` [PATCH 08/11] powerpc/nvram: Add nvram_find_partition() Benjamin Herrenschmidt
2010-08-02  0:55                 ` [PATCH 09/11] powerpc/nvram: Change nvram_setup_partition() to use new helper Benjamin Herrenschmidt
2010-08-02  0:55                   ` [PATCH 10/11] powerpc/nvram: Move the log partition stuff to pseries Benjamin Herrenschmidt
2010-08-02  0:55                     ` [PATCH 11/11] powerpc/nvram: Rename ppc64, linux partition to ibm, rtas-log Benjamin Herrenschmidt
2010-08-02  1:40                     ` [PATCH 10/11] powerpc/nvram: Move the log partition stuff to pseries Benjamin Herrenschmidt
2010-08-02  3:50           ` [PATCH 05/11] powerpc/nvram: Completely clear a new partition Michael Ellerman
2010-08-02  3:47       ` [PATCH 03/11] powerpc/nvram: nvram_create_partitions() now uses bytes Michael Ellerman
2010-08-02  3:43     ` [PATCH 02/11] powerpc/nvram: More flexible nvram_create_partition() Michael Ellerman
2010-08-02  3:54       ` Benjamin Herrenschmidt
2010-08-02  7:02     ` Benjamin Herrenschmidt

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=1280710522-6362-7-git-send-email-benh@kernel.crashing.org \
    --to=benh@kernel.crashing.org \
    --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).