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
46extern "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 */
61static 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 */
77static 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 */
92static 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 */
109static 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 */
124static inline uint64_t
125ext4_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 */
141static inline void
142ext4_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 */
155static 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 */
171static 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 */
185static 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 */
201static 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 */
215static 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 */
231static 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 */
245static 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 */
262static 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 */
275static 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 */
285static 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 */
294static 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 */
305static 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*/
317uint16_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