OSDN Git Service

Pull pstore into release branch
authorTony Luck <tony.luck@intel.com>
Fri, 20 May 2011 17:34:50 +0000 (10:34 -0700)
committerTony Luck <tony.luck@intel.com>
Fri, 20 May 2011 17:34:50 +0000 (10:34 -0700)
drivers/acpi/apei/Kconfig
drivers/acpi/apei/erst.c
fs/pstore/platform.c
include/linux/pstore.h

index 66a03ca..f739a70 100644 (file)
@@ -1,5 +1,6 @@
 config ACPI_APEI
        bool "ACPI Platform Error Interface (APEI)"
+       select MISC_FILESYSTEMS
        select PSTORE
        depends on X86
        help
index d6cb0ff..e6cef8e 100644 (file)
@@ -929,13 +929,17 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
        return 0;
 }
 
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+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);
 static u64 erst_writer(enum pstore_type_id type, size_t size);
 
 static struct pstore_info erst_info = {
        .owner          = THIS_MODULE,
        .name           = "erst",
+       .open           = erst_open_pstore,
+       .close          = erst_close_pstore,
        .read           = erst_reader,
        .write          = erst_writer,
        .erase          = erst_clear
@@ -957,12 +961,32 @@ struct cper_pstore_record {
        char data[];
 } __packed;
 
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+static int reader_pos;
+
+static int erst_open_pstore(struct pstore_info *psi)
+{
+       int rc;
+
+       if (erst_disable)
+               return -ENODEV;
+
+       rc = erst_get_record_id_begin(&reader_pos);
+
+       return rc;
+}
+
+static int erst_close_pstore(struct pstore_info *psi)
+{
+       erst_get_record_id_end();
+
+       return 0;
+}
+
+static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
                       struct timespec *time)
 {
        int rc;
-       ssize_t len;
-       unsigned long flags;
+       ssize_t len = 0;
        u64 record_id;
        struct cper_pstore_record *rcd = (struct cper_pstore_record *)
                                        (erst_info.buf - sizeof(*rcd));
@@ -970,24 +994,28 @@ static size_t erst_reader(u64 *id, enum pstore_type_id *type,
        if (erst_disable)
                return -ENODEV;
 
-       raw_spin_lock_irqsave(&erst_lock, flags);
 skip:
-       rc = __erst_get_next_record_id(&record_id);
-       if (rc) {
-               raw_spin_unlock_irqrestore(&erst_lock, flags);
-               return rc;
-       }
+       rc = erst_get_record_id_next(&reader_pos, &record_id);
+       if (rc)
+               goto out;
+
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               raw_spin_unlock_irqrestore(&erst_lock, flags);
-               return 0;
+               rc = -1;
+               goto out;
        }
 
-       len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
-                         erst_erange.size);
+       len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
+                       erst_info.bufsize);
+       /* The record may be cleared by others, try read next record */
+       if (len == -ENOENT)
+               goto skip;
+       else if (len < 0) {
+               rc = -1;
+               goto out;
+       }
        if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
                goto skip;
-       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        *id = record_id;
        if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1005,7 +1033,8 @@ skip:
                time->tv_sec = 0;
        time->tv_nsec = 0;
 
-       return len - sizeof(*rcd);
+out:
+       return (rc < 0) ? rc : (len - sizeof(*rcd));
 }
 
 static u64 erst_writer(enum pstore_type_id type, size_t size)
index f835a25..f2c3ff2 100644 (file)
@@ -152,21 +152,27 @@ EXPORT_SYMBOL_GPL(pstore_register);
 void pstore_get_records(void)
 {
        struct pstore_info *psi = psinfo;
-       size_t                  size;
+       ssize_t                 size;
        u64                     id;
        enum pstore_type_id     type;
        struct timespec         time;
-       int                     failed = 0;
+       int                     failed = 0, rc;
 
        if (!psi)
                return;
 
        mutex_lock(&psinfo->buf_mutex);
+       rc = psi->open(psi);
+       if (rc)
+               goto out;
+
        while ((size = psi->read(&id, &type, &time)) > 0) {
-               if (pstore_mkfile(type, psi->name, id, psi->buf, size,
+               if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
                                  time, psi->erase))
                        failed++;
        }
+       psi->close(psi);
+out:
        mutex_unlock(&psinfo->buf_mutex);
 
        if (failed)
index 4197773..2455ef2 100644 (file)
@@ -35,7 +35,9 @@ struct pstore_info {
        struct mutex    buf_mutex;      /* serialize access to 'buf' */
        char            *buf;
        size_t          bufsize;
-       size_t          (*read)(u64 *id, enum pstore_type_id *type,
+       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);
        u64             (*write)(enum pstore_type_id type, size_t size);
        int             (*erase)(u64 id);