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