pstore/ram: Read and write to the 'compressed' flag of pstore
authorAruna Balakrishnaiah <aruna@linux.vnet.ibm.com>
Fri, 16 Aug 2013 20:58:00 +0000 (13:58 -0700)
committerTony Luck <tony.luck@intel.com>
Mon, 19 Aug 2013 18:53:50 +0000 (11:53 -0700)
In pstore write, add character 'C'(compressed) or 'D'(decompressed)
in the header while writing to Ram persistent buffer. In pstore read,
read the header and update the 'compressed' flag accordingly.

Signed-off-by: Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
fs/pstore/ram.c

index 292722327811ac4b6e21ce923e8a94c95f91a01e..4027c2065842d488755e2cadbc6bbdf62b171e39 100644 (file)
@@ -131,6 +131,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
        return prz;
 }
 
+static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
+                                 bool *compressed)
+{
+       char data_type;
+
+       if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
+                       &time->tv_sec, &time->tv_nsec, &data_type) == 3) {
+               if (data_type == 'C')
+                       *compressed = true;
+               else
+                       *compressed = false;
+       } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
+                       &time->tv_sec, &time->tv_nsec) == 2) {
+                       *compressed = false;
+       } else {
+               time->tv_sec = 0;
+               time->tv_nsec = 0;
+               *compressed = false;
+       }
+}
+
 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
                                   int *count, struct timespec *time,
                                   char **buf, bool *compressed,
@@ -153,10 +174,6 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
        if (!prz)
                return 0;
 
-       /* TODO(kees): Bogus time for the moment. */
-       time->tv_sec = 0;
-       time->tv_nsec = 0;
-
        size = persistent_ram_old_size(prz);
 
        /* ECC correction notice */
@@ -167,12 +184,14 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
                return -ENOMEM;
 
        memcpy(*buf, persistent_ram_old(prz), size);
+       ramoops_read_kmsg_hdr(*buf, time, compressed);
        persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
 
        return size + ecc_notice_size;
 }
 
-static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
+static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
+                                    bool compressed)
 {
        char *hdr;
        struct timespec timestamp;
@@ -183,8 +202,9 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
                timestamp.tv_sec = 0;
                timestamp.tv_nsec = 0;
        }
-       hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
-               (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000));
+       hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
+               (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000),
+               compressed ? 'C' : 'D');
        WARN_ON_ONCE(!hdr);
        len = hdr ? strlen(hdr) : 0;
        persistent_ram_write(prz, hdr, len);
@@ -243,7 +263,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
 
        prz = cxt->przs[cxt->dump_write_cnt];
 
-       hlen = ramoops_write_kmsg_hdr(prz);
+       hlen = ramoops_write_kmsg_hdr(prz, compressed);
        if (size + hlen > prz->buffer_size)
                size = prz->buffer_size - hlen;
        persistent_ram_write(prz, buf, size);