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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Device-mapper snapshot exception store.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #ifndef _LINUX_DM_EXCEPTION_STORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define _LINUX_DM_EXCEPTION_STORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/list_bl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * The snapshot code deals with largish chunks of the disk at a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * time. Typically 32k - 512k.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) typedef sector_t chunk_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * An exception is used where an old chunk of data has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * replaced by a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * of chunks that follow contiguously.  Remaining bits hold the number of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * chunk within the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) struct dm_exception {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct hlist_bl_node hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	chunk_t old_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	chunk_t new_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * Abstraction to handle the meta/layout of exception stores (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * COW device).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) struct dm_exception_store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct dm_exception_store_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct module *module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int (*ctr) (struct dm_exception_store *store, char *options);
^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) 	 * Destroys this object when you've finished with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	void (*dtr) (struct dm_exception_store *store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	 * The target shouldn't read the COW device until this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	 * called.  As exceptions are read from the COW, they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	 * reported back via the callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int (*read_metadata) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			      int (*callback)(void *callback_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 					      chunk_t old, chunk_t new),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			      void *callback_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	 * Find somewhere to store the next exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int (*prepare_exception) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 				  struct dm_exception *e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * Update the metadata with this exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	void (*commit_exception) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				  struct dm_exception *e, int valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				  void (*callback) (void *, int success),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				  void *callback_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * Returns 0 if the exception store is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * If there are exceptions still to be merged, sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * *last_old_chunk and *last_new_chunk to the most recent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * still-to-be-merged chunk and returns the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * consecutive previous ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int (*prepare_merge) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			      chunk_t *last_old_chunk, chunk_t *last_new_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 * Clear the last n exceptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * nr_merged must be <= the value returned by prepare_merge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	int (*commit_merge) (struct dm_exception_store *store, int nr_merged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 * The snapshot is invalid, note this in the metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	void (*drop_snapshot) (struct dm_exception_store *store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	unsigned (*status) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			    status_type_t status, char *result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			    unsigned maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	 * Return how full the snapshot is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	void (*usage) (struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		       sector_t *total_sectors, sector_t *sectors_allocated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		       sector_t *metadata_sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* For internal device-mapper use only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct dm_snapshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct dm_exception_store {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct dm_exception_store_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct dm_snapshot *snap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* Size of data blocks saved - must be a power of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	unsigned chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	unsigned chunk_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	unsigned chunk_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	void *context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	bool userspace_supports_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * Obtain the origin or cow device used by a given snapshot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct dm_dev *dm_snap_origin(struct dm_snapshot *snap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct dm_dev *dm_snap_cow(struct dm_snapshot *snap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * Funtions to manipulate consecutive chunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define DM_CHUNK_CONSECUTIVE_BITS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define DM_CHUNK_NUMBER_BITS 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static inline chunk_t dm_chunk_number(chunk_t chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	return e->new_chunk >> DM_CHUNK_NUMBER_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	BUG_ON(!dm_consecutive_chunk_count(e));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	BUG_ON(!dm_consecutive_chunk_count(e));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * Return the number of sectors in the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline sector_t get_dev_size(struct block_device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
^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 inline chunk_t sector_to_chunk(struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				      sector_t sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return sector >> store->chunk_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int dm_exception_store_type_register(struct dm_exception_store_type *type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				      unsigned chunk_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 				      char **error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			      struct dm_snapshot *snap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			      unsigned *args_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			      struct dm_exception_store **store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void dm_exception_store_destroy(struct dm_exception_store *store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int dm_exception_store_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void dm_exception_store_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * Two exception store implementations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int dm_persistent_snapshot_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) void dm_persistent_snapshot_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int dm_transient_snapshot_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void dm_transient_snapshot_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #endif /* _LINUX_DM_EXCEPTION_STORE */