summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeliang Tang <geliangtang@163.com>2015-10-20 03:39:03 -0400
committerTony Luck <tony.luck@intel.com>2015-10-22 11:59:18 -0400
commitee1d267423a1f8041e2b1a33fc23e4393c67677e (patch)
treeb53cdedcdc8f6a7b36f0342814b91005ce4955ea
parent1873041152d2e324e25ddeec5541b90c22c2dc0f (diff)
pstore: add pstore unregister
pstore doesn't support unregistering yet. It was marked as TODO. This patch adds some code to fix it: 1) Add functions to unregister kmsg/console/ftrace/pmsg. 2) Add a function to free compression buffer. 3) Unmap the memory and free it. 4) Add a function to unregister pstore filesystem. Signed-off-by: Geliang Tang <geliangtang@163.com> Acked-by: Kees Cook <keescook@chromium.org> [Removed __exit annotation from ramoops_remove(). Reported by Arnd Bergmann] Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--fs/pstore/Kconfig2
-rw-r--r--fs/pstore/Makefile6
-rw-r--r--fs/pstore/ftrace.c25
-rw-r--r--fs/pstore/inode.c9
-rw-r--r--fs/pstore/internal.h4
-rw-r--r--fs/pstore/platform.c35
-rw-r--r--fs/pstore/pmsg.c7
-rw-r--r--fs/pstore/ram.c19
-rw-r--r--include/linux/pstore.h14
-rw-r--r--kernel/printk/printk.c1
10 files changed, 88 insertions, 34 deletions
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 916b8e23d968..360ae43f590c 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -1,5 +1,5 @@
1config PSTORE 1config PSTORE
2 bool "Persistent store support" 2 tristate "Persistent store support"
3 default n 3 default n
4 select ZLIB_DEFLATE 4 select ZLIB_DEFLATE
5 select ZLIB_INFLATE 5 select ZLIB_INFLATE
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index e647d8e81712..b8803cc07fce 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -2,12 +2,12 @@
2# Makefile for the linux pstorefs routines. 2# Makefile for the linux pstorefs routines.
3# 3#
4 4
5obj-y += pstore.o 5obj-$(CONFIG_PSTORE) += pstore.o
6 6
7pstore-objs += inode.o platform.o 7pstore-objs += inode.o platform.o
8obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o 8pstore-$(CONFIG_PSTORE_FTRACE) += ftrace.o
9 9
10obj-$(CONFIG_PSTORE_PMSG) += pmsg.o 10pstore-$(CONFIG_PSTORE_PMSG) += pmsg.o
11 11
12ramoops-objs += ram.o ram_core.o 12ramoops-objs += ram.o ram_core.o
13obj-$(CONFIG_PSTORE_RAM) += ramoops.o 13obj-$(CONFIG_PSTORE_RAM) += ramoops.o
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index 76a4eeb92982..d4887705bb61 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -104,22 +104,23 @@ static const struct file_operations pstore_knob_fops = {
104 .write = pstore_ftrace_knob_write, 104 .write = pstore_ftrace_knob_write,
105}; 105};
106 106
107static struct dentry *pstore_ftrace_dir;
108
107void pstore_register_ftrace(void) 109void pstore_register_ftrace(void)
108{ 110{
109 struct dentry *dir;
110 struct dentry *file; 111 struct dentry *file;
111 112
112 if (!psinfo->write_buf) 113 if (!psinfo->write_buf)
113 return; 114 return;
114 115
115 dir = debugfs_create_dir("pstore", NULL); 116 pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
116 if (!dir) { 117 if (!pstore_ftrace_dir) {
117 pr_err("%s: unable to create pstore directory\n", __func__); 118 pr_err("%s: unable to create pstore directory\n", __func__);
118 return; 119 return;
119 } 120 }
120 121
121 file = debugfs_create_file("record_ftrace", 0600, dir, NULL, 122 file = debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir,
122 &pstore_knob_fops); 123 NULL, &pstore_knob_fops);
123 if (!file) { 124 if (!file) {
124 pr_err("%s: unable to create record_ftrace file\n", __func__); 125 pr_err("%s: unable to create record_ftrace file\n", __func__);
125 goto err_file; 126 goto err_file;
@@ -127,5 +128,17 @@ void pstore_register_ftrace(void)
127 128
128 return; 129 return;
129err_file: 130err_file:
130 debugfs_remove(dir); 131 debugfs_remove(pstore_ftrace_dir);
132}
133
134void pstore_unregister_ftrace(void)
135{
136 mutex_lock(&pstore_ftrace_lock);
137 if (pstore_ftrace_enabled) {
138 unregister_ftrace_function(&pstore_ftrace_ops);
139 pstore_ftrace_enabled = 0;
140 }
141 mutex_unlock(&pstore_ftrace_lock);
142
143 debugfs_remove_recursive(pstore_ftrace_dir);
131} 144}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 3adcc4669fac..3586491f26ba 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -178,6 +178,7 @@ static loff_t pstore_file_llseek(struct file *file, loff_t off, int whence)
178} 178}
179 179
180static const struct file_operations pstore_file_operations = { 180static const struct file_operations pstore_file_operations = {
181 .owner = THIS_MODULE,
181 .open = pstore_file_open, 182 .open = pstore_file_open,
182 .read = pstore_file_read, 183 .read = pstore_file_read,
183 .llseek = pstore_file_llseek, 184 .llseek = pstore_file_llseek,
@@ -456,6 +457,7 @@ static void pstore_kill_sb(struct super_block *sb)
456} 457}
457 458
458static struct file_system_type pstore_fs_type = { 459static struct file_system_type pstore_fs_type = {
460 .owner = THIS_MODULE,
459 .name = "pstore", 461 .name = "pstore",
460 .mount = pstore_mount, 462 .mount = pstore_mount,
461 .kill_sb = pstore_kill_sb, 463 .kill_sb = pstore_kill_sb,
@@ -479,5 +481,12 @@ out:
479} 481}
480module_init(init_pstore_fs) 482module_init(init_pstore_fs)
481 483
484static void __exit exit_pstore_fs(void)
485{
486 unregister_filesystem(&pstore_fs_type);
487 sysfs_remove_mount_point(fs_kobj, "pstore");
488}
489module_exit(exit_pstore_fs)
490
482MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>"); 491MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>");
483MODULE_LICENSE("GPL"); 492MODULE_LICENSE("GPL");
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index c36ba2cd0b5d..96253c474ea5 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -41,14 +41,18 @@ pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
41 41
42#ifdef CONFIG_PSTORE_FTRACE 42#ifdef CONFIG_PSTORE_FTRACE
43extern void pstore_register_ftrace(void); 43extern void pstore_register_ftrace(void);
44extern void pstore_unregister_ftrace(void);
44#else 45#else
45static inline void pstore_register_ftrace(void) {} 46static inline void pstore_register_ftrace(void) {}
47static inline void pstore_unregister_ftrace(void) {}
46#endif 48#endif
47 49
48#ifdef CONFIG_PSTORE_PMSG 50#ifdef CONFIG_PSTORE_PMSG
49extern void pstore_register_pmsg(void); 51extern void pstore_register_pmsg(void);
52extern void pstore_unregister_pmsg(void);
50#else 53#else
51static inline void pstore_register_pmsg(void) {} 54static inline void pstore_register_pmsg(void) {}
55static inline void pstore_unregister_pmsg(void) {}
52#endif 56#endif
53 57
54extern struct pstore_info *psinfo; 58extern struct pstore_info *psinfo;
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 1b1124942b4e..0aab920efff7 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -237,6 +237,14 @@ static void allocate_buf_for_compression(void)
237 237
238} 238}
239 239
240static void free_buf_for_compression(void)
241{
242 kfree(stream.workspace);
243 stream.workspace = NULL;
244 kfree(big_oops_buf);
245 big_oops_buf = NULL;
246}
247
240/* 248/*
241 * Called when compression fails, since the printk buffer 249 * Called when compression fails, since the printk buffer
242 * would be fetched for compression calling it again when 250 * would be fetched for compression calling it again when
@@ -358,6 +366,11 @@ static void pstore_register_kmsg(void)
358 kmsg_dump_register(&pstore_dumper); 366 kmsg_dump_register(&pstore_dumper);
359} 367}
360 368
369static void pstore_unregister_kmsg(void)
370{
371 kmsg_dump_unregister(&pstore_dumper);
372}
373
361#ifdef CONFIG_PSTORE_CONSOLE 374#ifdef CONFIG_PSTORE_CONSOLE
362static void pstore_console_write(struct console *con, const char *s, unsigned c) 375static void pstore_console_write(struct console *con, const char *s, unsigned c)
363{ 376{
@@ -395,8 +408,14 @@ static void pstore_register_console(void)
395{ 408{
396 register_console(&pstore_console); 409 register_console(&pstore_console);
397} 410}
411
412static void pstore_unregister_console(void)
413{
414 unregister_console(&pstore_console);
415}
398#else 416#else
399static void pstore_register_console(void) {} 417static void pstore_register_console(void) {}
418static void pstore_unregister_console(void) {}
400#endif 419#endif
401 420
402static int pstore_write_compat(enum pstore_type_id type, 421static int pstore_write_compat(enum pstore_type_id type,
@@ -467,12 +486,28 @@ int pstore_register(struct pstore_info *psi)
467 */ 486 */
468 backend = psi->name; 487 backend = psi->name;
469 488
489 module_put(owner);
490
470 pr_info("Registered %s as persistent store backend\n", psi->name); 491 pr_info("Registered %s as persistent store backend\n", psi->name);
471 492
472 return 0; 493 return 0;
473} 494}
474EXPORT_SYMBOL_GPL(pstore_register); 495EXPORT_SYMBOL_GPL(pstore_register);
475 496
497void pstore_unregister(struct pstore_info *psi)
498{
499 pstore_unregister_pmsg();
500 pstore_unregister_ftrace();
501 pstore_unregister_console();
502 pstore_unregister_kmsg();
503
504 free_buf_for_compression();
505
506 psinfo = NULL;
507 backend = NULL;
508}
509EXPORT_SYMBOL_GPL(pstore_unregister);
510
476/* 511/*
477 * Read all the records from the persistent store. Create 512 * Read all the records from the persistent store. Create
478 * files in our filesystem. Don't warn about -EEXIST errors 513 * files in our filesystem. Don't warn about -EEXIST errors
diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
index 5a2f05a16c1e..7de20cd3797f 100644
--- a/fs/pstore/pmsg.c
+++ b/fs/pstore/pmsg.c
@@ -114,3 +114,10 @@ err_class:
114err: 114err:
115 return; 115 return;
116} 116}
117
118void pstore_unregister_pmsg(void)
119{
120 device_destroy(pmsg_class, MKDEV(pmsg_major, 0));
121 class_destroy(pmsg_class);
122 unregister_chrdev(pmsg_major, PMSG_NAME);
123}
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 6c26c4daaec9..319c3a60cfa5 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -578,30 +578,27 @@ fail_out:
578 return err; 578 return err;
579} 579}
580 580
581static int __exit ramoops_remove(struct platform_device *pdev) 581static int ramoops_remove(struct platform_device *pdev)
582{ 582{
583#if 0
584 /* TODO(kees): We cannot unload ramoops since pstore doesn't support
585 * unregistering yet.
586 */
587 struct ramoops_context *cxt = &oops_cxt; 583 struct ramoops_context *cxt = &oops_cxt;
588 584
589 iounmap(cxt->virt_addr); 585 pstore_unregister(&cxt->pstore);
590 release_mem_region(cxt->phys_addr, cxt->size);
591 cxt->max_dump_cnt = 0; 586 cxt->max_dump_cnt = 0;
592 587
593 /* TODO(kees): When pstore supports unregistering, call it here. */
594 kfree(cxt->pstore.buf); 588 kfree(cxt->pstore.buf);
595 cxt->pstore.bufsize = 0; 589 cxt->pstore.bufsize = 0;
596 590
591 persistent_ram_free(cxt->mprz);
592 persistent_ram_free(cxt->fprz);
593 persistent_ram_free(cxt->cprz);
594 ramoops_free_przs(cxt);
595
597 return 0; 596 return 0;
598#endif
599 return -EBUSY;
600} 597}
601 598
602static struct platform_driver ramoops_driver = { 599static struct platform_driver ramoops_driver = {
603 .probe = ramoops_probe, 600 .probe = ramoops_probe,
604 .remove = __exit_p(ramoops_remove), 601 .remove = ramoops_remove,
605 .driver = { 602 .driver = {
606 .name = "ramoops", 603 .name = "ramoops",
607 }, 604 },
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 8e7a25b068b0..831479f8df8f 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -75,20 +75,8 @@ struct pstore_info {
75 75
76#define PSTORE_FLAGS_FRAGILE 1 76#define PSTORE_FLAGS_FRAGILE 1
77 77
78#ifdef CONFIG_PSTORE
79extern int pstore_register(struct pstore_info *); 78extern int pstore_register(struct pstore_info *);
79extern void pstore_unregister(struct pstore_info *);
80extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason); 80extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
81#else
82static inline int
83pstore_register(struct pstore_info *psi)
84{
85 return -ENODEV;
86}
87static inline bool
88pstore_cannot_block_path(enum kmsg_dump_reason reason)
89{
90 return false;
91}
92#endif
93 81
94#endif /*_LINUX_PSTORE_H*/ 82#endif /*_LINUX_PSTORE_H*/
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 8f0324ef72ab..b16f35487b67 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -517,6 +517,7 @@ int check_syslog_permissions(int type, int source)
517ok: 517ok:
518 return security_syslog(type); 518 return security_syslog(type);
519} 519}
520EXPORT_SYMBOL_GPL(check_syslog_permissions);
520 521
521static void append_char(char **pp, char *e, char c) 522static void append_char(char **pp, char *e, char c)
522{ 523{