linux/drivers/md/persistent-data/dm-space-map.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Red Hat, Inc.
   3 *
   4 * This file is released under the GPL.
   5 */
   6
   7#ifndef _LINUX_DM_SPACE_MAP_H
   8#define _LINUX_DM_SPACE_MAP_H
   9
  10#include "dm-block-manager.h"
  11
  12typedef void (*dm_sm_threshold_fn)(void *context);
  13
  14/*
  15 * struct dm_space_map keeps a record of how many times each block in a device
  16 * is referenced.  It needs to be fixed on disk as part of the transaction.
  17 */
  18struct dm_space_map {
  19        void (*destroy)(struct dm_space_map *sm);
  20
  21        /*
  22         * You must commit before allocating the newly added space.
  23         */
  24        int (*extend)(struct dm_space_map *sm, dm_block_t extra_blocks);
  25
  26        /*
  27         * Extensions do not appear in this count until after commit has
  28         * been called.
  29         */
  30        int (*get_nr_blocks)(struct dm_space_map *sm, dm_block_t *count);
  31
  32        /*
  33         * Space maps must never allocate a block from the previous
  34         * transaction, in case we need to rollback.  This complicates the
  35         * semantics of get_nr_free(), it should return the number of blocks
  36         * that are available for allocation _now_.  For instance you may
  37         * have blocks with a zero reference count that will not be
  38         * available for allocation until after the next commit.
  39         */
  40        int (*get_nr_free)(struct dm_space_map *sm, dm_block_t *count);
  41
  42        int (*get_count)(struct dm_space_map *sm, dm_block_t b, uint32_t *result);
  43        int (*count_is_more_than_one)(struct dm_space_map *sm, dm_block_t b,
  44                                      int *result);
  45        int (*set_count)(struct dm_space_map *sm, dm_block_t b, uint32_t count);
  46
  47        int (*commit)(struct dm_space_map *sm);
  48
  49        int (*inc_blocks)(struct dm_space_map *sm, dm_block_t b, dm_block_t e);
  50        int (*dec_blocks)(struct dm_space_map *sm, dm_block_t b, dm_block_t e);
  51
  52        /*
  53         * new_block will increment the returned block.
  54         */
  55        int (*new_block)(struct dm_space_map *sm, dm_block_t *b);
  56
  57        /*
  58         * The root contains all the information needed to fix the space map.
  59         * Generally this info is small, so squirrel it away in a disk block
  60         * along with other info.
  61         */
  62        int (*root_size)(struct dm_space_map *sm, size_t *result);
  63        int (*copy_root)(struct dm_space_map *sm, void *copy_to_here_le, size_t len);
  64
  65        /*
  66         * You can register one threshold callback which is edge-triggered
  67         * when the free space in the space map drops below the threshold.
  68         */
  69        int (*register_threshold_callback)(struct dm_space_map *sm,
  70                                           dm_block_t threshold,
  71                                           dm_sm_threshold_fn fn,
  72                                           void *context);
  73};
  74
  75/*----------------------------------------------------------------*/
  76
  77static inline void dm_sm_destroy(struct dm_space_map *sm)
  78{
  79        sm->destroy(sm);
  80}
  81
  82static inline int dm_sm_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
  83{
  84        return sm->extend(sm, extra_blocks);
  85}
  86
  87static inline int dm_sm_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
  88{
  89        return sm->get_nr_blocks(sm, count);
  90}
  91
  92static inline int dm_sm_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
  93{
  94        return sm->get_nr_free(sm, count);
  95}
  96
  97static inline int dm_sm_get_count(struct dm_space_map *sm, dm_block_t b,
  98                                  uint32_t *result)
  99{
 100        return sm->get_count(sm, b, result);
 101}
 102
 103static inline int dm_sm_count_is_more_than_one(struct dm_space_map *sm,
 104                                               dm_block_t b, int *result)
 105{
 106        return sm->count_is_more_than_one(sm, b, result);
 107}
 108
 109static inline int dm_sm_set_count(struct dm_space_map *sm, dm_block_t b,
 110                                  uint32_t count)
 111{
 112        return sm->set_count(sm, b, count);
 113}
 114
 115static inline int dm_sm_commit(struct dm_space_map *sm)
 116{
 117        return sm->commit(sm);
 118}
 119
 120static inline int dm_sm_inc_blocks(struct dm_space_map *sm, dm_block_t b, dm_block_t e)
 121{
 122        return sm->inc_blocks(sm, b, e);
 123}
 124
 125static inline int dm_sm_inc_block(struct dm_space_map *sm, dm_block_t b)
 126{
 127        return dm_sm_inc_blocks(sm, b, b + 1);
 128}
 129
 130static inline int dm_sm_dec_blocks(struct dm_space_map *sm, dm_block_t b, dm_block_t e)
 131{
 132        return sm->dec_blocks(sm, b, e);
 133}
 134
 135static inline int dm_sm_dec_block(struct dm_space_map *sm, dm_block_t b)
 136{
 137        return dm_sm_dec_blocks(sm, b, b + 1);
 138}
 139
 140static inline int dm_sm_new_block(struct dm_space_map *sm, dm_block_t *b)
 141{
 142        return sm->new_block(sm, b);
 143}
 144
 145static inline int dm_sm_root_size(struct dm_space_map *sm, size_t *result)
 146{
 147        return sm->root_size(sm, result);
 148}
 149
 150static inline int dm_sm_copy_root(struct dm_space_map *sm, void *copy_to_here_le, size_t len)
 151{
 152        return sm->copy_root(sm, copy_to_here_le, len);
 153}
 154
 155static inline int dm_sm_register_threshold_callback(struct dm_space_map *sm,
 156                                                    dm_block_t threshold,
 157                                                    dm_sm_threshold_fn fn,
 158                                                    void *context)
 159{
 160        if (sm->register_threshold_callback)
 161                return sm->register_threshold_callback(sm, threshold, fn, context);
 162
 163        return -EINVAL;
 164}
 165
 166
 167#endif  /* _LINUX_DM_SPACE_MAP_H */
 168