ringfs.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright © 2014 Kosma Moczek <kosma@cloudyourcar.com>
  3. * This program is free software. It comes without any warranty, to the extent
  4. * permitted by applicable law. You can redistribute it and/or modify it under
  5. * the terms of the Do What The Fuck You Want To Public License, Version 2, as
  6. * published by Sam Hocevar. See the COPYING file for more details.
  7. */
  8. #ifndef RINGFS_H
  9. #define RINGFS_H
  10. /**
  11. * @defgroup ringfs_api RingFS API
  12. * @{
  13. */
  14. #include <stdint.h>
  15. #include <unistd.h>
  16. #include "tinystdio.h"
  17. /**
  18. * Flash memory+parition descriptor.
  19. */
  20. struct ringfs_flash_partition
  21. {
  22. int sector_size; /**< Sector size, in bytes. */
  23. int sector_offset; /**< Partition offset, in sectors. */
  24. int sector_count; /**< Partition size, in sectors. */
  25. /**
  26. * Erase a sector.
  27. * @param address Any address inside the sector.
  28. * @returns Zero on success, -1 on failure.
  29. */
  30. int (*sector_erase)(struct ringfs_flash_partition *flash, int address);
  31. /**
  32. * Program flash memory bits by toggling them from 1 to 0.
  33. * @param address Start address, in bytes.
  34. * @param data Data to program.
  35. * @param size Size of data.
  36. * @returns size on success, -1 on failure.
  37. */
  38. ssize_t (*program)(struct ringfs_flash_partition *flash, int address, const void *data, size_t size);
  39. /**
  40. * Read flash memory.
  41. * @param address Start address, in bytes.
  42. * @param data Buffer to store read data.
  43. * @param size Size of data.
  44. * @returns size on success, -1 on failure.
  45. */
  46. ssize_t (*read)(struct ringfs_flash_partition *flash, int address, void *data, size_t size);
  47. };
  48. /** @private */
  49. struct ringfs_loc {
  50. int sector;
  51. int slot;
  52. };
  53. /**
  54. * RingFS instance. Should be initialized with ringfs_init() befure use.
  55. * Structure fields should not be accessed directly.
  56. * */
  57. struct ringfs {
  58. /* Constant values, set once at ringfs_init(). */
  59. struct ringfs_flash_partition *flash;
  60. uint32_t version;
  61. int object_size;
  62. /* Cached values. */
  63. int slots_per_sector;
  64. /* Read/write pointers. Modified as needed. */
  65. struct ringfs_loc read;
  66. struct ringfs_loc write;
  67. struct ringfs_loc cursor;
  68. int cursor_position;
  69. };
  70. /**
  71. * Initialize a RingFS instance. Must be called before the instance can be used
  72. * with the other ringfs_* functions.
  73. *
  74. * @param fs RingFS instance to be initialized.
  75. * @param flash Flash memory interface. Must be implemented externally.
  76. * @param version Object version. Should be incremented whenever the object's
  77. * semantics or size change in a backwards-incompatible way.
  78. * @param object_size Size of one stored object, in bytes.
  79. * @returns Zero on success, -1 on failure.
  80. */
  81. int ringfs_init(struct ringfs *fs, struct ringfs_flash_partition *flash, uint32_t version, int object_size);
  82. /**
  83. * Format the flash memory.
  84. *
  85. * @param fs Initialized RingFS instance.
  86. * @returns Zero on success, -1 on failure.
  87. */
  88. int ringfs_format(struct ringfs *fs);
  89. /**
  90. * Scan the flash memory for a valid filesystem.
  91. *
  92. * @param fs Initialized RingFS instance.
  93. * @returns Zero on success, -1 on failure.
  94. */
  95. int ringfs_scan(struct ringfs *fs);
  96. /**
  97. * Calculate maximum RingFS capacity.
  98. *
  99. * @param fs Initialized RingFS instance.
  100. * @returns Maximum capacity on success, -1 on failure.
  101. */
  102. int ringfs_capacity(struct ringfs *fs);
  103. /**
  104. * Calculate approximate object count.
  105. * Runs in O(1).
  106. *
  107. * @param fs Initialized RingFS instance.
  108. * @returns Estimated object count on success, -1 on failure.
  109. */
  110. int ringfs_count_estimate(struct ringfs *fs);
  111. /**
  112. * Calculate exact object count.
  113. * Runs in O(n).
  114. *
  115. * @param fs Initialized RingFS instance.
  116. * @returns Exact object count on success, -1 on failure.
  117. */
  118. int ringfs_count_exact(struct ringfs *fs);
  119. /**
  120. * Get current cursor position.
  121. *
  122. * @param fs Initialized RingFS instance.
  123. * @returns Current cursor position, -1 on failure.
  124. */
  125. int ringfs_cursor_position(struct ringfs *fs);
  126. /**
  127. * Append an object at the end of the ring. Deletes oldest objects as needed.
  128. *
  129. * @param fs Initialized RingFS instance.
  130. * @param object Object to be stored.
  131. * @returns Zero on success, -1 on failure.
  132. */
  133. int ringfs_append(struct ringfs *fs, const void *object);
  134. /**
  135. * Fetch next object from the ring, oldest-first. Advances read cursor.
  136. *
  137. * @param fs Initialized RingFS instance.
  138. * @param object Buffer to store retrieved object.
  139. * @returns Zero on success, -1 on failure.
  140. */
  141. int ringfs_fetch(struct ringfs *fs, void *object);
  142. /**
  143. * Discard all fetched objects up to the read cursor.
  144. *
  145. * @param fs Initialized RingFS instance.
  146. * @returns Zero on success, -1 on failure.
  147. */
  148. int ringfs_discard(struct ringfs *fs);
  149. /**
  150. * Rewind the read cursor back to the oldest object.
  151. *
  152. * @param fs Initialized RingFS instance.
  153. * @returns Zero on success, -1 on failure.
  154. */
  155. int ringfs_rewind(struct ringfs *fs);
  156. /**
  157. * @}
  158. */
  159. #endif
  160. /* vim: set ts=4 sw=4 et: */