| Joe Thornber | 3241b1d | 2011-10-31 20:19:11 +0000 | [diff] [blame] | 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 |  | 
|  | 12 | /* | 
|  | 13 | * struct dm_space_map keeps a record of how many times each block in a device | 
|  | 14 | * is referenced.  It needs to be fixed on disk as part of the transaction. | 
|  | 15 | */ | 
|  | 16 | struct dm_space_map { | 
|  | 17 | void (*destroy)(struct dm_space_map *sm); | 
|  | 18 |  | 
|  | 19 | /* | 
|  | 20 | * You must commit before allocating the newly added space. | 
|  | 21 | */ | 
|  | 22 | int (*extend)(struct dm_space_map *sm, dm_block_t extra_blocks); | 
|  | 23 |  | 
|  | 24 | /* | 
|  | 25 | * Extensions do not appear in this count until after commit has | 
|  | 26 | * been called. | 
|  | 27 | */ | 
|  | 28 | int (*get_nr_blocks)(struct dm_space_map *sm, dm_block_t *count); | 
|  | 29 |  | 
|  | 30 | /* | 
|  | 31 | * Space maps must never allocate a block from the previous | 
|  | 32 | * transaction, in case we need to rollback.  This complicates the | 
|  | 33 | * semantics of get_nr_free(), it should return the number of blocks | 
|  | 34 | * that are available for allocation _now_.  For instance you may | 
|  | 35 | * have blocks with a zero reference count that will not be | 
|  | 36 | * available for allocation until after the next commit. | 
|  | 37 | */ | 
|  | 38 | int (*get_nr_free)(struct dm_space_map *sm, dm_block_t *count); | 
|  | 39 |  | 
|  | 40 | int (*get_count)(struct dm_space_map *sm, dm_block_t b, uint32_t *result); | 
|  | 41 | int (*count_is_more_than_one)(struct dm_space_map *sm, dm_block_t b, | 
|  | 42 | int *result); | 
|  | 43 | int (*set_count)(struct dm_space_map *sm, dm_block_t b, uint32_t count); | 
|  | 44 |  | 
|  | 45 | int (*commit)(struct dm_space_map *sm); | 
|  | 46 |  | 
|  | 47 | int (*inc_block)(struct dm_space_map *sm, dm_block_t b); | 
|  | 48 | int (*dec_block)(struct dm_space_map *sm, dm_block_t b); | 
|  | 49 |  | 
|  | 50 | /* | 
|  | 51 | * new_block will increment the returned block. | 
|  | 52 | */ | 
|  | 53 | int (*new_block)(struct dm_space_map *sm, dm_block_t *b); | 
|  | 54 |  | 
|  | 55 | /* | 
|  | 56 | * The root contains all the information needed to fix the space map. | 
|  | 57 | * Generally this info is small, so squirrel it away in a disk block | 
|  | 58 | * along with other info. | 
|  | 59 | */ | 
|  | 60 | int (*root_size)(struct dm_space_map *sm, size_t *result); | 
|  | 61 | int (*copy_root)(struct dm_space_map *sm, void *copy_to_here_le, size_t len); | 
|  | 62 | }; | 
|  | 63 |  | 
|  | 64 | /*----------------------------------------------------------------*/ | 
|  | 65 |  | 
|  | 66 | static inline void dm_sm_destroy(struct dm_space_map *sm) | 
|  | 67 | { | 
|  | 68 | sm->destroy(sm); | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | static inline int dm_sm_extend(struct dm_space_map *sm, dm_block_t extra_blocks) | 
|  | 72 | { | 
|  | 73 | return sm->extend(sm, extra_blocks); | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | static inline int dm_sm_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) | 
|  | 77 | { | 
|  | 78 | return sm->get_nr_blocks(sm, count); | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | static inline int dm_sm_get_nr_free(struct dm_space_map *sm, dm_block_t *count) | 
|  | 82 | { | 
|  | 83 | return sm->get_nr_free(sm, count); | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | static inline int dm_sm_get_count(struct dm_space_map *sm, dm_block_t b, | 
|  | 87 | uint32_t *result) | 
|  | 88 | { | 
|  | 89 | return sm->get_count(sm, b, result); | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | static inline int dm_sm_count_is_more_than_one(struct dm_space_map *sm, | 
|  | 93 | dm_block_t b, int *result) | 
|  | 94 | { | 
|  | 95 | return sm->count_is_more_than_one(sm, b, result); | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | static inline int dm_sm_set_count(struct dm_space_map *sm, dm_block_t b, | 
|  | 99 | uint32_t count) | 
|  | 100 | { | 
|  | 101 | return sm->set_count(sm, b, count); | 
|  | 102 | } | 
|  | 103 |  | 
|  | 104 | static inline int dm_sm_commit(struct dm_space_map *sm) | 
|  | 105 | { | 
|  | 106 | return sm->commit(sm); | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | static inline int dm_sm_inc_block(struct dm_space_map *sm, dm_block_t b) | 
|  | 110 | { | 
|  | 111 | return sm->inc_block(sm, b); | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | static inline int dm_sm_dec_block(struct dm_space_map *sm, dm_block_t b) | 
|  | 115 | { | 
|  | 116 | return sm->dec_block(sm, b); | 
|  | 117 | } | 
|  | 118 |  | 
|  | 119 | static inline int dm_sm_new_block(struct dm_space_map *sm, dm_block_t *b) | 
|  | 120 | { | 
|  | 121 | return sm->new_block(sm, b); | 
|  | 122 | } | 
|  | 123 |  | 
|  | 124 | static inline int dm_sm_root_size(struct dm_space_map *sm, size_t *result) | 
|  | 125 | { | 
|  | 126 | return sm->root_size(sm, result); | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | static inline int dm_sm_copy_root(struct dm_space_map *sm, void *copy_to_here_le, size_t len) | 
|  | 130 | { | 
|  | 131 | return sm->copy_root(sm, copy_to_here_le, len); | 
|  | 132 | } | 
|  | 133 |  | 
|  | 134 | #endif	/* _LINUX_DM_SPACE_MAP_H */ |