[PATCH v3 3/3] pstore: support current records dump in ramoops
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
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 @@