From a9efd39cd547223597cfe7c53acec44c099b9264 Mon Sep 17 00:00:00 2001 From: Seiji Aguchi Date: Wed, 14 Nov 2012 20:27:28 +0000 Subject: efi_pstore: Add ctime to argument of erase callback [Issue] Currently, a variable name, which is used to identify each log entry, consists of type, id and ctime. But an erase callback does not use ctime. If efi_pstore supported just one log, type and id were enough. However, in case of supporting multiple logs, it doesn't work because it can't distinguish each entry without ctime at erasing time. As you can see below, efi_pstore can't differentiate first event from second one without ctime. a variable name of first event: dump-type0-1-12345678 a variable name of second event: dump-type0-1-23456789 type:0 id:1 ctime:12345678, 23456789 [Solution] This patch adds ctime to an argument of an erase callback. It works across reboots because ctime of pstore means the date that the record was originally stored. To do this, efi_pstore saves the ctime to variable name at writing time and passes it to pstore at reading time. Signed-off-by: Seiji Aguchi Acked-by: Mike Waychison Signed-off-by: Tony Luck --- drivers/firmware/efivars.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index fbe9202c2678..3803621c0d45 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -747,24 +747,25 @@ static int efi_pstore_write(enum pstore_type_id type, }; static int efi_pstore_erase(enum pstore_type_id type, u64 id, - struct pstore_info *psi) + struct timespec time, struct pstore_info *psi) { - char stub_name[DUMP_NAME_LEN]; + 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; struct efivar_entry *entry, *found = NULL; int i; - sprintf(stub_name, "dump-type%u-%u-", type, (unsigned int)id); + sprintf(name, "dump-type%u-%u-%lu", type, (unsigned int)id, + time.tv_sec); spin_lock(&efivars->lock); for (i = 0; i < DUMP_NAME_LEN; i++) - efi_name[i] = stub_name[i]; + efi_name[i] = name[i]; /* - * Clean up any entries with the same name + * Clean up an entry with the same name */ list_for_each_entry(entry, &efivars->list, list) { @@ -775,9 +776,6 @@ static int efi_pstore_erase(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; @@ -785,6 +783,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, &entry->var.VendorGuid, PSTORE_EFI_ATTRIBUTES, 0, NULL); + break; } if (found) @@ -823,7 +822,7 @@ static int efi_pstore_write(enum pstore_type_id type, } static int efi_pstore_erase(enum pstore_type_id type, u64 id, - struct pstore_info *psi) + struct timespec time, struct pstore_info *psi) { return 0; } -- cgit v1.2.3