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 | |
34 | /** @addtogroup lwext4 |
35 | * @{ |
36 | */ |
37 | /** |
38 | * @file ext4_block_group.h |
39 | * @brief Block group function set. |
40 | */ |
41 | |
42 | #ifndef EXT4_BLOCK_GROUP_H_ |
43 | #define EXT4_BLOCK_GROUP_H_ |
44 | |
45 | #ifdef __cplusplus |
46 | extern "C" { |
47 | #endif |
48 | |
49 | #include <ext4_config.h> |
50 | #include <ext4_types.h> |
51 | #include <ext4_super.h> |
52 | |
53 | #include <stdint.h> |
54 | #include <stdbool.h> |
55 | |
56 | /**@brief Get address of block with data block bitmap. |
57 | * @param bg pointer to block group |
58 | * @param s pointer to superblock |
59 | * @return Address of block with block bitmap |
60 | */ |
61 | static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg, |
62 | struct ext4_sblock *s) |
63 | { |
64 | uint64_t v = to_le32(bg->block_bitmap_lo); |
65 | |
66 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
67 | v |= (uint64_t)to_le32(bg->block_bitmap_hi) << 32; |
68 | |
69 | return v; |
70 | } |
71 | |
72 | /**@brief Set address of block with data block bitmap. |
73 | * @param bg pointer to block group |
74 | * @param s pointer to superblock |
75 | * @param blk block to set |
76 | */ |
77 | static inline void ext4_bg_set_block_bitmap(struct ext4_bgroup *bg, |
78 | struct ext4_sblock *s, uint64_t blk) |
79 | { |
80 | |
81 | bg->block_bitmap_lo = to_le32((uint32_t)blk); |
82 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
83 | bg->block_bitmap_hi = to_le32(blk >> 32); |
84 | |
85 | } |
86 | |
87 | /**@brief Get address of block with i-node bitmap. |
88 | * @param bg Pointer to block group |
89 | * @param s Pointer to superblock |
90 | * @return Address of block with i-node bitmap |
91 | */ |
92 | static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg, |
93 | struct ext4_sblock *s) |
94 | { |
95 | |
96 | uint64_t v = to_le32(bg->inode_bitmap_lo); |
97 | |
98 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
99 | v |= (uint64_t)to_le32(bg->inode_bitmap_hi) << 32; |
100 | |
101 | return v; |
102 | } |
103 | |
104 | /**@brief Set address of block with i-node bitmap. |
105 | * @param bg Pointer to block group |
106 | * @param s Pointer to superblock |
107 | * @param blk block to set |
108 | */ |
109 | static inline void ext4_bg_set_inode_bitmap(struct ext4_bgroup *bg, |
110 | struct ext4_sblock *s, uint64_t blk) |
111 | { |
112 | bg->inode_bitmap_lo = to_le32((uint32_t)blk); |
113 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
114 | bg->inode_bitmap_hi = to_le32(blk >> 32); |
115 | |
116 | } |
117 | |
118 | |
119 | /**@brief Get address of the first block of the i-node table. |
120 | * @param bg Pointer to block group |
121 | * @param s Pointer to superblock |
122 | * @return Address of first block of i-node table |
123 | */ |
124 | static inline uint64_t |
125 | ext4_bg_get_inode_table_first_block(struct ext4_bgroup *bg, |
126 | struct ext4_sblock *s) |
127 | { |
128 | uint64_t v = to_le32(bg->inode_table_first_block_lo); |
129 | |
130 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
131 | v |= (uint64_t)to_le32(bg->inode_table_first_block_hi) << 32; |
132 | |
133 | return v; |
134 | } |
135 | |
136 | /**@brief Set address of the first block of the i-node table. |
137 | * @param bg Pointer to block group |
138 | * @param s Pointer to superblock |
139 | * @param blk block to set |
140 | */ |
141 | static inline void |
142 | ext4_bg_set_inode_table_first_block(struct ext4_bgroup *bg, |
143 | struct ext4_sblock *s, uint64_t blk) |
144 | { |
145 | bg->inode_table_first_block_lo = to_le32((uint32_t)blk); |
146 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
147 | bg->inode_table_first_block_hi = to_le32(blk >> 32); |
148 | } |
149 | |
150 | /**@brief Get number of free blocks in block group. |
151 | * @param bg Pointer to block group |
152 | * @param s Pointer to superblock |
153 | * @return Number of free blocks in block group |
154 | */ |
155 | static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg, |
156 | struct ext4_sblock *s) |
157 | { |
158 | uint32_t v = to_le16(bg->free_blocks_count_lo); |
159 | |
160 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
161 | v |= (uint32_t)to_le16(bg->free_blocks_count_hi) << 16; |
162 | |
163 | return v; |
164 | } |
165 | |
166 | /**@brief Set number of free blocks in block group. |
167 | * @param bg Pointer to block group |
168 | * @param s Pointer to superblock |
169 | * @param cnt Number of free blocks in block group |
170 | */ |
171 | static inline void ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg, |
172 | struct ext4_sblock *s, |
173 | uint32_t cnt) |
174 | { |
175 | bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16); |
176 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
177 | bg->free_blocks_count_hi = to_le16(cnt >> 16); |
178 | } |
179 | |
180 | /**@brief Get number of free i-nodes in block group. |
181 | * @param bg Pointer to block group |
182 | * @param s Pointer to superblock |
183 | * @return Number of free i-nodes in block group |
184 | */ |
185 | static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg, |
186 | struct ext4_sblock *s) |
187 | { |
188 | uint32_t v = to_le16(bg->free_inodes_count_lo); |
189 | |
190 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
191 | v |= (uint32_t)to_le16(bg->free_inodes_count_hi) << 16; |
192 | |
193 | return v; |
194 | } |
195 | |
196 | /**@brief Set number of free i-nodes in block group. |
197 | * @param bg Pointer to block group |
198 | * @param s Pointer to superblock |
199 | * @param cnt Number of free i-nodes in block group |
200 | */ |
201 | static inline void ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg, |
202 | struct ext4_sblock *s, |
203 | uint32_t cnt) |
204 | { |
205 | bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16); |
206 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
207 | bg->free_inodes_count_hi = to_le16(cnt >> 16); |
208 | } |
209 | |
210 | /**@brief Get number of used directories in block group. |
211 | * @param bg Pointer to block group |
212 | * @param s Pointer to superblock |
213 | * @return Number of used directories in block group |
214 | */ |
215 | static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg, |
216 | struct ext4_sblock *s) |
217 | { |
218 | uint32_t v = to_le16(bg->used_dirs_count_lo); |
219 | |
220 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
221 | v |= (uint32_t)to_le16(bg->used_dirs_count_hi) << 16; |
222 | |
223 | return v; |
224 | } |
225 | |
226 | /**@brief Set number of used directories in block group. |
227 | * @param bg Pointer to block group |
228 | * @param s Pointer to superblock |
229 | * @param cnt Number of used directories in block group |
230 | */ |
231 | static inline void ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg, |
232 | struct ext4_sblock *s, |
233 | uint32_t cnt) |
234 | { |
235 | bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16); |
236 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
237 | bg->used_dirs_count_hi = to_le16(cnt >> 16); |
238 | } |
239 | |
240 | /**@brief Get number of unused i-nodes. |
241 | * @param bg Pointer to block group |
242 | * @param s Pointer to superblock |
243 | * @return Number of unused i-nodes |
244 | */ |
245 | static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg, |
246 | struct ext4_sblock *s) |
247 | { |
248 | |
249 | uint32_t v = to_le16(bg->itable_unused_lo); |
250 | |
251 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
252 | v |= (uint32_t)to_le16(bg->itable_unused_hi) << 16; |
253 | |
254 | return v; |
255 | } |
256 | |
257 | /**@brief Set number of unused i-nodes. |
258 | * @param bg Pointer to block group |
259 | * @param s Pointer to superblock |
260 | * @param cnt Number of unused i-nodes |
261 | */ |
262 | static inline void ext4_bg_set_itable_unused(struct ext4_bgroup *bg, |
263 | struct ext4_sblock *s, |
264 | uint32_t cnt) |
265 | { |
266 | bg->itable_unused_lo = to_le16((cnt << 16) >> 16); |
267 | if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) |
268 | bg->itable_unused_hi = to_le16(cnt >> 16); |
269 | } |
270 | |
271 | /**@brief Set checksum of block group. |
272 | * @param bg Pointer to block group |
273 | * @param crc Cheksum of block group |
274 | */ |
275 | static inline void ext4_bg_set_checksum(struct ext4_bgroup *bg, uint16_t crc) |
276 | { |
277 | bg->checksum = to_le16(crc); |
278 | } |
279 | |
280 | /**@brief Check if block group has a flag. |
281 | * @param bg Pointer to block group |
282 | * @param f Flag to be checked |
283 | * @return True if flag is set to 1 |
284 | */ |
285 | static inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f) |
286 | { |
287 | return to_le16(bg->flags) & f; |
288 | } |
289 | |
290 | /**@brief Set flag of block group. |
291 | * @param bg Pointer to block group |
292 | * @param f Flag to be set |
293 | */ |
294 | static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f) |
295 | { |
296 | uint16_t flags = to_le16(bg->flags); |
297 | flags |= f; |
298 | bg->flags = to_le16(flags); |
299 | } |
300 | |
301 | /**@brief Clear flag of block group. |
302 | * @param bg Pointer to block group |
303 | * @param f Flag to be cleared |
304 | */ |
305 | static inline void ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f) |
306 | { |
307 | uint16_t flags = to_le16(bg->flags); |
308 | flags &= ~f; |
309 | bg->flags = to_le16(flags); |
310 | } |
311 | |
312 | /**@brief Calculate CRC16 of the block group. |
313 | * @param crc Init value |
314 | * @param buffer Input buffer |
315 | * @param len Sizeof input buffer |
316 | * @return Computed CRC16*/ |
317 | uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len); |
318 | |
319 | #ifdef __cplusplus |
320 | } |
321 | #endif |
322 | |
323 | #endif /* EXT4_BLOCK_GROUP_H_ */ |
324 | |
325 | /** |
326 | * @} |
327 | */ |
328 | |