linux/drivers/md/dm-snap-persistent.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
 * Copyright (C) 2006-2008 Red Hat GmbH
 *
 * This file is released under the GPL.
 */

#include "dm-exception-store.h"

#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/dm-io.h>
#include <linux/dm-bufio.h>

#define DM_MSG_PREFIX
#define DM_CHUNK_SIZE_DEFAULT_SECTORS

#define DM_PREFETCH_CHUNKS

/*
 *---------------------------------------------------------------
 * Persistent snapshots, by persistent we mean that the snapshot
 * will survive a reboot.
 *---------------------------------------------------------------
 */

/*
 * We need to store a record of which parts of the origin have
 * been copied to the snapshot device.  The snapshot code
 * requires that we copy exception chunks to chunk aligned areas
 * of the COW store.  It makes sense therefore, to store the
 * metadata in chunk size blocks.
 *
 * There is no backward or forward compatibility implemented,
 * snapshots with different disk versions than the kernel will
 * not be usable.  It is expected that "lvcreate" will blank out
 * the start of a fresh COW device before calling the snapshot
 * constructor.
 *
 * The first chunk of the COW device just contains the header.
 * After this there is a chunk filled with exception metadata,
 * followed by as many exception chunks as can fit in the
 * metadata areas.
 *
 * All on disk structures are in little-endian format.  The end
 * of the exceptions info is indicated by an exception with a
 * new_chunk of 0, which is invalid since it would point to the
 * header chunk.
 */

/*
 * Magic for persistent snapshots: "SnAp" - Feeble isn't it.
 */
#define SNAP_MAGIC

/*
 * The on-disk version of the metadata.
 */
#define SNAPSHOT_DISK_VERSION

#define NUM_SNAPSHOT_HDR_CHUNKS

struct disk_header {} __packed;

struct disk_exception {} __packed;

struct core_exception {};

struct commit_callback {};

/*
 * The top level structure for a persistent exception store.
 */
struct pstore {};

static int alloc_area(struct pstore *ps)
{}

static void free_area(struct pstore *ps)
{}

struct mdata_req {};

static void do_metadata(struct work_struct *work)
{}

/*
 * Read or write a chunk aligned and sized block of data from a device.
 */
static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, blk_opf_t opf,
		    int metadata)
{}

/*
 * Convert a metadata area index to a chunk index.
 */
static chunk_t area_location(struct pstore *ps, chunk_t area)
{}

static void skip_metadata(struct pstore *ps)
{}

/*
 * Read or write a metadata area.  Remembering to skip the first
 * chunk which holds the header.
 */
static int area_io(struct pstore *ps, blk_opf_t opf)
{}

static void zero_memory_area(struct pstore *ps)
{}

static int zero_disk_area(struct pstore *ps, chunk_t area)
{}

static int read_header(struct pstore *ps, int *new_snapshot)
{}

static int write_header(struct pstore *ps)
{}

/*
 * Access functions for the disk exceptions, these do the endian conversions.
 */
static struct disk_exception *get_exception(struct pstore *ps, void *ps_area,
					    uint32_t index)
{}

static void read_exception(struct pstore *ps, void *ps_area,
			   uint32_t index, struct core_exception *result)
{}

static void write_exception(struct pstore *ps,
			    uint32_t index, struct core_exception *e)
{}

static void clear_exception(struct pstore *ps, uint32_t index)
{}

/*
 * Registers the exceptions that are present in the current area.
 * 'full' is filled in to indicate if the area has been
 * filled.
 */
static int insert_exceptions(struct pstore *ps, void *ps_area,
			     int (*callback)(void *callback_context,
					     chunk_t old, chunk_t new),
			     void *callback_context,
			     int *full)
{}

static int read_exceptions(struct pstore *ps,
			   int (*callback)(void *callback_context, chunk_t old,
					   chunk_t new),
			   void *callback_context)
{}

static struct pstore *get_info(struct dm_exception_store *store)
{}

static void persistent_usage(struct dm_exception_store *store,
			     sector_t *total_sectors,
			     sector_t *sectors_allocated,
			     sector_t *metadata_sectors)
{}

static void persistent_dtr(struct dm_exception_store *store)
{}

static int persistent_read_metadata(struct dm_exception_store *store,
				    int (*callback)(void *callback_context,
						    chunk_t old, chunk_t new),
				    void *callback_context)
{}

static int persistent_prepare_exception(struct dm_exception_store *store,
					struct dm_exception *e)
{}

static void persistent_commit_exception(struct dm_exception_store *store,
					struct dm_exception *e, int valid,
					void (*callback)(void *, int success),
					void *callback_context)
{}

static int persistent_prepare_merge(struct dm_exception_store *store,
				    chunk_t *last_old_chunk,
				    chunk_t *last_new_chunk)
{}

static int persistent_commit_merge(struct dm_exception_store *store,
				   int nr_merged)
{}

static void persistent_drop_snapshot(struct dm_exception_store *store)
{}

static int persistent_ctr(struct dm_exception_store *store, char *options)
{}

static unsigned int persistent_status(struct dm_exception_store *store,
				  status_type_t status, char *result,
				  unsigned int maxlen)
{}

static struct dm_exception_store_type _persistent_type =;

static struct dm_exception_store_type _persistent_compat_type =;

int dm_persistent_snapshot_init(void)
{}

void dm_persistent_snapshot_exit(void)
{}