dm-space-map.h 4.2 KB

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