Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Persistent Storage - ramfs parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/fsnotify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/ramfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/pstore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/pstore_ram.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define	PSTORE_NAMELEN	64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static DEFINE_MUTEX(records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static LIST_HEAD(records_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static DEFINE_MUTEX(pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static struct super_block *pstore_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct pstore_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct pstore_record *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	size_t total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) struct pstore_ftrace_seq_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	const void *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define REC_SIZE sizeof(struct pstore_ftrace_record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static void free_pstore_private(struct pstore_private *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (!private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (private->record) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		kfree(private->record->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		kfree(private->record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	kfree(private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static void *pstore_ftrace_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct pstore_private *ps = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct pstore_ftrace_seq_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	data->off = ps->total_size % REC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	data->off += *pos * REC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (data->off + REC_SIZE > ps->total_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static void pstore_ftrace_seq_stop(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	kfree(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static void *pstore_ftrace_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct pstore_private *ps = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct pstore_ftrace_seq_data *data = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	(*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	data->off += REC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (data->off + REC_SIZE > ps->total_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int pstore_ftrace_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct pstore_private *ps = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct pstore_ftrace_seq_data *data = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct pstore_ftrace_record *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	rec = (struct pstore_ftrace_record *)(ps->record->buf + data->off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	seq_printf(s, "CPU:%d ts:%llu %08lx  %08lx  %ps <- %pS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		   pstore_ftrace_decode_cpu(rec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		   pstore_ftrace_read_timestamp(rec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		   rec->ip, rec->parent_ip, (void *)rec->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		   (void *)rec->parent_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static const struct seq_operations pstore_ftrace_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	.start	= pstore_ftrace_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	.next	= pstore_ftrace_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	.stop	= pstore_ftrace_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	.show	= pstore_ftrace_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static ssize_t pstore_file_read(struct file *file, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 						size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	struct seq_file *sf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct pstore_private *ps = sf->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	size_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct pstore_record *record = ps->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (record->type == PSTORE_TYPE_BOOT_LOG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		size = ramoops_pstore_read_for_boot_log(ps->record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		size = simple_read_from_buffer(userbuf, count, ppos, record->buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (ps->record->type == PSTORE_TYPE_FTRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return seq_read(file, userbuf, count, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return simple_read_from_buffer(userbuf, count, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 				       ps->record->buf, ps->total_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int pstore_file_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct pstore_private *ps = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct seq_file *sf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	const struct seq_operations *sops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (ps->record->type == PSTORE_TYPE_FTRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		sops = &pstore_ftrace_seq_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	err = seq_open(file, sops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	sf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	sf->private = ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static loff_t pstore_file_llseek(struct file *file, loff_t off, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	struct seq_file *sf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (sf->op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return seq_lseek(file, off, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return default_llseek(file, off, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const struct file_operations pstore_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	.open		= pstore_file_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	.read		= pstore_file_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.llseek		= pstore_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.release	= seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * When a file is unlinked from our file system we call the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * platform driver to erase the record from persistent store.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int pstore_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct pstore_private *p = d_inode(dentry)->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct pstore_record *record = p->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (!record->psi->erase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* Make sure we can't race while removing this file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	mutex_lock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (!list_empty(&p->list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		list_del_init(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	p->dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	mutex_unlock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	mutex_lock(&record->psi->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	record->psi->erase(record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	mutex_unlock(&record->psi->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return simple_unlink(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void pstore_evict_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct pstore_private	*p = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	clear_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	free_pstore_private(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static const struct inode_operations pstore_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	.lookup		= simple_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	.unlink		= pstore_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static struct inode *pstore_get_inode(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct inode *inode = new_inode(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		inode->i_ino = get_next_ino();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	Opt_kmsg_bytes, Opt_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const match_table_t tokens = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	{Opt_kmsg_bytes, "kmsg_bytes=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	{Opt_err, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void parse_options(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	char		*p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	substring_t	args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	int		option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	if (!options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	while ((p = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		token = match_token(p, tokens, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		case Opt_kmsg_bytes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			if (!match_int(&args[0], &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 				pstore_set_kmsg_bytes(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * Display the mount options in /proc/mounts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int pstore_show_options(struct seq_file *m, struct dentry *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (kmsg_bytes != PSTORE_DEFAULT_KMSG_BYTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		seq_printf(m, ",kmsg_bytes=%lu", kmsg_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int pstore_remount(struct super_block *sb, int *flags, char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	sync_filesystem(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	parse_options(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static const struct super_operations pstore_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.statfs		= simple_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	.drop_inode	= generic_delete_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.evict_inode	= pstore_evict_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.remount_fs	= pstore_remount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	.show_options	= pstore_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static struct dentry *psinfo_lock_root(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	struct dentry *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	mutex_lock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	 * Having no backend is fine -- no records appear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * Not being mounted is fine -- nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (!psinfo || !pstore_sb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		mutex_unlock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	root = pstore_sb->s_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	inode_lock(d_inode(root));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	mutex_unlock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	return root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int pstore_put_backend_records(struct pstore_info *psi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct pstore_private *pos, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct dentry *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	root = psinfo_lock_root();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (!root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	mutex_lock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	list_for_each_entry_safe(pos, tmp, &records_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		if (pos->record->psi == psi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			list_del_init(&pos->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			rc = simple_unlink(d_inode(root), pos->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			if (WARN_ON(rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			d_drop(pos->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			dput(pos->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			pos->dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	mutex_unlock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	inode_unlock(d_inode(root));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * Make a regular file in the root directory of our file system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * Load it up with "size" bytes of data from "buf".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * Set the mtime & ctime to the date that this record was originally stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int pstore_mkfile(struct dentry *root, struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	struct dentry		*dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	struct inode		*inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	int			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	char			name[PSTORE_NAMELEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct pstore_private	*private, *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	size_t			size = record->size + record->ecc_notice_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (WARN_ON(!inode_is_locked(d_inode(root))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* Skip records that are already present in the filesystem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	mutex_lock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	list_for_each_entry(pos, &records_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		if (pos->record->type == record->type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		    pos->record->id == record->id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		    pos->record->psi == record->psi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	inode = pstore_get_inode(root->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	inode->i_mode = S_IFREG | 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	inode->i_fop = &pstore_file_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	scnprintf(name, sizeof(name), "%s-%s-%llu%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			pstore_type_to_name(record->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			record->psi->name, record->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			record->compressed ? ".enc.z" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	private = kzalloc(sizeof(*private), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (!private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		goto fail_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	dentry = d_alloc_name(root, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		goto fail_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	private->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	private->record = record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	inode->i_size = private->total_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	inode->i_private = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (record->time.tv_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		inode->i_mtime = inode->i_ctime = record->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	d_add(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	list_add(&private->list, &records_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	mutex_unlock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) fail_private:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	free_pstore_private(private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) fail_inode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	mutex_unlock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  * Read all the records from the persistent store. Create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  * files in our filesystem.  Don't warn about -EEXIST errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * when we are re-scanning the backing store looking to add new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  * error records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) void pstore_get_records(int quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct dentry *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	root = psinfo_lock_root();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (!root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	pstore_get_backend_records(psinfo, root, quiet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	inode_unlock(d_inode(root));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int pstore_fill_super(struct super_block *sb, void *data, int silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	sb->s_maxbytes		= MAX_LFS_FILESIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	sb->s_blocksize		= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	sb->s_blocksize_bits	= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	sb->s_magic		= PSTOREFS_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	sb->s_op		= &pstore_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	sb->s_time_gran		= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	parse_options(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	inode = pstore_get_inode(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		inode->i_mode = S_IFDIR | 0750;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		inode->i_op = &pstore_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		inode->i_fop = &simple_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		inc_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	sb->s_root = d_make_root(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if (!sb->s_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	mutex_lock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	pstore_sb = sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	mutex_unlock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	pstore_get_records(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static struct dentry *pstore_mount(struct file_system_type *fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	int flags, const char *dev_name, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	return mount_single(fs_type, flags, data, pstore_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static void pstore_kill_sb(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	mutex_lock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	WARN_ON(pstore_sb && pstore_sb != sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	kill_litter_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	pstore_sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	mutex_lock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	INIT_LIST_HEAD(&records_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	mutex_unlock(&records_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	mutex_unlock(&pstore_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static struct file_system_type pstore_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	.owner          = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	.name		= "pstore",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	.mount		= pstore_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	.kill_sb	= pstore_kill_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int __init pstore_init_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	/* Create a convenient mount point for people to access pstore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	err = sysfs_create_mount_point(fs_kobj, "pstore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	err = register_filesystem(&pstore_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		sysfs_remove_mount_point(fs_kobj, "pstore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) void __exit pstore_exit_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	unregister_filesystem(&pstore_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	sysfs_remove_mount_point(fs_kobj, "pstore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }