// SPDX-License-Identifier: GPL-2.0
/*
* Provide a pstore intermediate backend, organized into kernel memory
* allocated zones that are then mapped and flushed into a single
* contiguous region on a storage backend of some kind (block, mtd, etc).
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/printk.h>
#include <linux/fs.h>
#include <linux/pstore_zone.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <linux/namei.h>
#include <linux/fcntl.h>
#include <linux/uio.h>
#include <linux/writeback.h>
#include "internal.h"
/**
* struct psz_head - header of zone to flush to storage
*
* @sig: signature to indicate header (PSZ_SIG xor PSZONE-type value)
* @datalen: length of data in @data
* @start: offset into @data where the beginning of the stored bytes begin
* @data: zone data.
*/
struct psz_buffer {
#define PSZ_SIG (0x43474244) /* DBGC */
uint32_t sig;
atomic_t datalen;
atomic_t start;
uint8_t data[];
};
/**
* struct psz_kmsg_header - kmsg dump-specific header to flush to storage
*
* @magic: magic num for kmsg dump header
* @time: kmsg dump trigger time
* @compressed: whether conpressed
* @counter: kmsg dump counter
* @reason: the kmsg dump reason (e.g. oops, panic, etc)
* @data: pointer to log data
*
* This is a sub-header for a kmsg dump, trailing after &psz_buffer.
*/
struct psz_kmsg_header {
#define PSTORE_KMSG_HEADER_MAGIC 0x4dfc3ae5 /* Just a random number */
uint32_t magic;
struct timespec64 time;
bool compressed;
uint32_t counter;
enum kmsg_dump_reason reason;
uint8_t data[];
};
/**
* struct pstore_zone - single stored buffer
*
* @off: zone offset of storage
* @type: front-end type for this zone
* @name: front-end name for this zone
* @buffer: pointer to data buffer managed by this zone
* @oldbuf: pointer to old data buffer
* @buffer_size: bytes in @buffer->data
* @should_recover: whether this zone should recover from storage
* @dirty: whether the data in @buffer dirty
*
* zone structure in memory.
*/
struct pstore_zone {