[PATCH v3 3/3] pstore: support current records dump in ramoops

2014-04-03 Thread Liu ShuoX
dump the records in runtime is useful sometime. We could check the
records and understand driver's and device's status.

Signed-off-by: Zhang Yanmin 
Signed-off-by: Liu ShuoX 
---
 fs/pstore/inode.c  | 39 +++
 fs/pstore/internal.h   |  3 ++-
 fs/pstore/platform.c   | 39 ++-
 fs/pstore/ram.c| 18 ++
 fs/pstore/ram_core.c   | 10 ++
 include/linux/pstore.h |  2 ++
 include/linux/pstore_ram.h |  2 ++
 7 files changed, 95 insertions(+), 18 deletions(-)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index a9c9782..a3b817c15df 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -48,10 +48,11 @@ struct pstore_private {
struct list_head list;
struct pstore_info *psi;
enum pstore_type_id type;
+   int curr;
u64 id;
int count;
ssize_t size;
-   chardata[];
+   char*data;
 };
 
 struct pstore_seq_data {
@@ -210,16 +211,27 @@ static int pstore_file_open(struct inode *inode, struct 
file *file)
struct ramoops_context *cxt = ps->psi->data;
struct ramoops_zone*zones = cxt ? cxt->zones : NULL;
struct seq_file *sf;
+   char *buf = NULL;
int err;
+   u64 id = ps->id;
const struct seq_operations *sops = NULL;
 
if (ps->type == PSTORE_TYPE_FTRACE)
sops = _ftrace_seq_ops;
if (ps->type == PSTORE_TYPE_NORM && zones) {
-   if (zones[ps->id].seq_ops)
-   sops = zones[ps->id].seq_ops;
+   if (zones[id].seq_ops)
+   sops = zones[id].seq_ops;
else
sops = _seq_ops;
+   if (ps->curr) {
+   /*
+* Update size again as current buffer
+* size might be changed.
+*/
+   inode->i_size = ps->size =
+   ps->psi->read_curr(, PSTORE_TYPE_NORM,
+   , ps->psi);
+   }
}
 
err = seq_open(file, sops);
@@ -256,12 +268,16 @@ static int pstore_unlink(struct inode *dir, struct dentry 
*dentry)
 {
struct pstore_private *p = dentry->d_inode->i_private;
 
+   if (p->curr)
+   goto unlink;
if (p->psi->erase)
p->psi->erase(p->type, p->id, p->count,
  dentry->d_inode->i_ctime, p->psi);
else
return -EPERM;
 
+   kfree(p->data);
+unlink:
return simple_unlink(dir, dentry);
 }
 
@@ -358,7 +374,7 @@ int pstore_is_mounted(void)
  */
 int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
  char *data, bool compressed, size_t size,
- struct timespec time, struct pstore_info *psi)
+ struct timespec time, struct pstore_info *psi, bool curr)
 {
struct dentry   *root = pstore_sb->s_root;
struct dentry   *dentry;
@@ -374,14 +390,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
list_for_each_entry(pos, , list) {
if (pos->type == type &&
pos->id == id &&
-   pos->psi == psi) {
+   pos->psi == psi &&
+   pos->curr == curr) {
rc = -EEXIST;
break;
}
}
spin_unlock_irqrestore(_lock, flags);
if (rc)
-   return rc;
+   goto fail;
 
rc = -ENOMEM;
inode = pstore_get_inode(pstore_sb);
@@ -389,13 +406,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
goto fail;
inode->i_mode = S_IFREG | 0444;
inode->i_fop = _file_operations;
-   private = kmalloc(sizeof *private + size, GFP_KERNEL);
+   private = kmalloc(sizeof(*private), GFP_KERNEL);
if (!private)
goto fail_alloc;
private->type = type;
private->id = id;
private->count = count;
private->psi = psi;
+   private->curr = curr;
+   private->data = data;
 
switch (type) {
case PSTORE_TYPE_DMESG:
@@ -434,13 +453,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
break;
}
 
+   if (curr)
+   strcat(name, "_cur");
+
mutex_lock(>d_inode->i_mutex);
 
dentry = d_alloc_name(root, name);
if (!dentry)
goto fail_lockedalloc;
 
-   memcpy(private->data, data, size);
inode->i_size = private->size = size;
 
inode->i_private = private;
@@ -465,6 +486,7 @@ fail_alloc:
iput(inode);
 
 fail:
+   kfree(data);
return rc;
 }
 
@@ -497,6 +519,7 @@ static int 

[PATCH v3 3/3] pstore: support current records dump in ramoops

