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>

authored by

Luck, Tony and committed by
Linus Torvalds
366f7e7a 10effcb5

+59 -47
+9 -3
Documentation/ABI/testing/pstore
··· 1 1 Where: /dev/pstore/... 2 - Date: January 2011 3 - Kernel Version: 2.6.38 2 + Date: March 2011 3 + Kernel Version: 2.6.39 4 4 Contact: tony.luck@intel.com 5 5 Description: Generic interface to platform dependent persistent storage. 6 6 ··· 11 11 of the console log is captured, but other interesting 12 12 data can also be saved. 13 13 14 - # mount -t pstore - /dev/pstore 14 + # mount -t pstore -o kmsg_bytes=8000 - /dev/pstore 15 15 16 16 $ ls -l /dev/pstore 17 17 total 0 ··· 33 33 will be saved elsewhere and erased from persistent store 34 34 soon after boot to free up space ready for the next 35 35 catastrophe. 36 + 37 + The 'kmsg_bytes' mount option changes the target amount of 38 + data saved on each oops/panic. Pstore saves (possibly 39 + multiple) files based on the record size of the underlying 40 + persistent storage until at least this amount is reached. 41 + Default is 10 Kbytes.
-7
Documentation/ABI/testing/sysfs-fs-pstore
··· 1 - What: /sys/fs/pstore/kmsg_bytes 2 - Date: January 2011 3 - Kernel Version: 2.6.38 4 - Contact: "Tony Luck" <tony.luck@intel.com> 5 - Description: 6 - Controls amount of console log that will be saved 7 - to persistent store on oops/panic.
+46 -22
fs/pstore/inode.c
··· 27 27 #include <linux/string.h> 28 28 #include <linux/mount.h> 29 29 #include <linux/ramfs.h> 30 + #include <linux/parser.h> 30 31 #include <linux/sched.h> 31 32 #include <linux/magic.h> 32 33 #include <linux/pstore.h> ··· 113 112 return inode; 114 113 } 115 114 115 + enum { 116 + Opt_kmsg_bytes, Opt_err 117 + }; 118 + 119 + static const match_table_t tokens = { 120 + {Opt_kmsg_bytes, "kmsg_bytes=%u"}, 121 + {Opt_err, NULL} 122 + }; 123 + 124 + static void parse_options(char *options) 125 + { 126 + char *p; 127 + substring_t args[MAX_OPT_ARGS]; 128 + int option; 129 + 130 + if (!options) 131 + return; 132 + 133 + while ((p = strsep(&options, ",")) != NULL) { 134 + int token; 135 + 136 + if (!*p) 137 + continue; 138 + 139 + token = match_token(p, tokens, args); 140 + switch (token) { 141 + case Opt_kmsg_bytes: 142 + if (!match_int(&args[0], &option)) 143 + pstore_set_kmsg_bytes(option); 144 + break; 145 + } 146 + } 147 + } 148 + 149 + static int pstore_remount(struct super_block *sb, int *flags, char *data) 150 + { 151 + parse_options(data); 152 + 153 + return 0; 154 + } 155 + 116 156 static const struct super_operations pstore_ops = { 117 157 .statfs = simple_statfs, 118 158 .drop_inode = generic_delete_inode, 119 159 .evict_inode = pstore_evict_inode, 160 + .remount_fs = pstore_remount, 120 161 .show_options = generic_show_options, 121 162 }; 122 163 ··· 258 215 sb->s_op = &pstore_ops; 259 216 sb->s_time_gran = 1; 260 217 218 + parse_options(data); 219 + 261 220 inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0); 262 221 if (!inode) { 263 222 err = -ENOMEM; ··· 303 258 304 259 static int __init init_pstore_fs(void) 305 260 { 306 - int rc = 0; 307 - struct kobject *pstorefs_kobj; 308 - 309 - pstorefs_kobj = kobject_create_and_add("pstore", fs_kobj); 310 - if (!pstorefs_kobj) { 311 - rc = -ENOMEM; 312 - goto done; 313 - } 314 - 315 - rc = sysfs_create_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr); 316 - if (rc) 317 - goto done1; 318 - 319 - rc = register_filesystem(&pstore_fs_type); 320 - if (rc == 0) 321 - goto done; 322 - 323 - sysfs_remove_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr); 324 - done1: 325 - kobject_put(pstorefs_kobj); 326 - done: 327 - return rc; 261 + return register_filesystem(&pstore_fs_type); 328 262 } 329 263 module_init(init_pstore_fs) 330 264
+1 -2
fs/pstore/internal.h
··· 1 + extern void pstore_set_kmsg_bytes(int); 1 2 extern void pstore_get_records(void); 2 3 extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, 3 4 char *data, size_t size, 4 5 struct timespec time, int (*erase)(u64)); 5 6 extern int pstore_is_mounted(void); 6 - 7 - extern struct kobj_attribute pstore_kmsg_bytes_attr;
+3 -13
fs/pstore/platform.c
··· 37 37 static DEFINE_SPINLOCK(pstore_lock); 38 38 static struct pstore_info *psinfo; 39 39 40 - /* How much of the console log to snapshot. /sys/fs/pstore/kmsg_bytes */ 40 + /* How much of the console log to snapshot */ 41 41 static unsigned long kmsg_bytes = 10240; 42 42 43 - static ssize_t b_show(struct kobject *kobj, 44 - struct kobj_attribute *attr, char *buf) 43 + void pstore_set_kmsg_bytes(int bytes) 45 44 { 46 - return snprintf(buf, PAGE_SIZE, "%lu\n", kmsg_bytes); 45 + kmsg_bytes = bytes; 47 46 } 48 - 49 - static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr, 50 - const char *buf, size_t count) 51 - { 52 - return (sscanf(buf, "%lu", &kmsg_bytes) > 0) ? count : 0; 53 - } 54 - 55 - struct kobj_attribute pstore_kmsg_bytes_attr = 56 - __ATTR(kmsg_bytes, S_IRUGO | S_IWUSR, b_show, b_store); 57 47 58 48 /* Tag each group of saved records with a sequence number */ 59 49 static int oopscount;