dm-space-map.h 4.6 KB

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