hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/fs/pstore/inode.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Persistent Storage - ramfs parts.
34 *
45 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
186 */
197
208 #include <linux/module.h>
....@@ -34,10 +22,9 @@
3422 #include <linux/magic.h>
3523 #include <linux/pstore.h>
3624 #include <linux/slab.h>
37
-#include <linux/spinlock.h>
3825 #include <linux/uaccess.h>
3926
40
-#ifdef CONFIG_PSTORE_MCU_LOG
27
+#ifdef CONFIG_PSTORE_BOOT_LOG
4128 #include <linux/pstore_ram.h>
4229 #include <linux/io.h>
4330 #endif
....@@ -46,11 +33,15 @@
4633
4734 #define PSTORE_NAMELEN 64
4835
49
-static DEFINE_SPINLOCK(allpstore_lock);
50
-static LIST_HEAD(allpstore);
36
+static DEFINE_MUTEX(records_list_lock);
37
+static LIST_HEAD(records_list);
38
+
39
+static DEFINE_MUTEX(pstore_sb_lock);
40
+static struct super_block *pstore_sb;
5141
5242 struct pstore_private {
5343 struct list_head list;
44
+ struct dentry *dentry;
5445 struct pstore_record *record;
5546 size_t total_size;
5647 };
....@@ -123,7 +114,7 @@
123114
124115 rec = (struct pstore_ftrace_record *)(ps->record->buf + data->off);
125116
126
- seq_printf(s, "CPU:%d ts:%llu %08lx %08lx %pf <- %pF\n",
117
+ seq_printf(s, "CPU:%d ts:%llu %08lx %08lx %ps <- %pS\n",
127118 pstore_ftrace_decode_cpu(rec),
128119 pstore_ftrace_read_timestamp(rec),
129120 rec->ip, rec->parent_ip, (void *)rec->ip,
....@@ -144,40 +135,14 @@
144135 {
145136 struct seq_file *sf = file->private_data;
146137 struct pstore_private *ps = sf->private;
147
-#ifdef CONFIG_PSTORE_MCU_LOG
138
+#ifdef CONFIG_PSTORE_BOOT_LOG
139
+ size_t size = 0;
148140 struct pstore_record *record = ps->record;
149
- struct ramoops_context *cxt = record->psi->data;
150
- struct persistent_ram_zone *prz;
151
- struct persistent_ram_buffer *buffer;
152
- char *log_tmp;
153
- size_t size, start, n;
154141
155
- if (ps->record->type == PSTORE_TYPE_MCU_LOG) {
156
-
157
- if (!cxt)
158
- return count;
159
-
160
- prz = cxt->mcu_przs[record->id];
161
-
162
- if (!prz)
163
- return count;
164
-
165
- buffer = prz->buffer;
166
- if (!buffer)
167
- return count;
168
-
169
- size = atomic_read(&buffer->size);
170
- start = atomic_read(&buffer->start);
171
-
172
- log_tmp = kmalloc(size, GFP_KERNEL);
173
- if (!log_tmp)
174
- return count;
175
- memcpy_fromio(log_tmp, &buffer->data[start], size - start);
176
- memcpy_fromio(log_tmp + size - start, &buffer->data[0], start);
177
-
178
- n = simple_read_from_buffer(userbuf, count, ppos, log_tmp, size);
179
- kfree(log_tmp);
180
- return n;
142
+ if (record->type == PSTORE_TYPE_BOOT_LOG) {
143
+ size = ramoops_pstore_read_for_boot_log(ps->record);
144
+ size = simple_read_from_buffer(userbuf, count, ppos, record->buf, size);
145
+ return size;
181146 }
182147 #endif
183148 if (ps->record->type == PSTORE_TYPE_FTRACE)
....@@ -230,9 +195,21 @@
230195 {
231196 struct pstore_private *p = d_inode(dentry)->i_private;
232197 struct pstore_record *record = p->record;
198
+ int rc = 0;
233199
234200 if (!record->psi->erase)
235201 return -EPERM;
202
+
203
+ /* Make sure we can't race while removing this file. */
204
+ mutex_lock(&records_list_lock);
205
+ if (!list_empty(&p->list))
206
+ list_del_init(&p->list);
207
+ else
208
+ rc = -ENOENT;
209
+ p->dentry = NULL;
210
+ mutex_unlock(&records_list_lock);
211
+ if (rc)
212
+ return rc;
236213
237214 mutex_lock(&record->psi->read_mutex);
238215 record->psi->erase(record);
....@@ -244,15 +221,9 @@
244221 static void pstore_evict_inode(struct inode *inode)
245222 {
246223 struct pstore_private *p = inode->i_private;
247
- unsigned long flags;
248224
249225 clear_inode(inode);
250
- if (p) {
251
- spin_lock_irqsave(&allpstore_lock, flags);
252
- list_del(&p->list);
253
- spin_unlock_irqrestore(&allpstore_lock, flags);
254
- free_pstore_private(p);
255
- }
226
+ free_pstore_private(p);
256227 }
257228
258229 static const struct inode_operations pstore_dir_inode_operations = {
....@@ -330,11 +301,54 @@
330301 .show_options = pstore_show_options,
331302 };
332303
333
-static struct super_block *pstore_sb;
334
-
335
-bool pstore_is_mounted(void)
304
+static struct dentry *psinfo_lock_root(void)
336305 {
337
- return pstore_sb != NULL;
306
+ struct dentry *root;
307
+
308
+ mutex_lock(&pstore_sb_lock);
309
+ /*
310
+ * Having no backend is fine -- no records appear.
311
+ * Not being mounted is fine -- nothing to do.
312
+ */
313
+ if (!psinfo || !pstore_sb) {
314
+ mutex_unlock(&pstore_sb_lock);
315
+ return NULL;
316
+ }
317
+
318
+ root = pstore_sb->s_root;
319
+ inode_lock(d_inode(root));
320
+ mutex_unlock(&pstore_sb_lock);
321
+
322
+ return root;
323
+}
324
+
325
+int pstore_put_backend_records(struct pstore_info *psi)
326
+{
327
+ struct pstore_private *pos, *tmp;
328
+ struct dentry *root;
329
+ int rc = 0;
330
+
331
+ root = psinfo_lock_root();
332
+ if (!root)
333
+ return 0;
334
+
335
+ mutex_lock(&records_list_lock);
336
+ list_for_each_entry_safe(pos, tmp, &records_list, list) {
337
+ if (pos->record->psi == psi) {
338
+ list_del_init(&pos->list);
339
+ rc = simple_unlink(d_inode(root), pos->dentry);
340
+ if (WARN_ON(rc))
341
+ break;
342
+ d_drop(pos->dentry);
343
+ dput(pos->dentry);
344
+ pos->dentry = NULL;
345
+ }
346
+ }
347
+ mutex_unlock(&records_list_lock);
348
+
349
+ inode_unlock(d_inode(root));
350
+
351
+ return rc;
338352 }
339353
340354 /*
....@@ -349,23 +363,20 @@
349363 int rc = 0;
350364 char name[PSTORE_NAMELEN];
351365 struct pstore_private *private, *pos;
352
- unsigned long flags;
353366 size_t size = record->size + record->ecc_notice_size;
354367
355
- WARN_ON(!inode_is_locked(d_inode(root)));
368
+ if (WARN_ON(!inode_is_locked(d_inode(root))))
369
+ return -EINVAL;
356370
357
- spin_lock_irqsave(&allpstore_lock, flags);
358
- list_for_each_entry(pos, &allpstore, list) {
371
+ rc = -EEXIST;
372
+ /* Skip records that are already present in the filesystem. */
373
+ mutex_lock(&records_list_lock);
374
+ list_for_each_entry(pos, &records_list, list) {
359375 if (pos->record->type == record->type &&
360376 pos->record->id == record->id &&
361
- pos->record->psi == record->psi) {
362
- rc = -EEXIST;
363
- break;
364
- }
377
+ pos->record->psi == record->psi)
378
+ goto fail;
365379 }
366
- spin_unlock_irqrestore(&allpstore_lock, flags);
367
- if (rc)
368
- return rc;
369380
370381 rc = -ENOMEM;
371382 inode = pstore_get_inode(root->d_sb);
....@@ -373,59 +384,10 @@
373384 goto fail;
374385 inode->i_mode = S_IFREG | 0444;
375386 inode->i_fop = &pstore_file_operations;
376
-
377
- switch (record->type) {
378
- case PSTORE_TYPE_DMESG:
379
- scnprintf(name, sizeof(name), "dmesg-%s-%llu%s",
380
- record->psi->name, record->id,
381
- record->compressed ? ".enc.z" : "");
382
- break;
383
- case PSTORE_TYPE_CONSOLE:
384
- scnprintf(name, sizeof(name), "console-%s-%llu",
385
- record->psi->name, record->id);
386
- break;
387
- case PSTORE_TYPE_FTRACE:
388
- scnprintf(name, sizeof(name), "ftrace-%s-%llu",
389
- record->psi->name, record->id);
390
- break;
391
- case PSTORE_TYPE_MCE:
392
- scnprintf(name, sizeof(name), "mce-%s-%llu",
393
- record->psi->name, record->id);
394
- break;
395
- case PSTORE_TYPE_PPC_RTAS:
396
- scnprintf(name, sizeof(name), "rtas-%s-%llu",
397
- record->psi->name, record->id);
398
- break;
399
- case PSTORE_TYPE_PPC_OF:
400
- scnprintf(name, sizeof(name), "powerpc-ofw-%s-%llu",
401
- record->psi->name, record->id);
402
- break;
403
- case PSTORE_TYPE_PPC_COMMON:
404
- scnprintf(name, sizeof(name), "powerpc-common-%s-%llu",
405
- record->psi->name, record->id);
406
- break;
407
- case PSTORE_TYPE_PMSG:
408
- scnprintf(name, sizeof(name), "pmsg-%s-%llu",
409
- record->psi->name, record->id);
410
- break;
411
- case PSTORE_TYPE_PPC_OPAL:
412
- scnprintf(name, sizeof(name), "powerpc-opal-%s-%llu",
413
- record->psi->name, record->id);
414
- break;
415
-#ifdef CONFIG_PSTORE_MCU_LOG
416
- case PSTORE_TYPE_MCU_LOG:
417
- scnprintf(name, sizeof(name), "mcu-log-%llu", record->id);
418
- break;
419
-#endif
420
- case PSTORE_TYPE_UNKNOWN:
421
- scnprintf(name, sizeof(name), "unknown-%s-%llu",
422
- record->psi->name, record->id);
423
- break;
424
- default:
425
- scnprintf(name, sizeof(name), "type%d-%s-%llu",
426
- record->type, record->psi->name, record->id);
427
- break;
428
- }
387
+ scnprintf(name, sizeof(name), "%s-%s-%llu%s",
388
+ pstore_type_to_name(record->type),
389
+ record->psi->name, record->id,
390
+ record->compressed ? ".enc.z" : "");
429391
430392 private = kzalloc(sizeof(*private), GFP_KERNEL);
431393 if (!private)
....@@ -435,6 +397,7 @@
435397 if (!dentry)
436398 goto fail_private;
437399
400
+ private->dentry = dentry;
438401 private->record = record;
439402 inode->i_size = private->total_size = size;
440403 inode->i_private = private;
....@@ -444,9 +407,8 @@
444407
445408 d_add(dentry, inode);
446409
447
- spin_lock_irqsave(&allpstore_lock, flags);
448
- list_add(&private->list, &allpstore);
449
- spin_unlock_irqrestore(&allpstore_lock, flags);
410
+ list_add(&private->list, &records_list);
411
+ mutex_unlock(&records_list_lock);
450412
451413 return 0;
452414
....@@ -454,8 +416,8 @@
454416 free_pstore_private(private);
455417 fail_inode:
456418 iput(inode);
457
-
458419 fail:
420
+ mutex_unlock(&records_list_lock);
459421 return rc;
460422 }
461423
....@@ -467,24 +429,19 @@
467429 */
468430 void pstore_get_records(int quiet)
469431 {
470
- struct pstore_info *psi = psinfo;
471432 struct dentry *root;
472433
473
- if (!psi || !pstore_sb)
434
+ root = psinfo_lock_root();
435
+ if (!root)
474436 return;
475437
476
- root = pstore_sb->s_root;
477
-
478
- inode_lock(d_inode(root));
479
- pstore_get_backend_records(psi, root, quiet);
438
+ pstore_get_backend_records(psinfo, root, quiet);
480439 inode_unlock(d_inode(root));
481440 }
482441
483442 static int pstore_fill_super(struct super_block *sb, void *data, int silent)
484443 {
485444 struct inode *inode;
486
-
487
- pstore_sb = sb;
488445
489446 sb->s_maxbytes = MAX_LFS_FILESIZE;
490447 sb->s_blocksize = PAGE_SIZE;
....@@ -506,6 +463,10 @@
506463 if (!sb->s_root)
507464 return -ENOMEM;
508465
466
+ mutex_lock(&pstore_sb_lock);
467
+ pstore_sb = sb;
468
+ mutex_unlock(&pstore_sb_lock);
469
+
509470 pstore_get_records(0);
510471
511472 return 0;
....@@ -519,8 +480,17 @@
519480
520481 static void pstore_kill_sb(struct super_block *sb)
521482 {
483
+ mutex_lock(&pstore_sb_lock);
484
+ WARN_ON(pstore_sb && pstore_sb != sb);
485
+
522486 kill_litter_super(sb);
523487 pstore_sb = NULL;
488
+
489
+ mutex_lock(&records_list_lock);
490
+ INIT_LIST_HEAD(&records_list);
491
+ mutex_unlock(&records_list_lock);
492
+
493
+ mutex_unlock(&pstore_sb_lock);
524494 }
525495
526496 static struct file_system_type pstore_fs_type = {