Browse Source

pstore: use mount option instead sysfs to tweak kmsg_bytes

/sys/fs is a somewhat strange way to tweak what could more
obviously be tuned with a mount option.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Luck, Tony 14 years ago
parent
commit
366f7e7a79

+ 9 - 3
Documentation/ABI/testing/pstore

@@ -1,6 +1,6 @@
 Where:		/dev/pstore/...
 Where:		/dev/pstore/...
-Date:		January 2011
-Kernel Version: 2.6.38
+Date:		March 2011
+Kernel Version: 2.6.39
 Contact:	tony.luck@intel.com
 Contact:	tony.luck@intel.com
 Description:	Generic interface to platform dependent persistent storage.
 Description:	Generic interface to platform dependent persistent storage.
 
 
@@ -11,7 +11,7 @@ Description:	Generic interface to platform dependent persistent storage.
 		of the console log is captured, but other interesting
 		of the console log is captured, but other interesting
 		data can also be saved.
 		data can also be saved.
 
 
-		# mount -t pstore - /dev/pstore
+		# mount -t pstore -o kmsg_bytes=8000 - /dev/pstore
 
 
 		$ ls -l /dev/pstore
 		$ ls -l /dev/pstore
 		total 0
 		total 0
@@ -33,3 +33,9 @@ Description:	Generic interface to platform dependent persistent storage.
 		will be saved elsewhere and erased from persistent store
 		will be saved elsewhere and erased from persistent store
 		soon after boot to free up space ready for the next
 		soon after boot to free up space ready for the next
 		catastrophe.
 		catastrophe.
+
+		The 'kmsg_bytes' mount option changes the target amount of
+		data saved on each oops/panic. Pstore saves (possibly
+		multiple) files based on the record size of the underlying
+		persistent storage until at least this amount is reached.
+		Default is 10 Kbytes.

+ 0 - 7
Documentation/ABI/testing/sysfs-fs-pstore

@@ -1,7 +0,0 @@
-What:		/sys/fs/pstore/kmsg_bytes
-Date:		January 2011
-Kernel Version: 2.6.38
-Contact:	"Tony Luck" <tony.luck@intel.com>
-Description:
-		Controls amount of console log that will be saved
-		to persistent store on oops/panic.

+ 46 - 22
fs/pstore/inode.c

@@ -27,6 +27,7 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/mount.h>
 #include <linux/mount.h>
 #include <linux/ramfs.h>
 #include <linux/ramfs.h>
+#include <linux/parser.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/magic.h>
 #include <linux/magic.h>
 #include <linux/pstore.h>
 #include <linux/pstore.h>
@@ -112,10 +113,52 @@ static struct inode *pstore_get_inode(struct super_block *sb,
 	return inode;
 	return inode;
 }
 }
 
 
+enum {
+	Opt_kmsg_bytes, Opt_err
+};
+
+static const match_table_t tokens = {
+	{Opt_kmsg_bytes, "kmsg_bytes=%u"},
+	{Opt_err, NULL}
+};
+
+static void parse_options(char *options)
+{
+	char		*p;
+	substring_t	args[MAX_OPT_ARGS];
+	int		option;
+
+	if (!options)
+		return;
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token;
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_kmsg_bytes:
+			if (!match_int(&args[0], &option))
+				pstore_set_kmsg_bytes(option);
+			break;
+		}
+	}
+}
+
+static int pstore_remount(struct super_block *sb, int *flags, char *data)
+{
+	parse_options(data);
+
+	return 0;
+}
+
 static const struct super_operations pstore_ops = {
 static const struct super_operations pstore_ops = {
 	.statfs		= simple_statfs,
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
 	.drop_inode	= generic_delete_inode,
 	.evict_inode	= pstore_evict_inode,
 	.evict_inode	= pstore_evict_inode,
+	.remount_fs	= pstore_remount,
 	.show_options	= generic_show_options,
 	.show_options	= generic_show_options,
 };
 };
 
 
@@ -215,6 +258,8 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_op		= &pstore_ops;
 	sb->s_op		= &pstore_ops;
 	sb->s_time_gran		= 1;
 	sb->s_time_gran		= 1;
 
 
+	parse_options(data);
+
 	inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0);
 	inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0);
 	if (!inode) {
 	if (!inode) {
 		err = -ENOMEM;
 		err = -ENOMEM;
@@ -258,28 +303,7 @@ static struct file_system_type pstore_fs_type = {
 
 
 static int __init init_pstore_fs(void)
 static int __init init_pstore_fs(void)
 {
 {
-	int rc = 0;
-	struct kobject *pstorefs_kobj;
-
-	pstorefs_kobj = kobject_create_and_add("pstore", fs_kobj);
-	if (!pstorefs_kobj) {
-		rc = -ENOMEM;
-		goto done;
-	}
-
-	rc = sysfs_create_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
-	if (rc)
-		goto done1;
-
-	rc = register_filesystem(&pstore_fs_type);
-	if (rc == 0)
-		goto done;
-
-	sysfs_remove_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
-done1:
-	kobject_put(pstorefs_kobj);
-done:
-	return rc;
+	return register_filesystem(&pstore_fs_type);
 }
 }
 module_init(init_pstore_fs)
 module_init(init_pstore_fs)
 
 

+ 1 - 2
fs/pstore/internal.h

@@ -1,7 +1,6 @@
+extern void	pstore_set_kmsg_bytes(int);
 extern void	pstore_get_records(void);
 extern void	pstore_get_records(void);
 extern int	pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
 extern int	pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
 			      char *data, size_t size,
 			      char *data, size_t size,
 			      struct timespec time, int (*erase)(u64));
 			      struct timespec time, int (*erase)(u64));
 extern int	pstore_is_mounted(void);
 extern int	pstore_is_mounted(void);
-
-extern struct kobj_attribute pstore_kmsg_bytes_attr;

+ 3 - 13
fs/pstore/platform.c

@@ -37,24 +37,14 @@
 static DEFINE_SPINLOCK(pstore_lock);
 static DEFINE_SPINLOCK(pstore_lock);
 static struct pstore_info *psinfo;
 static struct pstore_info *psinfo;
 
 
-/* How much of the console log to snapshot. /sys/fs/pstore/kmsg_bytes */
+/* How much of the console log to snapshot */
 static unsigned long kmsg_bytes = 10240;
 static unsigned long kmsg_bytes = 10240;
 
 
-static ssize_t b_show(struct kobject *kobj,
-		      struct kobj_attribute *attr, char *buf)
+void pstore_set_kmsg_bytes(int bytes)
 {
 {
-	return snprintf(buf, PAGE_SIZE, "%lu\n", kmsg_bytes);
+	kmsg_bytes = bytes;
 }
 }
 
 
-static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
-		       const char *buf, size_t count)
-{
-	return (sscanf(buf, "%lu", &kmsg_bytes) > 0) ? count : 0;
-}
-
-struct kobj_attribute pstore_kmsg_bytes_attr =
-	__ATTR(kmsg_bytes, S_IRUGO | S_IWUSR, b_show, b_store);
-
 /* Tag each group of saved records with a sequence number */
 /* Tag each group of saved records with a sequence number */
 static int	oopscount;
 static int	oopscount;