Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

<Example>

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 <seiji.aguchi@hds.com>
Acked-by: Mike Waychison <mikew@google.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by

Seiji Aguchi and committed by
Tony Luck
a9efd39c 96480d9c

+14 -14
+2 -2
drivers/acpi/apei/erst.c
··· 938 938 u64 *id, unsigned int part, 939 939 size_t size, struct pstore_info *psi); 940 940 static int erst_clearer(enum pstore_type_id type, u64 id, 941 - struct pstore_info *psi); 941 + struct timespec time, struct pstore_info *psi); 942 942 943 943 static struct pstore_info erst_info = { 944 944 .owner = THIS_MODULE, ··· 1102 1102 } 1103 1103 1104 1104 static int erst_clearer(enum pstore_type_id type, u64 id, 1105 - struct pstore_info *psi) 1105 + struct timespec time, struct pstore_info *psi) 1106 1106 { 1107 1107 return erst_clear(id); 1108 1108 }
+8 -9
drivers/firmware/efivars.c
··· 747 747 }; 748 748 749 749 static int efi_pstore_erase(enum pstore_type_id type, u64 id, 750 - struct pstore_info *psi) 750 + struct timespec time, struct pstore_info *psi) 751 751 { 752 - char stub_name[DUMP_NAME_LEN]; 752 + char name[DUMP_NAME_LEN]; 753 753 efi_char16_t efi_name[DUMP_NAME_LEN]; 754 754 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 755 755 struct efivars *efivars = psi->data; 756 756 struct efivar_entry *entry, *found = NULL; 757 757 int i; 758 758 759 - sprintf(stub_name, "dump-type%u-%u-", type, (unsigned int)id); 759 + sprintf(name, "dump-type%u-%u-%lu", type, (unsigned int)id, 760 + time.tv_sec); 760 761 761 762 spin_lock(&efivars->lock); 762 763 763 764 for (i = 0; i < DUMP_NAME_LEN; i++) 764 - efi_name[i] = stub_name[i]; 765 + efi_name[i] = name[i]; 765 766 766 767 /* 767 - * Clean up any entries with the same name 768 + * Clean up an entry with the same name 768 769 */ 769 770 770 771 list_for_each_entry(entry, &efivars->list, list) { ··· 776 775 if (utf16_strncmp(entry->var.VariableName, efi_name, 777 776 utf16_strlen(efi_name))) 778 777 continue; 779 - /* Needs to be a prefix */ 780 - if (entry->var.VariableName[utf16_strlen(efi_name)] == 0) 781 - continue; 782 778 783 779 /* found */ 784 780 found = entry; ··· 783 785 &entry->var.VendorGuid, 784 786 PSTORE_EFI_ATTRIBUTES, 785 787 0, NULL); 788 + break; 786 789 } 787 790 788 791 if (found) ··· 822 823 } 823 824 824 825 static int efi_pstore_erase(enum pstore_type_id type, u64 id, 825 - struct pstore_info *psi) 826 + struct timespec time, struct pstore_info *psi) 826 827 { 827 828 return 0; 828 829 }
+2 -1
fs/pstore/inode.c
··· 175 175 struct pstore_private *p = dentry->d_inode->i_private; 176 176 177 177 if (p->psi->erase) 178 - p->psi->erase(p->type, p->id, p->psi); 178 + p->psi->erase(p->type, p->id, dentry->d_inode->i_ctime, 179 + p->psi); 179 180 180 181 return simple_unlink(dir, dentry); 181 182 }
+1 -1
fs/pstore/ram.c
··· 237 237 } 238 238 239 239 static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, 240 - struct pstore_info *psi) 240 + struct timespec time, struct pstore_info *psi) 241 241 { 242 242 struct ramoops_context *cxt = psi->data; 243 243 struct persistent_ram_zone *prz;
+1 -1
include/linux/pstore.h
··· 60 60 unsigned int part, const char *buf, size_t size, 61 61 struct pstore_info *psi); 62 62 int (*erase)(enum pstore_type_id type, u64 id, 63 - struct pstore_info *psi); 63 + struct timespec time, struct pstore_info *psi); 64 64 void *data; 65 65 }; 66 66