aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/apei
diff options
context:
space:
mode:
authorChen Gong <gong.chen@linux.intel.com>2011-05-16 14:00:27 -0400
committerTony Luck <tony.luck@intel.com>2011-05-16 14:05:00 -0400
commit06cf91b4b4aafa50ee0a94c81d2c6922a18af242 (patch)
treef45fe916103b323a714c8958048b8adab1f944b1 /drivers/acpi/apei
parent8d38d74b648513dd8ed8bd2b67d899208ef4e09e (diff)
pstore: fix pstore filesystem mount/remount issue
Currently after mount/remount operation on pstore filesystem, the content on pstore will be lost. It is because current ERST implementation doesn't support multi-user usage, which moves internal pointer to the end after accessing it. Adding multi-user support for pstore usage. Signed-off-by: Chen Gong <gong.chen@linux.intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r--drivers/acpi/apei/erst.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index d5a89d067f98..ddb68c4f8d3e 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -929,6 +929,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
929 return 0; 929 return 0;
930} 930}
931 931
932static int erst_open_pstore(struct pstore_info *psi);
933static int erst_close_pstore(struct pstore_info *psi);
932static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 934static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
933 struct timespec *time); 935 struct timespec *time);
934static u64 erst_writer(enum pstore_type_id type, size_t size); 936static u64 erst_writer(enum pstore_type_id type, size_t size);
@@ -936,6 +938,8 @@ static u64 erst_writer(enum pstore_type_id type, size_t size);
936static struct pstore_info erst_info = { 938static struct pstore_info erst_info = {
937 .owner = THIS_MODULE, 939 .owner = THIS_MODULE,
938 .name = "erst", 940 .name = "erst",
941 .open = erst_open_pstore,
942 .close = erst_close_pstore,
939 .read = erst_reader, 943 .read = erst_reader,
940 .write = erst_writer, 944 .write = erst_writer,
941 .erase = erst_clear 945 .erase = erst_clear
@@ -957,12 +961,32 @@ struct cper_pstore_record {
957 char data[]; 961 char data[];
958} __packed; 962} __packed;
959 963
964static int reader_pos;
965
966static int erst_open_pstore(struct pstore_info *psi)
967{
968 int rc;
969
970 if (erst_disable)
971 return -ENODEV;
972
973 rc = erst_get_record_id_begin(&reader_pos);
974
975 return rc;
976}
977
978static int erst_close_pstore(struct pstore_info *psi)
979{
980 erst_get_record_id_end();
981
982 return 0;
983}
984
960static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 985static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
961 struct timespec *time) 986 struct timespec *time)
962{ 987{
963 int rc; 988 int rc;
964 ssize_t len; 989 ssize_t len = 0;
965 unsigned long flags;
966 u64 record_id; 990 u64 record_id;
967 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 991 struct cper_pstore_record *rcd = (struct cper_pstore_record *)
968 (erst_info.buf - sizeof(*rcd)); 992 (erst_info.buf - sizeof(*rcd));
@@ -970,24 +994,21 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
970 if (erst_disable) 994 if (erst_disable)
971 return -ENODEV; 995 return -ENODEV;
972 996
973 raw_spin_lock_irqsave(&erst_lock, flags);
974skip: 997skip:
975 rc = __erst_get_next_record_id(&record_id); 998 rc = erst_get_record_id_next(&reader_pos, &record_id);
976 if (rc) { 999 if (rc)
977 raw_spin_unlock_irqrestore(&erst_lock, flags); 1000 goto out;
978 return rc; 1001
979 }
980 /* no more record */ 1002 /* no more record */
981 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 1003 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
982 raw_spin_unlock_irqrestore(&erst_lock, flags); 1004 rc = -1;
983 return 0; 1005 goto out;
984 } 1006 }
985 1007
986 len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + 1008 len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
987 erst_erange.size); 1009 erst_erange.size);
988 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) 1010 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
989 goto skip; 1011 goto skip;
990 raw_spin_unlock_irqrestore(&erst_lock, flags);
991 1012
992 *id = record_id; 1013 *id = record_id;
993 if (uuid_le_cmp(rcd->sec_hdr.section_type, 1014 if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1005,7 +1026,8 @@ skip:
1005 time->tv_sec = 0; 1026 time->tv_sec = 0;
1006 time->tv_nsec = 0; 1027 time->tv_nsec = 0;
1007 1028
1008 return len - sizeof(*rcd); 1029out:
1030 return (rc < 0) ? rc : (len - sizeof(*rcd));
1009} 1031}
1010 1032
1011static u64 erst_writer(enum pstore_type_id type, size_t size) 1033static u64 erst_writer(enum pstore_type_id type, size_t size)