public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Chen Gong <gong.chen@linux.intel.com>
To: tony.luck@intel.com, mjg59@srcf.ucam.org
Cc: linux-kernel@vger.kernel.org, Chen Gong <gong.chen@linux.intel.com>
Subject: [PATCH 2/2] pstore: update the policy of the UEFI-based backend
Date: Sat,  3 Sep 2011 13:30:17 +0800	[thread overview]
Message-ID: <1315027817-5316-3-git-send-email-gong.chen@linux.intel.com> (raw)
In-Reply-To: <1315027817-5316-1-git-send-email-gong.chen@linux.intel.com>

UEFI-based backend only employs one group records to save
dumped information, which means new log will overwrite old one.
It doesn't make sense because in fact the older log is nearer
to the truth. Update its policy to comply with ERST logic.

Signed-off-by: Chen Gong <gong.chen@linux.intel.com>
---
 drivers/firmware/efivars.c |  108 +++++++++++++++++++++++++------------------
 1 files changed, 63 insertions(+), 45 deletions(-)

diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index fe07673..f33302d 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -463,8 +463,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
 	struct efivars *efivars = psi->data;
 	char name[DUMP_NAME_LEN];
 	int i;
-	unsigned int part, size;
-	unsigned long time;
+	unsigned int size;
 
 	while (&efivars->walk_entry->list != &efivars->list) {
 		if (!efi_guidcmp(efivars->walk_entry->var.VendorGuid,
@@ -472,9 +471,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
 			for (i = 0; i < DUMP_NAME_LEN; i++) {
 				name[i] = efivars->walk_entry->var.VariableName[i];
 			}
-			if (sscanf(name, "dump-type%u-%u-%lu", type, &part, &time) == 3) {
-				*id = part;
-				timespec->tv_sec = time;
+			if (sscanf(name, "dump-type%u-%llu", type, id) == 2) {
+				timespec->tv_sec = *id;
 				timespec->tv_nsec = 0;
 				get_var_data_locked(efivars, &efivars->walk_entry->var);
 				size = efivars->walk_entry->var.DataSize;
@@ -494,24 +492,59 @@ static int efi_pstore_write(enum pstore_type_id type, u64 *id,
 		unsigned int part, size_t size, struct pstore_info *psi)
 {
 	char name[DUMP_NAME_LEN];
+	efi_char16_t efi_name[DUMP_NAME_LEN];
+	efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
+	struct efivars *efivars = psi->data;
+	efi_status_t status = EFI_NOT_FOUND;
+	int i, ret;
+	unsigned int time;
+
+	if (size == 0)
+		return -1;
+
+	time = get_seconds();
+	/* assume time + part = monotonic increasing */
+	*id = time + part;
+	sprintf(name, "dump-type%u-%llu", type, *id);
+
+	spin_lock(&efivars->lock);
+
+	for (i = 0; i < DUMP_NAME_LEN; i++)
+		efi_name[i] = name[i];
+
+	status = efivars->ops->set_variable(efi_name, &vendor,
+		PSTORE_EFI_ATTRIBUTES, size, psi->buf);
+	spin_unlock(&efivars->lock);
+
+	if (status != EFI_SUCCESS) {
+		printk(KERN_WARNING "efivars: set_variable() failed: "
+			"status=%lx\n", status);
+		return -EIO;
+	}
+
+	ret = efivar_create_sysfs_entry(efivars,
+		utf16_strsize(efi_name, DUMP_NAME_LEN * 2), efi_name, &vendor);
+
+	return ret;
+};
+
+static int efi_pstore_erase(enum pstore_type_id type, u64 id,
+			    struct pstore_info *psi)
+{
 	char stub_name[DUMP_NAME_LEN];
 	efi_char16_t efi_name[DUMP_NAME_LEN];
 	efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 	struct efivars *efivars = psi->data;
 	struct efivar_entry *entry, *found = NULL;
-	int i, ret = 0;
-
-	sprintf(stub_name, "dump-type%u-%u-", type, part);
-	sprintf(name, "%s%lu", stub_name, get_seconds());
+	efi_status_t status = EFI_NOT_FOUND;
+	int i;
 
-	spin_lock(&efivars->lock);
+	sprintf(stub_name, "dump-type%u-%llu", type, id);
 
 	for (i = 0; i < DUMP_NAME_LEN; i++)
 		efi_name[i] = stub_name[i];
 
-	/*
-	 * Clean up any entries with the same name
-	 */
+	spin_lock(&efivars->lock);
 
 	list_for_each_entry(entry, &efivars->list, list) {
 		get_var_data_locked(efivars, &entry->var);
@@ -521,46 +554,31 @@ static int efi_pstore_write(enum pstore_type_id type, u64 *id,
 		if (utf16_strncmp(entry->var.VariableName, efi_name,
 				  utf16_strlen(efi_name)))
 			continue;
-		/* Needs to be a prefix */
-		if (entry->var.VariableName[utf16_strlen(efi_name)] == 0)
-			continue;
 
 		/* found */
 		found = entry;
-		efivars->ops->set_variable(entry->var.VariableName,
-					   &entry->var.VendorGuid,
-					   PSTORE_EFI_ATTRIBUTES,
-					   0, NULL);
+		break;
 	}
 
-	if (found)
-		list_del(&found->list);
-
-	for (i = 0; i < DUMP_NAME_LEN; i++)
-		efi_name[i] = name[i];
+	if (!found) {
+		spin_unlock(&efivars->lock);
+		return -EINVAL;
+	}
 
-	efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
-				   size, psi->buf);
+	status = efivars->ops->set_variable(entry->var.VariableName,
+				   &entry->var.VendorGuid,
+				   PSTORE_EFI_ATTRIBUTES,
+				   0, NULL);
+	if (status != EFI_SUCCESS) {
+		printk(KERN_WARNING "efivars: set_variable() failed: "
+			"status=%lx\n", status);
+		spin_unlock(&efivars->lock);
+		return -EIO;
+	}
 
+	list_del(&found->list);
 	spin_unlock(&efivars->lock);
-
-	if (found)
-		efivar_unregister(found);
-
-	if (size)
-		ret = efivar_create_sysfs_entry(efivars,
-					  utf16_strsize(efi_name,
-							DUMP_NAME_LEN * 2),
-					  efi_name, &vendor);
-
-	*id = part;
-	return ret;
-};
-
-static int efi_pstore_erase(enum pstore_type_id type, u64 id,
-			    struct pstore_info *psi)
-{
-	efi_pstore_write(type, &id, (unsigned int)id, 0, psi);
+	efivar_unregister(found);
 
 	return 0;
 }
-- 
1.7.7.rc0.70.g82660


  parent reply	other threads:[~2011-09-03  5:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-03  5:30 pstore: enhancement for pstore write interface Chen Gong
2011-09-03  5:30 ` [PATCH 1/2] pstore: change the purpose of return value for pstore write operation Chen Gong
2011-09-03  5:30 ` Chen Gong [this message]
2011-09-03 12:36   ` [PATCH 2/2] pstore: update the policy of the UEFI-based backend Matthew Garrett

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=1315027817-5316-3-git-send-email-gong.chen@linux.intel.com \
    --to=gong.chen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=tony.luck@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox