root/drivers/md/dm-exception-store.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. dm_chunk_number
  2. dm_consecutive_chunk_count
  3. dm_consecutive_chunk_count_inc
  4. dm_consecutive_chunk_count_dec
  5. get_dev_size
  6. sector_to_chunk

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

/* [<][>][^][v][top][bottom][index][help] */