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_super.c |
39 | * @brief Superblock operations. |
40 | */ |
41 | |
42 | #ifndef EXT4_SUPER_H_ |
43 | #define EXT4_SUPER_H_ |
44 | |
45 | #ifdef __cplusplus |
46 | extern "C" { |
47 | #endif |
48 | |
49 | #include <ext4_config.h> |
50 | #include <ext4_types.h> |
51 | #include <ext4_misc.h> |
52 | |
53 | /**@brief Blocks count get stored in superblock. |
54 | * @param s superblock descriptor |
55 | * @return count of blocks*/ |
56 | static inline uint64_t ext4_sb_get_blocks_cnt(struct ext4_sblock *s) |
57 | { |
58 | return ((uint64_t)to_le32(s->blocks_count_hi) << 32) | |
59 | to_le32(s->blocks_count_lo); |
60 | } |
61 | |
62 | /**@brief Blocks count set in superblock. |
63 | * @param s superblock descriptor |
64 | * @param cnt count of blocks*/ |
65 | static inline void ext4_sb_set_blocks_cnt(struct ext4_sblock *s, uint64_t cnt) |
66 | { |
67 | s->blocks_count_lo = to_le32((cnt << 32) >> 32); |
68 | s->blocks_count_hi = to_le32(cnt >> 32); |
69 | } |
70 | |
71 | /**@brief Free blocks count get stored in superblock. |
72 | * @param s superblock descriptor |
73 | * @return free blocks*/ |
74 | static inline uint64_t ext4_sb_get_free_blocks_cnt(struct ext4_sblock *s) |
75 | { |
76 | return ((uint64_t)to_le32(s->free_blocks_count_hi) << 32) | |
77 | to_le32(s->free_blocks_count_lo); |
78 | } |
79 | |
80 | /**@brief Free blocks count set. |
81 | * @param s superblock descriptor |
82 | * @param cnt new value of free blocks*/ |
83 | static inline void ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s, |
84 | uint64_t cnt) |
85 | { |
86 | s->free_blocks_count_lo = to_le32((cnt << 32) >> 32); |
87 | s->free_blocks_count_hi = to_le32(cnt >> 32); |
88 | } |
89 | |
90 | /**@brief Block size get from superblock. |
91 | * @param s superblock descriptor |
92 | * @return block size in bytes*/ |
93 | static inline uint32_t ext4_sb_get_block_size(struct ext4_sblock *s) |
94 | { |
95 | return 1024 << to_le32(s->log_block_size); |
96 | } |
97 | |
98 | /**@brief Block group descriptor size. |
99 | * @param s superblock descriptor |
100 | * @return block group descriptor size in bytes*/ |
101 | static inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s) |
102 | { |
103 | uint16_t size = to_le16(s->desc_size); |
104 | |
105 | return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE |
106 | ? EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE |
107 | : size; |
108 | } |
109 | |
110 | /*************************Flags and features*********************************/ |
111 | |
112 | /**@brief Support check of flag. |
113 | * @param s superblock descriptor |
114 | * @param v flag to check |
115 | * @return true if flag is supported*/ |
116 | static inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v) |
117 | { |
118 | return to_le32(s->flags) & v; |
119 | } |
120 | |
121 | /**@brief Support check of feature compatible. |
122 | * @param s superblock descriptor |
123 | * @param v feature to check |
124 | * @return true if feature is supported*/ |
125 | static inline bool ext4_sb_feature_com(struct ext4_sblock *s, uint32_t v) |
126 | { |
127 | return to_le32(s->features_compatible) & v; |
128 | } |
129 | |
130 | /**@brief Support check of feature incompatible. |
131 | * @param s superblock descriptor |
132 | * @param v feature to check |
133 | * @return true if feature is supported*/ |
134 | static inline bool ext4_sb_feature_incom(struct ext4_sblock *s, uint32_t v) |
135 | { |
136 | return to_le32(s->features_incompatible) & v; |
137 | } |
138 | |
139 | /**@brief Support check of read only flag. |
140 | * @param s superblock descriptor |
141 | * @param v flag to check |
142 | * @return true if flag is supported*/ |
143 | static inline bool ext4_sb_feature_ro_com(struct ext4_sblock *s, uint32_t v) |
144 | { |
145 | return to_le32(s->features_read_only) & v; |
146 | } |
147 | |
148 | /**@brief Block group to flex group. |
149 | * @param s superblock descriptor |
150 | * @param block_group block group |
151 | * @return flex group id*/ |
152 | static inline uint32_t ext4_sb_bg_to_flex(struct ext4_sblock *s, |
153 | uint32_t block_group) |
154 | { |
155 | return block_group >> to_le32(s->log_groups_per_flex); |
156 | } |
157 | |
158 | /**@brief Flex block group size. |
159 | * @param s superblock descriptor |
160 | * @return flex bg size*/ |
161 | static inline uint32_t ext4_sb_flex_bg_size(struct ext4_sblock *s) |
162 | { |
163 | return 1 << to_le32(s->log_groups_per_flex); |
164 | } |
165 | |
166 | /**@brief Return first meta block group id. |
167 | * @param s superblock descriptor |
168 | * @return first meta_bg id */ |
169 | static inline uint32_t ext4_sb_first_meta_bg(struct ext4_sblock *s) |
170 | { |
171 | return to_le32(s->first_meta_bg); |
172 | } |
173 | |
174 | /**************************More complex functions****************************/ |
175 | |
176 | /**@brief Returns a block group count. |
177 | * @param s superblock descriptor |
178 | * @return count of block groups*/ |
179 | uint32_t ext4_block_group_cnt(struct ext4_sblock *s); |
180 | |
181 | /**@brief Returns block count in block group |
182 | * (last block group may have less blocks) |
183 | * @param s superblock descriptor |
184 | * @param bgid block group id |
185 | * @return blocks count*/ |
186 | uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid); |
187 | |
188 | /**@brief Returns inodes count in block group |
189 | * (last block group may have less inodes) |
190 | * @param s superblock descriptor |
191 | * @param bgid block group id |
192 | * @return inodes count*/ |
193 | uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid); |
194 | |
195 | /***************************Read/write/check superblock**********************/ |
196 | |
197 | /**@brief Superblock write. |
198 | * @param bdev block device descriptor. |
199 | * @param s superblock descriptor |
200 | * @return Standard error code */ |
201 | int ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s); |
202 | |
203 | /**@brief Superblock read. |
204 | * @param bdev block device descriptor. |
205 | * @param s superblock descriptor |
206 | * @return Standard error code */ |
207 | int ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s); |
208 | |
209 | /**@brief Superblock simple validation. |
210 | * @param s superblock descriptor |
211 | * @return true if OK*/ |
212 | bool ext4_sb_check(struct ext4_sblock *s); |
213 | |
214 | /**@brief Superblock presence in block group. |
215 | * @param s superblock descriptor |
216 | * @param block_group block group id |
217 | * @return true if block group has superblock*/ |
218 | bool ext4_sb_is_super_in_bg(struct ext4_sblock *s, uint32_t block_group); |
219 | |
220 | /**@brief TODO:*/ |
221 | bool ext4_sb_sparse(uint32_t group); |
222 | |
223 | /**@brief TODO:*/ |
224 | uint32_t ext4_bg_num_gdb(struct ext4_sblock *s, uint32_t group); |
225 | |
226 | /**@brief TODO:*/ |
227 | uint32_t ext4_num_base_meta_clusters(struct ext4_sblock *s, |
228 | uint32_t block_group); |
229 | |
230 | #ifdef __cplusplus |
231 | } |
232 | #endif |
233 | |
234 | #endif /* EXT4_SUPER_H_ */ |
235 | |
236 | /** |
237 | * @} |
238 | */ |
239 | |