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