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