Loading drivers/acpi/apei/erst.c +22 −9 Original line number Diff line number Diff line Loading @@ -932,7 +932,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) static int erst_open_pstore(struct pstore_info *psi); static int erst_close_pstore(struct pstore_info *psi); static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi); struct timespec *time, char **buf, struct pstore_info *psi); static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part, size_t size, struct pstore_info *psi); static int erst_clearer(enum pstore_type_id type, u64 id, Loading Loading @@ -986,17 +987,23 @@ static int erst_close_pstore(struct pstore_info *psi) } static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi) struct timespec *time, char **buf, struct pstore_info *psi) { int rc; ssize_t len = 0; u64 record_id; struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf - sizeof(*rcd)); struct cper_pstore_record *rcd; size_t rcd_len = sizeof(*rcd) + erst_info.bufsize; if (erst_disable) return -ENODEV; rcd = kmalloc(rcd_len, GFP_KERNEL); if (!rcd) { rc = -ENOMEM; goto out; } skip: rc = erst_get_record_id_next(&reader_pos, &record_id); if (rc) Loading @@ -1004,22 +1011,27 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, /* no more record */ if (record_id == APEI_ERST_INVALID_RECORD_ID) { rc = -1; rc = -EINVAL; goto out; } len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + erst_info.bufsize); len = erst_read(record_id, &rcd->hdr, rcd_len); /* The record may be cleared by others, try read next record */ if (len == -ENOENT) goto skip; else if (len < 0) { rc = -1; else if (len < sizeof(*rcd)) { rc = -EIO; goto out; } if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) goto skip; *buf = kmalloc(len, GFP_KERNEL); if (*buf == NULL) { rc = -ENOMEM; goto out; } memcpy(*buf, rcd->data, len - sizeof(*rcd)); *id = record_id; if (uuid_le_cmp(rcd->sec_hdr.section_type, CPER_SECTION_TYPE_DMESG) == 0) Loading @@ -1037,6 +1049,7 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, time->tv_nsec = 0; out: kfree(rcd); return (rc < 0) ? rc : (len - sizeof(*rcd)); } Loading drivers/firmware/efivars.c +7 −2 Original line number Diff line number Diff line Loading @@ -457,7 +457,8 @@ static int efi_pstore_close(struct pstore_info *psi) } static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, struct timespec *timespec, struct pstore_info *psi) struct timespec *timespec, char **buf, struct pstore_info *psi) { efi_guid_t vendor = LINUX_EFI_CRASH_GUID; struct efivars *efivars = psi->data; Loading @@ -478,7 +479,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, timespec->tv_nsec = 0; get_var_data_locked(efivars, &efivars->walk_entry->var); size = efivars->walk_entry->var.DataSize; memcpy(psi->buf, efivars->walk_entry->var.Data, size); *buf = kmalloc(size, GFP_KERNEL); if (*buf == NULL) return -ENOMEM; memcpy(*buf, efivars->walk_entry->var.Data, size); efivars->walk_entry = list_entry(efivars->walk_entry->list.next, struct efivar_entry, list); return size; Loading fs/pstore/platform.c +8 −5 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ int pstore_register(struct pstore_info *psi) } psinfo = psi; mutex_init(&psinfo->read_mutex); spin_unlock(&pstore_lock); if (owner && !try_module_get(owner)) { Loading Loading @@ -195,30 +196,32 @@ EXPORT_SYMBOL_GPL(pstore_register); void pstore_get_records(int quiet) { struct pstore_info *psi = psinfo; char *buf = NULL; ssize_t size; u64 id; enum pstore_type_id type; struct timespec time; int failed = 0, rc; unsigned long flags; if (!psi) return; spin_lock_irqsave(&psinfo->buf_lock, flags); mutex_lock(&psi->read_mutex); rc = psi->open(psi); if (rc) goto out; while ((size = psi->read(&id, &type, &time, psi)) > 0) { rc = pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size, while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) { rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size, time, psi); kfree(buf); buf = NULL; if (rc && (rc != -EEXIST || !quiet)) failed++; } psi->close(psi); out: spin_unlock_irqrestore(&psinfo->buf_lock, flags); mutex_unlock(&psi->read_mutex); if (failed) printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n", Loading include/linux/pstore.h +3 −1 Original line number Diff line number Diff line Loading @@ -35,10 +35,12 @@ struct pstore_info { spinlock_t buf_lock; /* serialize access to 'buf' */ char *buf; size_t bufsize; struct mutex read_mutex; /* serialize open/read/close */ int (*open)(struct pstore_info *psi); int (*close)(struct pstore_info *psi); ssize_t (*read)(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi); struct timespec *time, char **buf, struct pstore_info *psi); int (*write)(enum pstore_type_id type, u64 *id, unsigned int part, size_t size, struct pstore_info *psi); int (*erase)(enum pstore_type_id type, u64 id, Loading Loading
drivers/acpi/apei/erst.c +22 −9 Original line number Diff line number Diff line Loading @@ -932,7 +932,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) static int erst_open_pstore(struct pstore_info *psi); static int erst_close_pstore(struct pstore_info *psi); static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi); struct timespec *time, char **buf, struct pstore_info *psi); static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part, size_t size, struct pstore_info *psi); static int erst_clearer(enum pstore_type_id type, u64 id, Loading Loading @@ -986,17 +987,23 @@ static int erst_close_pstore(struct pstore_info *psi) } static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi) struct timespec *time, char **buf, struct pstore_info *psi) { int rc; ssize_t len = 0; u64 record_id; struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf - sizeof(*rcd)); struct cper_pstore_record *rcd; size_t rcd_len = sizeof(*rcd) + erst_info.bufsize; if (erst_disable) return -ENODEV; rcd = kmalloc(rcd_len, GFP_KERNEL); if (!rcd) { rc = -ENOMEM; goto out; } skip: rc = erst_get_record_id_next(&reader_pos, &record_id); if (rc) Loading @@ -1004,22 +1011,27 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, /* no more record */ if (record_id == APEI_ERST_INVALID_RECORD_ID) { rc = -1; rc = -EINVAL; goto out; } len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + erst_info.bufsize); len = erst_read(record_id, &rcd->hdr, rcd_len); /* The record may be cleared by others, try read next record */ if (len == -ENOENT) goto skip; else if (len < 0) { rc = -1; else if (len < sizeof(*rcd)) { rc = -EIO; goto out; } if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) goto skip; *buf = kmalloc(len, GFP_KERNEL); if (*buf == NULL) { rc = -ENOMEM; goto out; } memcpy(*buf, rcd->data, len - sizeof(*rcd)); *id = record_id; if (uuid_le_cmp(rcd->sec_hdr.section_type, CPER_SECTION_TYPE_DMESG) == 0) Loading @@ -1037,6 +1049,7 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, time->tv_nsec = 0; out: kfree(rcd); return (rc < 0) ? rc : (len - sizeof(*rcd)); } Loading
drivers/firmware/efivars.c +7 −2 Original line number Diff line number Diff line Loading @@ -457,7 +457,8 @@ static int efi_pstore_close(struct pstore_info *psi) } static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, struct timespec *timespec, struct pstore_info *psi) struct timespec *timespec, char **buf, struct pstore_info *psi) { efi_guid_t vendor = LINUX_EFI_CRASH_GUID; struct efivars *efivars = psi->data; Loading @@ -478,7 +479,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, timespec->tv_nsec = 0; get_var_data_locked(efivars, &efivars->walk_entry->var); size = efivars->walk_entry->var.DataSize; memcpy(psi->buf, efivars->walk_entry->var.Data, size); *buf = kmalloc(size, GFP_KERNEL); if (*buf == NULL) return -ENOMEM; memcpy(*buf, efivars->walk_entry->var.Data, size); efivars->walk_entry = list_entry(efivars->walk_entry->list.next, struct efivar_entry, list); return size; Loading
fs/pstore/platform.c +8 −5 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ int pstore_register(struct pstore_info *psi) } psinfo = psi; mutex_init(&psinfo->read_mutex); spin_unlock(&pstore_lock); if (owner && !try_module_get(owner)) { Loading Loading @@ -195,30 +196,32 @@ EXPORT_SYMBOL_GPL(pstore_register); void pstore_get_records(int quiet) { struct pstore_info *psi = psinfo; char *buf = NULL; ssize_t size; u64 id; enum pstore_type_id type; struct timespec time; int failed = 0, rc; unsigned long flags; if (!psi) return; spin_lock_irqsave(&psinfo->buf_lock, flags); mutex_lock(&psi->read_mutex); rc = psi->open(psi); if (rc) goto out; while ((size = psi->read(&id, &type, &time, psi)) > 0) { rc = pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size, while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) { rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size, time, psi); kfree(buf); buf = NULL; if (rc && (rc != -EEXIST || !quiet)) failed++; } psi->close(psi); out: spin_unlock_irqrestore(&psinfo->buf_lock, flags); mutex_unlock(&psi->read_mutex); if (failed) printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n", Loading
include/linux/pstore.h +3 −1 Original line number Diff line number Diff line Loading @@ -35,10 +35,12 @@ struct pstore_info { spinlock_t buf_lock; /* serialize access to 'buf' */ char *buf; size_t bufsize; struct mutex read_mutex; /* serialize open/read/close */ int (*open)(struct pstore_info *psi); int (*close)(struct pstore_info *psi); ssize_t (*read)(u64 *id, enum pstore_type_id *type, struct timespec *time, struct pstore_info *psi); struct timespec *time, char **buf, struct pstore_info *psi); int (*write)(enum pstore_type_id type, u64 *id, unsigned int part, size_t size, struct pstore_info *psi); int (*erase)(enum pstore_type_id type, u64 id, Loading