2014-04-03 Thread Liu ShuoX
dump the records in runtime is useful sometime. We could check the
records and understand driver's and device's status.

Signed-off-by: Zhang Yanmin yanmin.zh...@intel.com
Signed-off-by: Liu ShuoX shuox@intel.com
---
 fs/pstore/inode.c  | 39 +++
 fs/pstore/internal.h   |  3 ++-
 fs/pstore/platform.c   | 39 ++-
 fs/pstore/ram.c| 18 ++
 fs/pstore/ram_core.c   | 10 ++
 include/linux/pstore.h |  2 ++
 include/linux/pstore_ram.h |  2 ++
 7 files changed, 95 insertions(+), 18 deletions(-)

diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index a9c9782..a3b817c15df 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -48,10 +48,11 @@ struct pstore_private {
struct list_head list;
struct pstore_info *psi;
enum pstore_type_id type;
+   int curr;
u64 id;
int count;
ssize_t size;
-   chardata[];
+   char*data;
 };
 
 struct pstore_seq_data {
@@ -210,16 +211,27 @@ static int pstore_file_open(struct inode *inode, struct 
file *file)
struct ramoops_context *cxt = ps-psi-data;
struct ramoops_zone*zones = cxt ? cxt-zones : NULL;
struct seq_file *sf;
+   char *buf = NULL;
int err;
+   u64 id = ps-id;
const struct seq_operations *sops = NULL;
 
if (ps-type == PSTORE_TYPE_FTRACE)
sops = pstore_ftrace_seq_ops;
if (ps-type == PSTORE_TYPE_NORM  zones) {
-   if (zones[ps-id].seq_ops)
-   sops = zones[ps-id].seq_ops;
+   if (zones[id].seq_ops)
+   sops = zones[id].seq_ops;
else
sops = pstore_seq_ops;
+   if (ps-curr) {
+   /*
+* Update size again as current buffer
+* size might be changed.
+*/
+   inode-i_size = ps-size =
+   ps-psi-read_curr(id, PSTORE_TYPE_NORM,
+   buf, ps-psi);
+   }
}
 
err = seq_open(file, sops);
@@ -256,12 +268,16 @@ static int pstore_unlink(struct inode *dir, struct dentry 
*dentry)
 {
struct pstore_private *p = dentry-d_inode-i_private;
 
+   if (p-curr)
+   goto unlink;
if (p-psi-erase)
p-psi-erase(p-type, p-id, p-count,
  dentry-d_inode-i_ctime, p-psi);
else
return -EPERM;
 
+   kfree(p-data);
+unlink:
return simple_unlink(dir, dentry);
 }
 
@@ -358,7 +374,7 @@ int pstore_is_mounted(void)
  */
 int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
  char *data, bool compressed, size_t size,
- struct timespec time, struct pstore_info *psi)
+ struct timespec time, struct pstore_info *psi, bool curr)
 {
struct dentry   *root = pstore_sb-s_root;
struct dentry   *dentry;
@@ -374,14 +390,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
list_for_each_entry(pos, allpstore, list) {
if (pos-type == type 
pos-id == id 
-   pos-psi == psi) {
+   pos-psi == psi 
+   pos-curr == curr) {
rc = -EEXIST;
break;
}
}
spin_unlock_irqrestore(allpstore_lock, flags);
if (rc)
-   return rc;
+   goto fail;
 
rc = -ENOMEM;
inode = pstore_get_inode(pstore_sb);
@@ -389,13 +406,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
goto fail;
inode-i_mode = S_IFREG | 0444;
inode-i_fop = pstore_file_operations;
-   private = kmalloc(sizeof *private + size, GFP_KERNEL);
+   private = kmalloc(sizeof(*private), GFP_KERNEL);
if (!private)
goto fail_alloc;
private-type = type;
private-id = id;
private-count = count;
private-psi = psi;
+   private-curr = curr;
+   private-data = data;
 
switch (type) {
case PSTORE_TYPE_DMESG:
@@ -434,13 +453,15 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, 
u64 id, int count,
break;
}
 
+   if (curr)
+   strcat(name, _cur);
+
mutex_lock(root-d_inode-i_mutex);
 
dentry = d_alloc_name(root, name);
if (!dentry)
goto fail_lockedalloc;
 
-   memcpy(private-data, data, size);
inode-i_size = private-size = size;
 
inode-i_private = private;
@@ -465,6 +486,7 @@ fail_alloc:
iput(inode);
 
 fail:
+   kfree(data);
return rc;
 }
 
@@ -497,6 +519,7 @@