ext4_extent.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
  3. *
  4. *
  5. * HelenOS:
  6. * Copyright (c) 2012 Martin Sucha
  7. * Copyright (c) 2012 Frantisek Princ
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * - The name of the author may not be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  24. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. /** @addtogroup lwext4
  34. * @{
  35. */
  36. /**
  37. * @file ext4_extent.h
  38. * @brief More complex filesystem functions.
  39. */
  40. #ifndef EXT4_EXTENT_H_
  41. #define EXT4_EXTENT_H_
  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif
  45. #include "ext4_config.h"
  46. #include "ext4_types.h"
  47. #include "ext4_inode.h"
  48. /*
  49. * Array of ext4_ext_path contains path to some extent.
  50. * Creation/lookup routines use it for traversal/splitting/etc.
  51. * Truncate uses it to simulate recursive walking.
  52. */
  53. struct ext4_extent_path {
  54. ext4_fsblk_t p_block;
  55. struct ext4_block block;
  56. int32_t depth;
  57. int32_t maxdepth;
  58. struct ext4_extent_header *header;
  59. struct ext4_extent_index *index;
  60. struct ext4_extent *extent;
  61. };
  62. /**@brief Get logical number of the block covered by extent.
  63. * @param extent Extent to load number from
  64. * @return Logical number of the first block covered by extent */
  65. static inline uint32_t ext4_extent_get_first_block(struct ext4_extent *extent)
  66. {
  67. return to_le32(extent->first_block);
  68. }
  69. /**@brief Set logical number of the first block covered by extent.
  70. * @param extent Extent to set number to
  71. * @param iblock Logical number of the first block covered by extent */
  72. static inline void ext4_extent_set_first_block(struct ext4_extent *extent,
  73. uint32_t iblock)
  74. {
  75. extent->first_block = to_le32(iblock);
  76. }
  77. /**@brief Get number of blocks covered by extent.
  78. * @param extent Extent to load count from
  79. * @return Number of blocks covered by extent */
  80. static inline uint16_t ext4_extent_get_block_count(struct ext4_extent *extent)
  81. {
  82. if (EXT4_EXT_IS_UNWRITTEN(extent))
  83. return EXT4_EXT_GET_LEN_UNWRITTEN(extent);
  84. else
  85. return EXT4_EXT_GET_LEN(extent);
  86. }
  87. /**@brief Set number of blocks covered by extent.
  88. * @param extent Extent to load count from
  89. * @param count Number of blocks covered by extent
  90. * @param unwritten Whether the extent is unwritten or not */
  91. static inline void ext4_extent_set_block_count(struct ext4_extent *extent,
  92. uint16_t count, bool unwritten)
  93. {
  94. EXT4_EXT_SET_LEN(extent, count);
  95. if (unwritten)
  96. EXT4_EXT_SET_UNWRITTEN(extent);
  97. }
  98. /**@brief Get physical number of the first block covered by extent.
  99. * @param extent Extent to load number
  100. * @return Physical number of the first block covered by extent */
  101. static inline uint64_t ext4_extent_get_start(struct ext4_extent *extent)
  102. {
  103. return ((uint64_t)to_le16(extent->start_hi)) << 32 |
  104. ((uint64_t)to_le32(extent->start_lo));
  105. }
  106. /**@brief Set physical number of the first block covered by extent.
  107. * @param extent Extent to load number
  108. * @param fblock Physical number of the first block covered by extent */
  109. static inline void ext4_extent_set_start(struct ext4_extent *extent, uint64_t fblock)
  110. {
  111. extent->start_lo = to_le32((fblock << 32) >> 32);
  112. extent->start_hi = to_le16((uint16_t)(fblock >> 32));
  113. }
  114. /**@brief Get logical number of the block covered by extent index.
  115. * @param index Extent index to load number from
  116. * @return Logical number of the first block covered by extent index */
  117. static inline uint32_t
  118. ext4_extent_index_get_first_block(struct ext4_extent_index *index)
  119. {
  120. return to_le32(index->first_block);
  121. }
  122. /**@brief Set logical number of the block covered by extent index.
  123. * @param index Extent index to set number to
  124. * @param iblock Logical number of the first block covered by extent index */
  125. static inline void
  126. ext4_extent_index_set_first_block(struct ext4_extent_index *index,
  127. uint32_t iblock)
  128. {
  129. index->first_block = to_le32(iblock);
  130. }
  131. /**@brief Get physical number of block where the child node is located.
  132. * @param index Extent index to load number from
  133. * @return Physical number of the block with child node */
  134. static inline uint64_t
  135. ext4_extent_index_get_leaf(struct ext4_extent_index *index)
  136. {
  137. return ((uint64_t)to_le16(index->leaf_hi)) << 32 |
  138. ((uint64_t)to_le32(index->leaf_lo));
  139. }
  140. /**@brief Set physical number of block where the child node is located.
  141. * @param index Extent index to set number to
  142. * @param fblock Ohysical number of the block with child node */
  143. static inline void ext4_extent_index_set_leaf(struct ext4_extent_index *index,
  144. uint64_t fblock)
  145. {
  146. index->leaf_lo = to_le32((fblock << 32) >> 32);
  147. index->leaf_hi = to_le16((uint16_t)(fblock >> 32));
  148. }
  149. /**@brief Get magic value from extent header.
  150. * @param header Extent header to load value from
  151. * @return Magic value of extent header */
  152. static inline uint16_t
  153. ext4_extent_header_get_magic(struct ext4_extent_header *header)
  154. {
  155. return to_le16(header->magic);
  156. }
  157. /**@brief Set magic value to extent header.
  158. * @param header Extent header to set value to
  159. * @param magic Magic value of extent header */
  160. static inline void ext4_extent_header_set_magic(struct ext4_extent_header *header,
  161. uint16_t magic)
  162. {
  163. header->magic = to_le16(magic);
  164. }
  165. /**@brief Get number of entries from extent header
  166. * @param header Extent header to get value from
  167. * @return Number of entries covered by extent header */
  168. static inline uint16_t
  169. ext4_extent_header_get_entries_count(struct ext4_extent_header *header)
  170. {
  171. return to_le16(header->entries_count);
  172. }
  173. /**@brief Set number of entries to extent header
  174. * @param header Extent header to set value to
  175. * @param count Number of entries covered by extent header */
  176. static inline void
  177. ext4_extent_header_set_entries_count(struct ext4_extent_header *header,
  178. uint16_t count)
  179. {
  180. header->entries_count = to_le16(count);
  181. }
  182. /**@brief Get maximum number of entries from extent header
  183. * @param header Extent header to get value from
  184. * @return Maximum number of entries covered by extent header */
  185. static inline uint16_t
  186. ext4_extent_header_get_max_entries_count(struct ext4_extent_header *header)
  187. {
  188. return to_le16(header->max_entries_count);
  189. }
  190. /**@brief Set maximum number of entries to extent header
  191. * @param header Extent header to set value to
  192. * @param max_count Maximum number of entries covered by extent header */
  193. static inline void
  194. ext4_extent_header_set_max_entries_count(struct ext4_extent_header *header,
  195. uint16_t max_count)
  196. {
  197. header->max_entries_count = to_le16(max_count);
  198. }
  199. /**@brief Get depth of extent subtree.
  200. * @param header Extent header to get value from
  201. * @return Depth of extent subtree */
  202. static inline uint16_t
  203. ext4_extent_header_get_depth(struct ext4_extent_header *header)
  204. {
  205. return to_le16(header->depth);
  206. }
  207. /**@brief Set depth of extent subtree.
  208. * @param header Extent header to set value to
  209. * @param depth Depth of extent subtree */
  210. static inline void
  211. ext4_extent_header_set_depth(struct ext4_extent_header *header, uint16_t depth)
  212. {
  213. header->depth = to_le16(depth);
  214. }
  215. /**@brief Get generation from extent header
  216. * @param header Extent header to get value from
  217. * @return Generation */
  218. static inline uint32_t
  219. ext4_extent_header_get_generation(struct ext4_extent_header *header)
  220. {
  221. return to_le32(header->generation);
  222. }
  223. /**@brief Set generation to extent header
  224. * @param header Extent header to set value to
  225. * @param generation Generation */
  226. static inline void
  227. ext4_extent_header_set_generation(struct ext4_extent_header *header,
  228. uint32_t generation)
  229. {
  230. header->generation = to_le32(generation);
  231. }
  232. /******************************************************************************/
  233. /**TODO: */
  234. static inline void ext4_extent_tree_init(struct ext4_inode_ref *inode_ref)
  235. {
  236. /* Initialize extent root header */
  237. struct ext4_extent_header *header =
  238. ext4_inode_get_extent_header(inode_ref->inode);
  239. ext4_extent_header_set_depth(header, 0);
  240. ext4_extent_header_set_entries_count(header, 0);
  241. ext4_extent_header_set_generation(header, 0);
  242. ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC);
  243. uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -
  244. sizeof(struct ext4_extent_header)) /
  245. sizeof(struct ext4_extent);
  246. ext4_extent_header_set_max_entries_count(header, max_entries);
  247. inode_ref->dirty = true;
  248. }
  249. /**TODO: */
  250. int ext4_extent_get_blocks(struct ext4_inode_ref *inode_ref, ext4_lblk_t iblock,
  251. uint32_t max_blocks, ext4_fsblk_t *result, bool create,
  252. uint32_t *blocks_count);
  253. /**@brief Release all data blocks starting from specified logical block.
  254. * @param inode_ref I-node to release blocks from
  255. * @param iblock_from First logical block to release
  256. * @return Error code */
  257. int ext4_extent_remove_space(struct ext4_inode_ref *inode_ref, ext4_lblk_t from,
  258. ext4_lblk_t to);
  259. #ifdef __cplusplus
  260. }
  261. #endif
  262. #endif /* EXT4_EXTENT_H_ */
  263. /**
  264. * @}
  265. */