diff options
author | Seiji Aguchi <seiji.aguchi@hds.com> | 2012-11-14 15:28:50 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2012-11-26 19:08:30 -0500 |
commit | 0f7de85a94de553c6cb222b70ac4032d265b362d (patch) | |
tree | 9d9dbb7ade849ef391c2464393531c44c1d2e15e /drivers/firmware | |
parent | 755d4fe46529018ae45bc7c86df682de45ace764 (diff) |
efi_pstore: Add a format check for an existing variable name at reading time
[Issue]
a format of variable name has been updated to type, id, count and ctime
to support holding multiple logs.
Format of current variable name
dump-type0-1-2-12345678
type:0
id:1
count:2
ctime:12345678
On the other hand, if an old variable name before being updated
remains, users can't read it via /dev/pstore.
Format of old variable name
dump-type0-1-12345678
type:0
id:1
ctime:12345678
[Solution]
This patch add a format check for the old variable name in a read callback
to make it readable.
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>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efivars.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 7ad3aae6e085..bf7a6f994a3c 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -681,17 +681,35 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | |||
681 | *count = cnt; | 681 | *count = cnt; |
682 | timespec->tv_sec = time; | 682 | timespec->tv_sec = time; |
683 | timespec->tv_nsec = 0; | 683 | timespec->tv_nsec = 0; |
684 | get_var_data_locked(efivars, &efivars->walk_entry->var); | 684 | } else if (sscanf(name, "dump-type%u-%u-%lu", |
685 | size = efivars->walk_entry->var.DataSize; | 685 | type, &part, &time) == 3) { |
686 | *buf = kmalloc(size, GFP_KERNEL); | 686 | /* |
687 | if (*buf == NULL) | 687 | * Check if an old format, |
688 | return -ENOMEM; | 688 | * which doesn't support holding |
689 | memcpy(*buf, efivars->walk_entry->var.Data, | 689 | * multiple logs, remains. |
690 | size); | 690 | */ |
691 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, | 691 | *id = part; |
692 | struct efivar_entry, list); | 692 | *count = 0; |
693 | return size; | 693 | timespec->tv_sec = time; |
694 | timespec->tv_nsec = 0; | ||
695 | } else { | ||
696 | efivars->walk_entry = list_entry( | ||
697 | efivars->walk_entry->list.next, | ||
698 | struct efivar_entry, list); | ||
699 | continue; | ||
694 | } | 700 | } |
701 | |||
702 | get_var_data_locked(efivars, &efivars->walk_entry->var); | ||
703 | size = efivars->walk_entry->var.DataSize; | ||
704 | *buf = kmalloc(size, GFP_KERNEL); | ||
705 | if (*buf == NULL) | ||
706 | return -ENOMEM; | ||
707 | memcpy(*buf, efivars->walk_entry->var.Data, | ||
708 | size); | ||
709 | efivars->walk_entry = list_entry( | ||
710 | efivars->walk_entry->list.next, | ||
711 | struct efivar_entry, list); | ||
712 | return size; | ||
695 | } | 713 | } |
696 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, | 714 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, |
697 | struct efivar_entry, list); | 715 | struct efivar_entry, list); |