diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 10:50:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 10:50:59 -0500 |
commit | 251a8cfeda7c8a0ff26c62659a2358d3b4ff32df (patch) | |
tree | 8bff8895744c4eb159124a62750e89dadd9d17f8 | |
parent | 70f2836d023237868f2fef3625da84643e5aaf33 (diff) | |
parent | f94ec0c0594ef73ab3a2f1f32735aca8ddaf65e2 (diff) |
Merge tag 'please-pull-pstore_mevent' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull pstore fixes from Tony Luck:
"Patch series to allow EFI variable backend to pstore to hold multiple
records."
* tag 'please-pull-pstore_mevent' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
efi_pstore: Add a format check for an existing variable name at erasing time
efi_pstore: Add a format check for an existing variable name at reading time
efi_pstore: Add a sequence counter to a variable name
efi_pstore: Add ctime to argument of erase callback
efi_pstore: Remove a logic erasing entries from a write callback to hold multiple logs
efi_pstore: Add a logic erasing entries to an erase callback
efi_pstore: Check remaining space with QueryVariableInfo() before writing data
-rw-r--r-- | drivers/acpi/apei/erst.c | 16 | ||||
-rw-r--r-- | drivers/firmware/efivars.c | 163 | ||||
-rw-r--r-- | fs/pstore/inode.c | 7 | ||||
-rw-r--r-- | fs/pstore/internal.h | 2 | ||||
-rw-r--r-- | fs/pstore/platform.c | 13 | ||||
-rw-r--r-- | fs/pstore/ram.c | 9 | ||||
-rw-r--r-- | include/linux/efi.h | 1 | ||||
-rw-r--r-- | include/linux/pstore.h | 6 |
8 files changed, 144 insertions, 73 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index e4d9d24eb73d..6d894bfd8b8f 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -931,14 +931,14 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
931 | 931 | ||
932 | static int erst_open_pstore(struct pstore_info *psi); | 932 | static int erst_open_pstore(struct pstore_info *psi); |
933 | static int erst_close_pstore(struct pstore_info *psi); | 933 | static int erst_close_pstore(struct pstore_info *psi); |
934 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | 934 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count, |
935 | struct timespec *time, char **buf, | 935 | struct timespec *time, char **buf, |
936 | struct pstore_info *psi); | 936 | struct pstore_info *psi); |
937 | static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, | 937 | static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, |
938 | u64 *id, unsigned int part, | 938 | u64 *id, unsigned int part, int count, |
939 | size_t size, struct pstore_info *psi); | 939 | size_t size, struct pstore_info *psi); |
940 | static int erst_clearer(enum pstore_type_id type, u64 id, | 940 | static int erst_clearer(enum pstore_type_id type, u64 id, int count, |
941 | struct pstore_info *psi); | 941 | struct timespec time, struct pstore_info *psi); |
942 | 942 | ||
943 | static struct pstore_info erst_info = { | 943 | static struct pstore_info erst_info = { |
944 | .owner = THIS_MODULE, | 944 | .owner = THIS_MODULE, |
@@ -987,7 +987,7 @@ static int erst_close_pstore(struct pstore_info *psi) | |||
987 | return 0; | 987 | return 0; |
988 | } | 988 | } |
989 | 989 | ||
990 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | 990 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count, |
991 | struct timespec *time, char **buf, | 991 | struct timespec *time, char **buf, |
992 | struct pstore_info *psi) | 992 | struct pstore_info *psi) |
993 | { | 993 | { |
@@ -1055,7 +1055,7 @@ out: | |||
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, | 1057 | static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, |
1058 | u64 *id, unsigned int part, | 1058 | u64 *id, unsigned int part, int count, |
1059 | size_t size, struct pstore_info *psi) | 1059 | size_t size, struct pstore_info *psi) |
1060 | { | 1060 | { |
1061 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) | 1061 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) |
@@ -1101,8 +1101,8 @@ static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason, | |||
1101 | return ret; | 1101 | return ret; |
1102 | } | 1102 | } |
1103 | 1103 | ||
1104 | static int erst_clearer(enum pstore_type_id type, u64 id, | 1104 | static int erst_clearer(enum pstore_type_id type, u64 id, int count, |
1105 | struct pstore_info *psi) | 1105 | struct timespec time, struct pstore_info *psi) |
1106 | { | 1106 | { |
1107 | return erst_clear(id); | 1107 | return erst_clear(id); |
1108 | } | 1108 | } |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index d10c9873dd9a..6e51c1e81f14 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -658,13 +658,14 @@ static int efi_pstore_close(struct pstore_info *psi) | |||
658 | } | 658 | } |
659 | 659 | ||
660 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | 660 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, |
661 | struct timespec *timespec, | 661 | int *count, struct timespec *timespec, |
662 | char **buf, struct pstore_info *psi) | 662 | char **buf, struct pstore_info *psi) |
663 | { | 663 | { |
664 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; | 664 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; |
665 | struct efivars *efivars = psi->data; | 665 | struct efivars *efivars = psi->data; |
666 | char name[DUMP_NAME_LEN]; | 666 | char name[DUMP_NAME_LEN]; |
667 | int i; | 667 | int i; |
668 | int cnt; | ||
668 | unsigned int part, size; | 669 | unsigned int part, size; |
669 | unsigned long time; | 670 | unsigned long time; |
670 | 671 | ||
@@ -674,21 +675,41 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | |||
674 | for (i = 0; i < DUMP_NAME_LEN; i++) { | 675 | for (i = 0; i < DUMP_NAME_LEN; i++) { |
675 | name[i] = efivars->walk_entry->var.VariableName[i]; | 676 | name[i] = efivars->walk_entry->var.VariableName[i]; |
676 | } | 677 | } |
677 | if (sscanf(name, "dump-type%u-%u-%lu", type, &part, &time) == 3) { | 678 | if (sscanf(name, "dump-type%u-%u-%d-%lu", |
679 | type, &part, &cnt, &time) == 4) { | ||
680 | *id = part; | ||
681 | *count = cnt; | ||
682 | timespec->tv_sec = time; | ||
683 | timespec->tv_nsec = 0; | ||
684 | } else if (sscanf(name, "dump-type%u-%u-%lu", | ||
685 | type, &part, &time) == 3) { | ||
686 | /* | ||
687 | * Check if an old format, | ||
688 | * which doesn't support holding | ||
689 | * multiple logs, remains. | ||
690 | */ | ||
678 | *id = part; | 691 | *id = part; |
692 | *count = 0; | ||
679 | timespec->tv_sec = time; | 693 | timespec->tv_sec = time; |
680 | timespec->tv_nsec = 0; | 694 | timespec->tv_nsec = 0; |
681 | get_var_data_locked(efivars, &efivars->walk_entry->var); | 695 | } else { |
682 | size = efivars->walk_entry->var.DataSize; | 696 | efivars->walk_entry = list_entry( |
683 | *buf = kmalloc(size, GFP_KERNEL); | 697 | efivars->walk_entry->list.next, |
684 | if (*buf == NULL) | 698 | struct efivar_entry, list); |
685 | return -ENOMEM; | 699 | continue; |
686 | memcpy(*buf, efivars->walk_entry->var.Data, | ||
687 | size); | ||
688 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, | ||
689 | struct efivar_entry, list); | ||
690 | return size; | ||
691 | } | 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; | ||
692 | } | 713 | } |
693 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, | 714 | efivars->walk_entry = list_entry(efivars->walk_entry->list.next, |
694 | struct efivar_entry, list); | 715 | struct efivar_entry, list); |
@@ -698,26 +719,77 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | |||
698 | 719 | ||
699 | static int efi_pstore_write(enum pstore_type_id type, | 720 | static int efi_pstore_write(enum pstore_type_id type, |
700 | enum kmsg_dump_reason reason, u64 *id, | 721 | enum kmsg_dump_reason reason, u64 *id, |
701 | unsigned int part, size_t size, struct pstore_info *psi) | 722 | unsigned int part, int count, size_t size, |
723 | struct pstore_info *psi) | ||
702 | { | 724 | { |
703 | char name[DUMP_NAME_LEN]; | 725 | char name[DUMP_NAME_LEN]; |
704 | char stub_name[DUMP_NAME_LEN]; | ||
705 | efi_char16_t efi_name[DUMP_NAME_LEN]; | 726 | efi_char16_t efi_name[DUMP_NAME_LEN]; |
706 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; | 727 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; |
707 | struct efivars *efivars = psi->data; | 728 | struct efivars *efivars = psi->data; |
708 | struct efivar_entry *entry, *found = NULL; | ||
709 | int i, ret = 0; | 729 | int i, ret = 0; |
730 | u64 storage_space, remaining_space, max_variable_size; | ||
731 | efi_status_t status = EFI_NOT_FOUND; | ||
732 | |||
733 | spin_lock(&efivars->lock); | ||
734 | |||
735 | /* | ||
736 | * Check if there is a space enough to log. | ||
737 | * size: a size of logging data | ||
738 | * DUMP_NAME_LEN * 2: a maximum size of variable name | ||
739 | */ | ||
740 | status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES, | ||
741 | &storage_space, | ||
742 | &remaining_space, | ||
743 | &max_variable_size); | ||
744 | if (status || remaining_space < size + DUMP_NAME_LEN * 2) { | ||
745 | spin_unlock(&efivars->lock); | ||
746 | *id = part; | ||
747 | return -ENOSPC; | ||
748 | } | ||
749 | |||
750 | sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, | ||
751 | get_seconds()); | ||
752 | |||
753 | for (i = 0; i < DUMP_NAME_LEN; i++) | ||
754 | efi_name[i] = name[i]; | ||
755 | |||
756 | efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES, | ||
757 | size, psi->buf); | ||
758 | |||
759 | spin_unlock(&efivars->lock); | ||
760 | |||
761 | if (size) | ||
762 | ret = efivar_create_sysfs_entry(efivars, | ||
763 | utf16_strsize(efi_name, | ||
764 | DUMP_NAME_LEN * 2), | ||
765 | efi_name, &vendor); | ||
766 | |||
767 | *id = part; | ||
768 | return ret; | ||
769 | }; | ||
770 | |||
771 | static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, | ||
772 | struct timespec time, struct pstore_info *psi) | ||
773 | { | ||
774 | char name[DUMP_NAME_LEN]; | ||
775 | efi_char16_t efi_name[DUMP_NAME_LEN]; | ||
776 | char name_old[DUMP_NAME_LEN]; | ||
777 | efi_char16_t efi_name_old[DUMP_NAME_LEN]; | ||
778 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; | ||
779 | struct efivars *efivars = psi->data; | ||
780 | struct efivar_entry *entry, *found = NULL; | ||
781 | int i; | ||
710 | 782 | ||
711 | sprintf(stub_name, "dump-type%u-%u-", type, part); | 783 | sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, |
712 | sprintf(name, "%s%lu", stub_name, get_seconds()); | 784 | time.tv_sec); |
713 | 785 | ||
714 | spin_lock(&efivars->lock); | 786 | spin_lock(&efivars->lock); |
715 | 787 | ||
716 | for (i = 0; i < DUMP_NAME_LEN; i++) | 788 | for (i = 0; i < DUMP_NAME_LEN; i++) |
717 | efi_name[i] = stub_name[i]; | 789 | efi_name[i] = name[i]; |
718 | 790 | ||
719 | /* | 791 | /* |
720 | * Clean up any entries with the same name | 792 | * Clean up an entry with the same name |
721 | */ | 793 | */ |
722 | 794 | ||
723 | list_for_each_entry(entry, &efivars->list, list) { | 795 | list_for_each_entry(entry, &efivars->list, list) { |
@@ -726,11 +798,22 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
726 | if (efi_guidcmp(entry->var.VendorGuid, vendor)) | 798 | if (efi_guidcmp(entry->var.VendorGuid, vendor)) |
727 | continue; | 799 | continue; |
728 | if (utf16_strncmp(entry->var.VariableName, efi_name, | 800 | if (utf16_strncmp(entry->var.VariableName, efi_name, |
729 | utf16_strlen(efi_name))) | 801 | utf16_strlen(efi_name))) { |
730 | continue; | 802 | /* |
731 | /* Needs to be a prefix */ | 803 | * Check if an old format, |
732 | if (entry->var.VariableName[utf16_strlen(efi_name)] == 0) | 804 | * which doesn't support holding |
733 | continue; | 805 | * multiple logs, remains. |
806 | */ | ||
807 | sprintf(name_old, "dump-type%u-%u-%lu", type, | ||
808 | (unsigned int)id, time.tv_sec); | ||
809 | |||
810 | for (i = 0; i < DUMP_NAME_LEN; i++) | ||
811 | efi_name_old[i] = name_old[i]; | ||
812 | |||
813 | if (utf16_strncmp(entry->var.VariableName, efi_name_old, | ||
814 | utf16_strlen(efi_name_old))) | ||
815 | continue; | ||
816 | } | ||
734 | 817 | ||
735 | /* found */ | 818 | /* found */ |
736 | found = entry; | 819 | found = entry; |
@@ -738,37 +821,17 @@ static int efi_pstore_write(enum pstore_type_id type, | |||
738 | &entry->var.VendorGuid, | 821 | &entry->var.VendorGuid, |
739 | PSTORE_EFI_ATTRIBUTES, | 822 | PSTORE_EFI_ATTRIBUTES, |
740 | 0, NULL); | 823 | 0, NULL); |
824 | break; | ||
741 | } | 825 | } |
742 | 826 | ||
743 | if (found) | 827 | if (found) |
744 | list_del(&found->list); | 828 | list_del(&found->list); |
745 | 829 | ||
746 | for (i = 0; i < DUMP_NAME_LEN; i++) | ||
747 | efi_name[i] = name[i]; | ||
748 | |||
749 | efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES, | ||
750 | size, psi->buf); | ||
751 | |||
752 | spin_unlock(&efivars->lock); | 830 | spin_unlock(&efivars->lock); |
753 | 831 | ||
754 | if (found) | 832 | if (found) |
755 | efivar_unregister(found); | 833 | efivar_unregister(found); |
756 | 834 | ||
757 | if (size) | ||
758 | ret = efivar_create_sysfs_entry(efivars, | ||
759 | utf16_strsize(efi_name, | ||
760 | DUMP_NAME_LEN * 2), | ||
761 | efi_name, &vendor); | ||
762 | |||
763 | *id = part; | ||
764 | return ret; | ||
765 | }; | ||
766 | |||
767 | static int efi_pstore_erase(enum pstore_type_id type, u64 id, | ||
768 | struct pstore_info *psi) | ||
769 | { | ||
770 | efi_pstore_write(type, 0, &id, (unsigned int)id, 0, psi); | ||
771 | |||
772 | return 0; | 835 | return 0; |
773 | } | 836 | } |
774 | #else | 837 | #else |
@@ -782,7 +845,7 @@ static int efi_pstore_close(struct pstore_info *psi) | |||
782 | return 0; | 845 | return 0; |
783 | } | 846 | } |
784 | 847 | ||
785 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | 848 | static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count, |
786 | struct timespec *timespec, | 849 | struct timespec *timespec, |
787 | char **buf, struct pstore_info *psi) | 850 | char **buf, struct pstore_info *psi) |
788 | { | 851 | { |
@@ -791,13 +854,14 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, | |||
791 | 854 | ||
792 | static int efi_pstore_write(enum pstore_type_id type, | 855 | static int efi_pstore_write(enum pstore_type_id type, |
793 | enum kmsg_dump_reason reason, u64 *id, | 856 | enum kmsg_dump_reason reason, u64 *id, |
794 | unsigned int part, size_t size, struct pstore_info *psi) | 857 | unsigned int part, int count, size_t size, |
858 | struct pstore_info *psi) | ||
795 | { | 859 | { |
796 | return 0; | 860 | return 0; |
797 | } | 861 | } |
798 | 862 | ||
799 | static int efi_pstore_erase(enum pstore_type_id type, u64 id, | 863 | static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, |
800 | struct pstore_info *psi) | 864 | struct timespec time, struct pstore_info *psi) |
801 | { | 865 | { |
802 | return 0; | 866 | return 0; |
803 | } | 867 | } |
@@ -1237,6 +1301,7 @@ efivars_init(void) | |||
1237 | ops.get_variable = efi.get_variable; | 1301 | ops.get_variable = efi.get_variable; |
1238 | ops.set_variable = efi.set_variable; | 1302 | ops.set_variable = efi.set_variable; |
1239 | ops.get_next_variable = efi.get_next_variable; | 1303 | ops.get_next_variable = efi.get_next_variable; |
1304 | ops.query_variable_info = efi.query_variable_info; | ||
1240 | error = register_efivars(&__efivars, &ops, efi_kobj); | 1305 | error = register_efivars(&__efivars, &ops, efi_kobj); |
1241 | if (error) | 1306 | if (error) |
1242 | goto err_put; | 1307 | goto err_put; |
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 4ab572e6d277..ed1d8c7212da 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
@@ -49,6 +49,7 @@ struct pstore_private { | |||
49 | struct pstore_info *psi; | 49 | struct pstore_info *psi; |
50 | enum pstore_type_id type; | 50 | enum pstore_type_id type; |
51 | u64 id; | 51 | u64 id; |
52 | int count; | ||
52 | ssize_t size; | 53 | ssize_t size; |
53 | char data[]; | 54 | char data[]; |
54 | }; | 55 | }; |
@@ -175,7 +176,8 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) | |||
175 | struct pstore_private *p = dentry->d_inode->i_private; | 176 | struct pstore_private *p = dentry->d_inode->i_private; |
176 | 177 | ||
177 | if (p->psi->erase) | 178 | if (p->psi->erase) |
178 | p->psi->erase(p->type, p->id, p->psi); | 179 | p->psi->erase(p->type, p->id, p->count, |
180 | dentry->d_inode->i_ctime, p->psi); | ||
179 | 181 | ||
180 | return simple_unlink(dir, dentry); | 182 | return simple_unlink(dir, dentry); |
181 | } | 183 | } |
@@ -270,7 +272,7 @@ int pstore_is_mounted(void) | |||
270 | * Load it up with "size" bytes of data from "buf". | 272 | * Load it up with "size" bytes of data from "buf". |
271 | * Set the mtime & ctime to the date that this record was originally stored. | 273 | * Set the mtime & ctime to the date that this record was originally stored. |
272 | */ | 274 | */ |
273 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, | 275 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, |
274 | char *data, size_t size, struct timespec time, | 276 | char *data, size_t size, struct timespec time, |
275 | struct pstore_info *psi) | 277 | struct pstore_info *psi) |
276 | { | 278 | { |
@@ -306,6 +308,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, | |||
306 | goto fail_alloc; | 308 | goto fail_alloc; |
307 | private->type = type; | 309 | private->type = type; |
308 | private->id = id; | 310 | private->id = id; |
311 | private->count = count; | ||
309 | private->psi = psi; | 312 | private->psi = psi; |
310 | 313 | ||
311 | switch (type) { | 314 | switch (type) { |
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index 4847f588b7d5..937d820f273c 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h | |||
@@ -50,7 +50,7 @@ extern struct pstore_info *psinfo; | |||
50 | extern void pstore_set_kmsg_bytes(int); | 50 | extern void pstore_set_kmsg_bytes(int); |
51 | extern void pstore_get_records(int); | 51 | extern void pstore_get_records(int); |
52 | extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, | 52 | extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, |
53 | char *data, size_t size, | 53 | int count, char *data, size_t size, |
54 | struct timespec time, struct pstore_info *psi); | 54 | struct timespec time, struct pstore_info *psi); |
55 | extern int pstore_is_mounted(void); | 55 | extern int pstore_is_mounted(void); |
56 | 56 | ||
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 947fbe06c3b1..5ea2e77ff023 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -136,7 +136,7 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
136 | break; | 136 | break; |
137 | 137 | ||
138 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, | 138 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, |
139 | hsize + len, psinfo); | 139 | oopscount, hsize + len, psinfo); |
140 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) | 140 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) |
141 | pstore_new_entry = 1; | 141 | pstore_new_entry = 1; |
142 | 142 | ||
@@ -173,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) | |||
173 | spin_lock_irqsave(&psinfo->buf_lock, flags); | 173 | spin_lock_irqsave(&psinfo->buf_lock, flags); |
174 | } | 174 | } |
175 | memcpy(psinfo->buf, s, c); | 175 | memcpy(psinfo->buf, s, c); |
176 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); | 176 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, c, psinfo); |
177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); | 177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
178 | s += c; | 178 | s += c; |
179 | c = e - s; | 179 | c = e - s; |
@@ -197,7 +197,7 @@ static void pstore_register_console(void) {} | |||
197 | 197 | ||
198 | static int pstore_write_compat(enum pstore_type_id type, | 198 | static int pstore_write_compat(enum pstore_type_id type, |
199 | enum kmsg_dump_reason reason, | 199 | enum kmsg_dump_reason reason, |
200 | u64 *id, unsigned int part, | 200 | u64 *id, unsigned int part, int count, |
201 | size_t size, struct pstore_info *psi) | 201 | size_t size, struct pstore_info *psi) |
202 | { | 202 | { |
203 | return psi->write_buf(type, reason, id, part, psinfo->buf, size, psi); | 203 | return psi->write_buf(type, reason, id, part, psinfo->buf, size, psi); |
@@ -267,6 +267,7 @@ void pstore_get_records(int quiet) | |||
267 | char *buf = NULL; | 267 | char *buf = NULL; |
268 | ssize_t size; | 268 | ssize_t size; |
269 | u64 id; | 269 | u64 id; |
270 | int count; | ||
270 | enum pstore_type_id type; | 271 | enum pstore_type_id type; |
271 | struct timespec time; | 272 | struct timespec time; |
272 | int failed = 0, rc; | 273 | int failed = 0, rc; |
@@ -278,9 +279,9 @@ void pstore_get_records(int quiet) | |||
278 | if (psi->open && psi->open(psi)) | 279 | if (psi->open && psi->open(psi)) |
279 | goto out; | 280 | goto out; |
280 | 281 | ||
281 | while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) { | 282 | while ((size = psi->read(&id, &type, &count, &time, &buf, psi)) > 0) { |
282 | rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size, | 283 | rc = pstore_mkfile(type, psi->name, id, count, buf, |
283 | time, psi); | 284 | (size_t)size, time, psi); |
284 | kfree(buf); | 285 | kfree(buf); |
285 | buf = NULL; | 286 | buf = NULL; |
286 | if (rc && (rc != -EEXIST || !quiet)) | 287 | if (rc && (rc != -EEXIST || !quiet)) |
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 1a4f6da58eab..2bfa36e0ffe8 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -132,9 +132,8 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, | |||
132 | } | 132 | } |
133 | 133 | ||
134 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | 134 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, |
135 | struct timespec *time, | 135 | int *count, struct timespec *time, |
136 | char **buf, | 136 | char **buf, struct pstore_info *psi) |
137 | struct pstore_info *psi) | ||
138 | { | 137 | { |
139 | ssize_t size; | 138 | ssize_t size; |
140 | struct ramoops_context *cxt = psi->data; | 139 | struct ramoops_context *cxt = psi->data; |
@@ -236,8 +235,8 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
236 | return 0; | 235 | return 0; |
237 | } | 236 | } |
238 | 237 | ||
239 | static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, | 238 | static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count, |
240 | struct pstore_info *psi) | 239 | struct timespec time, struct pstore_info *psi) |
241 | { | 240 | { |
242 | struct ramoops_context *cxt = psi->data; | 241 | struct ramoops_context *cxt = psi->data; |
243 | struct persistent_ram_zone *prz; | 242 | struct persistent_ram_zone *prz; |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 8670eb1eb8cd..c47ec36f3f39 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -643,6 +643,7 @@ struct efivar_operations { | |||
643 | efi_get_variable_t *get_variable; | 643 | efi_get_variable_t *get_variable; |
644 | efi_get_next_variable_t *get_next_variable; | 644 | efi_get_next_variable_t *get_next_variable; |
645 | efi_set_variable_t *set_variable; | 645 | efi_set_variable_t *set_variable; |
646 | efi_query_variable_info_t *query_variable_info; | ||
646 | }; | 647 | }; |
647 | 648 | ||
648 | struct efivars { | 649 | struct efivars { |
diff --git a/include/linux/pstore.h b/include/linux/pstore.h index ee3034a40884..1788909d9a99 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h | |||
@@ -50,16 +50,18 @@ struct pstore_info { | |||
50 | int (*open)(struct pstore_info *psi); | 50 | int (*open)(struct pstore_info *psi); |
51 | int (*close)(struct pstore_info *psi); | 51 | int (*close)(struct pstore_info *psi); |
52 | ssize_t (*read)(u64 *id, enum pstore_type_id *type, | 52 | ssize_t (*read)(u64 *id, enum pstore_type_id *type, |
53 | struct timespec *time, char **buf, | 53 | int *count, struct timespec *time, char **buf, |
54 | struct pstore_info *psi); | 54 | struct pstore_info *psi); |
55 | int (*write)(enum pstore_type_id type, | 55 | int (*write)(enum pstore_type_id type, |
56 | enum kmsg_dump_reason reason, u64 *id, | 56 | enum kmsg_dump_reason reason, u64 *id, |
57 | unsigned int part, size_t size, struct pstore_info *psi); | 57 | unsigned int part, int count, size_t size, |
58 | struct pstore_info *psi); | ||
58 | int (*write_buf)(enum pstore_type_id type, | 59 | int (*write_buf)(enum pstore_type_id type, |
59 | enum kmsg_dump_reason reason, u64 *id, | 60 | enum kmsg_dump_reason reason, u64 *id, |
60 | unsigned int part, const char *buf, size_t size, | 61 | unsigned int part, const char *buf, size_t size, |
61 | struct pstore_info *psi); | 62 | struct pstore_info *psi); |
62 | int (*erase)(enum pstore_type_id type, u64 id, | 63 | int (*erase)(enum pstore_type_id type, u64 id, |
64 | int count, struct timespec time, | ||
63 | struct pstore_info *psi); | 65 | struct pstore_info *psi); |
64 | void *data; | 66 | void *data; |
65 | }; | 67 | }; |