source: mainline/uspace/lib/ext4/libext4_superblock.c@ e25d78c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e25d78c was fe61181, checked in by Frantisek Princ <frantisek.princ@…>, 13 years ago

Debug messages removed

  • Property mode set to 100644
File size: 28.1 KB
RevLine 
[eb91db7]1/*
[f22d5ef0]2 * Copyright (c) 2012 Frantisek Princ
[eb91db7]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libext4
30 * @{
31 */
32
33/**
34 * @file libext4_superblock.c
[9875711]35 * @brief Ext4 superblock operations.
[eb91db7]36 */
37
[01ab41b]38#include <byteorder.h>
39#include <errno.h>
40#include <libblock.h>
41#include <malloc.h>
[3711e7e]42#include "libext4.h"
[eb91db7]43
[9fc72fb3]44/** Get number of i-nodes in the whole filesystem.
45 *
46 * @param sb superblock
47 * @return number of i-nodes
48 */
[3712434]49uint32_t ext4_superblock_get_inodes_count(ext4_superblock_t *sb)
[01ab41b]50{
[3712434]51 return uint32_t_le2host(sb->inodes_count);
[01ab41b]52}
53
[9fc72fb3]54/** Set number of i-nodes in the whole filesystem.
55 *
56 * @param sb superblock
57 * @param count number of i-nodes
58 */
[fe27eb4]59void ext4_superblock_set_inodes_count(ext4_superblock_t *sb, uint32_t count)
60{
61 sb->inodes_count = host2uint32_t_le(count);
62}
63
[9fc72fb3]64/** Get number of data blocks in the whole filesystem.
65 *
66 * @param sb superblock
67 * @return number of data blocks
68 */
[3712434]69uint64_t ext4_superblock_get_blocks_count(ext4_superblock_t *sb)
70{
71 return ((uint64_t)uint32_t_le2host(sb->blocks_count_hi) << 32) |
72 uint32_t_le2host(sb->blocks_count_lo);
73}
74
[9fc72fb3]75/** Set number of data blocks in the whole filesystem.
76 *
77 * @param sb superblock
78 * @param count number of data blocks
79 */
[fe27eb4]80void ext4_superblock_set_blocks_count(ext4_superblock_t *sb, uint64_t count)
81{
82 sb->blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
83 sb->blocks_count_hi = host2uint32_t_le(count >> 32);
84}
85
[9fc72fb3]86/** Get number of reserved data blocks in the whole filesystem.
87 *
88 * @param sb superblock
89 * @return number of reserved data blocks
90 */
[3712434]91uint64_t ext4_superblock_get_reserved_blocks_count(ext4_superblock_t *sb)
92{
93 return ((uint64_t)uint32_t_le2host(sb->reserved_blocks_count_hi) << 32) |
94 uint32_t_le2host(sb->reserved_blocks_count_lo);
95}
96
[9fc72fb3]97/** Set number of reserved data blocks in the whole filesystem.
98 *
99 * @param sb superblock
100 * @param count number of reserved data blocks
101 */
[fe27eb4]102void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *sb, uint64_t count)
103{
104 sb->reserved_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
105 sb->reserved_blocks_count_hi = host2uint32_t_le(count >> 32);
106}
107
[9fc72fb3]108/** Get number of free data blocks in the whole filesystem.
109 *
110 * @param sb superblock
111 * @return number of free data blocks
112 */
[3712434]113uint64_t ext4_superblock_get_free_blocks_count(ext4_superblock_t *sb)
114{
115 return ((uint64_t)uint32_t_le2host(sb->free_blocks_count_hi) << 32) |
116 uint32_t_le2host(sb->free_blocks_count_lo);
117}
118
[9fc72fb3]119/** Set number of free data blocks in the whole filesystem.
120 *
121 * @param sb superblock
122 * @param count number of free data blocks
123 */
[ae3d4f8]124void ext4_superblock_set_free_blocks_count(ext4_superblock_t *sb, uint64_t count)
125{
126 sb->free_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
127 sb->free_blocks_count_hi = host2uint32_t_le(count >> 32);
128}
129
[9fc72fb3]130/** Get number of free i-nodes in the whole filesystem.
131 *
132 * @param sb superblock
133 * @return number of free i-nodes
134 */
[3712434]135uint32_t ext4_superblock_get_free_inodes_count(ext4_superblock_t *sb)
136{
137 return uint32_t_le2host(sb->free_inodes_count);
138}
139
[9fc72fb3]140/** Set number of free i-nodes in the whole filesystem.
141 *
142 * @param sb superblock
143 * @param count number of free i-nodes
144 */
[fe27eb4]145void ext4_superblock_set_free_inodes_count(ext4_superblock_t *sb, uint32_t count)
146{
147 sb->free_inodes_count = host2uint32_t_le(count);
148}
149
[9fc72fb3]150/** Get index of first data block (block, where is located superblock)
151 *
152 * @param sb superblock
153 * @return index of the first data block
154 */
[3712434]155uint32_t ext4_superblock_get_first_data_block(ext4_superblock_t *sb)
[01ab41b]156{
[9c0c0e1]157 return uint32_t_le2host(sb->first_data_block);
[01ab41b]158}
159
[9fc72fb3]160/** Set index of first data block (block, where is located superblock)
161 *
162 * @param sb superblock
163 * @param first index of the first data block
164 */
[fe27eb4]165void ext4_superblock_set_first_data_block(ext4_superblock_t *sb, uint32_t first)
166{
167 sb->first_data_block = host2uint32_t_le(first);
168}
169
[9fc72fb3]170/** Get logarithmic block size (1024 << size == block_size)
171 *
172 * @param sb superblock
173 * @return logarithmic block size
174 */
[3712434]175uint32_t ext4_superblock_get_log_block_size(ext4_superblock_t *sb)
[01ab41b]176{
[9c0c0e1]177 return uint32_t_le2host(sb->log_block_size);
[01ab41b]178}
179
[9fc72fb3]180/** Set logarithmic block size (1024 << size == block_size)
181 *
182 * @param sb superblock
183 * @return logarithmic block size
184 */
[fe27eb4]185void ext4_superblock_set_log_block_size(ext4_superblock_t *sb, uint32_t log_size)
186{
187 sb->log_block_size = host2uint32_t_le(log_size);
188}
189
[9fc72fb3]190/** Get size of data block (in bytes).
191 *
192 * @param sb superblock
193 * @return size of data block
194 */
[01ab41b]195uint32_t ext4_superblock_get_block_size(ext4_superblock_t *sb)
196{
[3712434]197 return 1024 << ext4_superblock_get_log_block_size(sb);
198}
199
[9fc72fb3]200/** Set size of data block (in bytes).
201 *
202 * @param sb superblock
203 * @param size size of data block (must be power of 2, at least 1024)
204 */
[fe27eb4]205void ext4_superblock_set_block_size(ext4_superblock_t *sb, uint32_t size)
206{
207 uint32_t log = 0;
208 uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
209
210 tmp >>= 1;
211 while (tmp) {
212 log++;
213 tmp >>= 1;
214 }
215
216 ext4_superblock_set_log_block_size(sb, log);
217}
[3712434]218
[fb04cd90]219/** Get logarithmic fragment size (1024 << size)
220 *
221 * @param sb superblock
222 * @return logarithmic fragment size
223 */
224uint32_t ext4_superblock_get_log_frag_size(ext4_superblock_t *sb)
225{
226 return uint32_t_le2host(sb->log_frag_size);
227}
228
229/** Set logarithmic fragment size (1024 << size)
230 *
231 * @param sb superblock
232 * @return logarithmic fragment size
233 */
234
235void ext4_superblock_set_log_frag_size(ext4_superblock_t *sb, uint32_t frag_size)
236{
237 sb->log_frag_size = host2uint32_t_le(frag_size);
238}
239
240/** Get size of fragment (in bytes).
241 *
242 * @param sb superblock
243 * @return size of fragment
244 */
245uint32_t ext4_superblock_get_frag_size(ext4_superblock_t *sb)
246{
247 return 1024 << ext4_superblock_get_log_frag_size(sb);
248}
249
250/** Set size of fragment (in bytes).
251 *
252 * @param sb superblock
253 * @param size size of fragment (must be power of 2, at least 1024)
254 */
255void ext4_superblock_set_frag_size(ext4_superblock_t *sb, uint32_t size)
256{
257 uint32_t log = 0;
258 uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
259
260 tmp >>= 1;
261 while (tmp) {
262 log++;
263 tmp >>= 1;
264 }
265
266 ext4_superblock_set_log_frag_size(sb, log);
267}
268
[9fc72fb3]269/** Get number of data blocks per block group (except last BG)
270 *
271 * @param sb superblock
272 * @return data blocks per block group
273 */
[3712434]274uint32_t ext4_superblock_get_blocks_per_group(ext4_superblock_t *sb)
275{
276 return uint32_t_le2host(sb->blocks_per_group);
277}
278
[9fc72fb3]279/** Set number of data blocks per block group (except last BG)
280 *
281 * @param sb superblock
282 * @param blocks data blocks per block group
283 */
[fe27eb4]284void ext4_superblock_set_blocks_per_group(ext4_superblock_t *sb, uint32_t blocks)
285{
286 sb->blocks_per_group = host2uint32_t_le(blocks);
287}
288
[fb04cd90]289/** Get number of fragments per block group (except last BG)
290 *
291 * @param sb superblock
292 * @return fragments per block group
293 */
294uint32_t ext4_superblock_get_frags_per_group(ext4_superblock_t *sb)
295{
296 return uint32_t_le2host(sb->frags_per_group);
297}
298
299/** Set number of fragment per block group (except last BG)
300 *
301 * @param sb superblock
302 * @param frags fragments per block group
303 */
304void ext4_superblock_set_frags_per_group(ext4_superblock_t *sb, uint32_t frags)
305{
306 sb->frags_per_group = host2uint32_t_le(frags);
307}
308
309
[9fc72fb3]310/** Get number of i-nodes per block group (except last BG)
311 *
312 * @param sb superblock
313 * @return i-nodes per block group
314 */
[3712434]315uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb)
316{
317 return uint32_t_le2host(sb->inodes_per_group);
318}
319
[9fc72fb3]320/** Set number of i-nodes per block group (except last BG)
321 *
322 * @param sb superblock
323 * @param inodes i-nodes per block group
324 */
[fe27eb4]325void ext4_superblock_set_inodes_per_group(ext4_superblock_t *sb, uint32_t inodes)
326{
327 sb->inodes_per_group = host2uint32_t_le(inodes);
328}
329
[9fc72fb3]330/** Get time when filesystem was mounted (POSIX time).
331 *
332 * @param sb superblock
333 * @return mount time
334 */
[3712434]335uint32_t ext4_superblock_get_mount_time(ext4_superblock_t *sb)
336{
337 return uint32_t_le2host(sb->mount_time);
338}
339
[9fc72fb3]340/** Set time when filesystem was mounted (POSIX time).
341 *
342 * @param sb superblock
343 * @param time mount time
344 */
[fe27eb4]345void ext4_superblock_set_mount_time(ext4_superblock_t *sb, uint32_t time)
346{
347 sb->mount_time = host2uint32_t_le(time);
348}
349
[9fc72fb3]350/** Get time when filesystem was last accesed by write operation (POSIX time).
351 *
352 * @param sb superblock
353 * @return write time
354 */
[3712434]355uint32_t ext4_superblock_get_write_time(ext4_superblock_t *sb)
356{
357 return uint32_t_le2host(sb->write_time);
358}
359
[9fc72fb3]360/** Set time when filesystem was last accesed by write operation (POSIX time).
361 *
362 * @param sb superblock
363 * @param time write time
364 */
[fe27eb4]365void ext4_superblock_set_write_time(ext4_superblock_t *sb, uint32_t time)
366{
367 sb->write_time = host2uint32_t_le(time);
368}
369
[9fc72fb3]370/** Get number of mount from last filesystem check.
371 *
372 * @param sb superblock
373 * @return number of mounts
374 */
[3712434]375uint16_t ext4_superblock_get_mount_count(ext4_superblock_t *sb)
376{
377 return uint16_t_le2host(sb->mount_count);
378}
379
[9fc72fb3]380/** Set number of mount from last filesystem check.
381 *
382 * @param sb superblock
383 * @param count number of mounts
384 */
[fe27eb4]385void ext4_superblock_set_mount_count(ext4_superblock_t *sb, uint16_t count)
386{
387 sb->mount_count = host2uint16_t_le(count);
388}
389
[9fc72fb3]390/** Get maximum number of mount from last filesystem check.
391 *
392 * @param sb superblock
393 * @return maximum number of mounts
394 */
[3712434]395uint16_t ext4_superblock_get_max_mount_count(ext4_superblock_t *sb)
396{
397 return uint16_t_le2host(sb->max_mount_count);
398}
399
[9fc72fb3]400/** Set maximum number of mount from last filesystem check.
401 *
402 * @param sb superblock
403 * @param count maximum number of mounts
404 */
[fe27eb4]405void ext4_superblock_set_max_mount_count(ext4_superblock_t *sb, uint16_t count)
406{
407 sb->max_mount_count = host2uint16_t_le(count);
408}
409
[9fc72fb3]410/** Get superblock magic value.
411 *
412 * @param sb superblock
413 * @return magic value
414 */
[3712434]415uint16_t ext4_superblock_get_magic(ext4_superblock_t *sb)
416{
417 return uint16_t_le2host(sb->magic);
418}
419
[9fc72fb3]420/** Set superblock magic value.
421 *
422 * @param sb superblock
423 * @param magic value
424 */
425void ext4_superblock_set_magic(ext4_superblock_t *sb, uint16_t magic)
426{
427 sb->magic = host2uint16_t_le(magic);
428}
429
[2226cc3]430/** Get filesystem state.
[9fc72fb3]431 *
[2226cc3]432 * @param sb superblock
433 * @return filesystem state
[9fc72fb3]434 */
[3712434]435uint16_t ext4_superblock_get_state(ext4_superblock_t *sb)
436{
437 return uint16_t_le2host(sb->state);
438}
439
[2226cc3]440/** Set filesystem state.
[9fc72fb3]441 *
[2226cc3]442 * @param sb superblock
443 * @param state filesystem state
[9fc72fb3]444 */
[fe27eb4]445void ext4_superblock_set_state(ext4_superblock_t *sb, uint16_t state)
446{
447 sb->state = host2uint16_t_le(state);
448}
449
[2226cc3]450/** Get behavior code when errors detected.
[9fc72fb3]451 *
[2226cc3]452 * @param sb superblock
453 * @return behavior code
[9fc72fb3]454 */
[3712434]455uint16_t ext4_superblock_get_errors(ext4_superblock_t *sb)
456{
457 return uint16_t_le2host(sb->errors);
458}
459
[2226cc3]460/** Set behavior code when errors detected.
[9fc72fb3]461 *
[2226cc3]462 * @param sb superblock
463 * @param errors behavior code
[9fc72fb3]464 */
[fe27eb4]465void ext4_superblock_set_errors(ext4_superblock_t *sb, uint16_t errors)
466{
467 sb->errors = host2uint16_t_le(errors);
468}
[3712434]469
[2226cc3]470/** Get minor revision level of the filesystem.
[9fc72fb3]471 *
[2226cc3]472 * @param sb superblock
473 * @return minor revision level
[9fc72fb3]474 */
[3712434]475uint16_t ext4_superblock_get_minor_rev_level(ext4_superblock_t *sb)
476{
477 return uint16_t_le2host(sb->minor_rev_level);
478}
479
[2226cc3]480/** Set minor revision level of the filesystem.
[9fc72fb3]481 *
[2226cc3]482 * @param sb superblock
483 * @param level minor revision level
[9fc72fb3]484 */
[fe27eb4]485void ext4_superblock_set_minor_rev_level(ext4_superblock_t *sb, uint16_t level)
486{
487 sb->minor_rev_level = host2uint16_t_le(level);
488}
489
[2226cc3]490/** Get time of the last filesystem check.
[9fc72fb3]491 *
[2226cc3]492 * @param sb superblock
493 * @return time of the last check (POSIX)
[9fc72fb3]494 */
[3712434]495uint32_t ext4_superblock_get_last_check_time(ext4_superblock_t *sb)
496{
497 return uint32_t_le2host(sb->last_check_time);
498}
499
[2226cc3]500/** Set time of the last filesystem check.
[9fc72fb3]501 *
[2226cc3]502 * @param sb superblock
503 * @param time time of the last check (POSIX)
[9fc72fb3]504 */
[fe27eb4]505void ext4_superblock_set_last_check_time(ext4_superblock_t *sb, uint32_t time)
506{
507 sb->state = host2uint32_t_le(time);
508}
509
[2226cc3]510/** Get maximum time interval between two filesystem checks.
[9fc72fb3]511 *
[2226cc3]512 * @param sb superblock
513 * @return time interval between two check (POSIX)
[9fc72fb3]514 */
[3712434]515uint32_t ext4_superblock_get_check_interval(ext4_superblock_t *sb){
516 return uint32_t_le2host(sb->check_interval);
517}
518
[2226cc3]519/** Set maximum time interval between two filesystem checks.
[9fc72fb3]520 *
[2226cc3]521 * @param sb superblock
522 * @param interval time interval between two check (POSIX)
[9fc72fb3]523 */
[fe27eb4]524void ext4_superblock_set_check_interval(ext4_superblock_t *sb, uint32_t interval)
525{
526 sb->check_interval = host2uint32_t_le(interval);
527}
528
[2226cc3]529/** Get operation system identifier, on which the filesystem was created.
[9fc72fb3]530 *
[2226cc3]531 * @param sb superblock
532 * @return operation system identifier
[9fc72fb3]533 */
[3712434]534uint32_t ext4_superblock_get_creator_os(ext4_superblock_t *sb)
535{
536 return uint32_t_le2host(sb->creator_os);
[01ab41b]537}
538
[2226cc3]539/** Set operation system identifier, on which the filesystem was created.
[9fc72fb3]540 *
[2226cc3]541 * @param sb superblock
542 * @param os operation system identifier
[9fc72fb3]543 */
[fe27eb4]544void ext4_superblock_set_creator_os(ext4_superblock_t *sb, uint32_t os)
545{
546 sb->creator_os = host2uint32_t_le(os);
547}
548
[2226cc3]549/** Get revision level of the filesystem.
[9fc72fb3]550 *
[2226cc3]551 * @param sb superblock
552 * @return revision level
[9fc72fb3]553 */
[9c0c0e1]554uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *sb)
555{
556 return uint32_t_le2host(sb->rev_level);
557}
558
[2226cc3]559/** Set revision level of the filesystem.
[9fc72fb3]560 *
[2226cc3]561 * @param sb superblock
562 * @param level revision level
[9fc72fb3]563 */
[fe27eb4]564void ext4_superblock_set_rev_level(ext4_superblock_t *sb, uint32_t level)
565{
566 sb->rev_level = host2uint32_t_le(level);
567}
568
[2226cc3]569/** Get default user id for reserved blocks.
[9fc72fb3]570 *
[2226cc3]571 * @param sb superblock
572 * @return default user id for reserved blocks.
[9fc72fb3]573 */
[fe27eb4]574uint16_t ext4_superblock_get_def_resuid(ext4_superblock_t *sb)
575{
576 return uint16_t_le2host(sb->def_resuid);
577}
578
[2226cc3]579/** Set default user id for reserved blocks.
[9fc72fb3]580 *
[2226cc3]581 * @param sb superblock
582 * @param uid default user id for reserved blocks.
[9fc72fb3]583 */
[fe27eb4]584void ext4_superblock_set_def_resuid(ext4_superblock_t *sb, uint16_t uid)
585{
586 sb->def_resuid = host2uint16_t_le(uid);
587}
588
[2226cc3]589/** Get default group id for reserved blocks.
[9fc72fb3]590 *
[2226cc3]591 * @param sb superblock
592 * @return default group id for reserved blocks.
[9fc72fb3]593 */
[fe27eb4]594uint16_t ext4_superblock_get_def_resgid(ext4_superblock_t *sb)
595{
596 return uint16_t_le2host(sb->def_resgid);
597}
598
[2226cc3]599/** Set default group id for reserved blocks.
[9fc72fb3]600 *
[2226cc3]601 * @param sb superblock
602 * @param gid default group id for reserved blocks.
[9fc72fb3]603 */
[fe27eb4]604void ext4_superblock_set_def_resgid(ext4_superblock_t *sb, uint16_t gid)
605{
606 sb->def_resgid = host2uint16_t_le(gid);
607}
608
[2226cc3]609/** Get index of the first i-node, which can be used for allocation.
[9fc72fb3]610 *
[2226cc3]611 * @param sb superblock
612 * @return i-node index
[9fc72fb3]613 */
[fe27eb4]614uint32_t ext4_superblock_get_first_inode(ext4_superblock_t *sb)
615{
616 return uint32_t_le2host(sb->first_inode);
617}
618
[2226cc3]619/** Set index of the first i-node, which can be used for allocation.
[9fc72fb3]620 *
[2226cc3]621 * @param sb superblock
622 * @param first_inode i-node index
[9fc72fb3]623 */
[fe27eb4]624void ext4_superblock_set_first_inode(ext4_superblock_t *sb, uint32_t first_inode)
625{
626 sb->first_inode = host2uint32_t_le(first_inode);
627}
628
[2226cc3]629/** Get size of i-node structure.
630 *
631 * For the oldest revision return constant number.
[9fc72fb3]632 *
[2226cc3]633 * @param sb superblock
634 * @return size of i-node structure
[9fc72fb3]635 */
[3711e7e]636uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb)
637{
638 if (ext4_superblock_get_rev_level(sb) == 0) {
639 return EXT4_REV0_INODE_SIZE;
640 }
641 return uint16_t_le2host(sb->inode_size);
642}
643
[2226cc3]644/** Set size of i-node structure.
[9fc72fb3]645 *
[2226cc3]646 * @param sb superblock
647 * @param size size of i-node structure
[9fc72fb3]648 */
[fe27eb4]649void ext4_superblock_set_inode_size(ext4_superblock_t *sb, uint16_t size)
650{
651 sb->inode_size = host2uint16_t_le(size);
652}
653
[2226cc3]654/** Get index of block group, where superblock copy is located.
[9fc72fb3]655 *
[2226cc3]656 * @param sb superblock
657 * @return block group index
[9fc72fb3]658 */
[2226cc3]659uint16_t ext4_superblock_get_block_group_index(ext4_superblock_t *sb)
[3711e7e]660{
[2226cc3]661 return uint16_t_le2host(sb->block_group_index);
[3711e7e]662}
663
[2226cc3]664/** Set index of block group, where superblock copy is located.
[9fc72fb3]665 *
[2226cc3]666 * @param sb superblock
667 * @param bgid block group index
[9fc72fb3]668 */
[2226cc3]669void ext4_superblock_set_block_group_index(ext4_superblock_t *sb, uint16_t bgid)
[fe27eb4]670{
[2226cc3]671 sb->block_group_index = host2uint16_t_le(bgid);
[fe27eb4]672}
673
[2226cc3]674/** Get compatible features supported by the filesystem.
[9fc72fb3]675 *
[2226cc3]676 * @param sb superblock
677 * @return compatible features bitmap
[9fc72fb3]678 */
[9c0c0e1]679uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *sb)
680{
681 return uint32_t_le2host(sb->features_compatible);
682}
683
[2226cc3]684/** Set compatible features supported by the filesystem.
[9fc72fb3]685 *
[2226cc3]686 * @param sb superblock
687 * @param features compatible features bitmap
[9fc72fb3]688 */
[fe27eb4]689void ext4_superblock_set_features_compatible(ext4_superblock_t *sb, uint32_t features)
690{
691 sb->features_compatible = host2uint32_t_le(features);
692}
693
[2226cc3]694/** Get incompatible features supported by the filesystem.
[9fc72fb3]695 *
[2226cc3]696 * @param sb superblock
697 * @return incompatible features bitmap
[9fc72fb3]698 */
[9c0c0e1]699uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *sb)
700{
701 return uint32_t_le2host(sb->features_incompatible);
702}
703
[2226cc3]704/** Set incompatible features supported by the filesystem.
[9fc72fb3]705 *
[2226cc3]706 * @param sb superblock
707 * @param features incompatible features bitmap
[9fc72fb3]708 */
[fe27eb4]709void ext4_superblock_set_features_incompatible(ext4_superblock_t *sb, uint32_t features)
710{
711 sb->features_incompatible = host2uint32_t_le(features);
712}
713
[2226cc3]714/** Get compatible features supported by the filesystem.
[9fc72fb3]715 *
[2226cc3]716 * @param sb superblock
717 * @return read-only compatible features bitmap
[9fc72fb3]718 */
[9c0c0e1]719uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *sb)
720{
721 return uint32_t_le2host(sb->features_read_only);
722}
723
[2226cc3]724/** Set compatible features supported by the filesystem.
[9fc72fb3]725 *
[2226cc3]726 * @param sb superblock
727 * @param feature read-only compatible features bitmap
[9fc72fb3]728 */
[fe27eb4]729void ext4_superblock_set_features_read_only(ext4_superblock_t *sb, uint32_t features)
730{
731 sb->features_read_only = host2uint32_t_le(features);
732}
[01ab41b]733
[2226cc3]734/** Get UUID of the filesystem.
[9fc72fb3]735 *
[2226cc3]736 * @param sb superblock
737 * @return pointer to UUID array
[9fc72fb3]738 */
[291af81]739const uint8_t * ext4_superblock_get_uuid(ext4_superblock_t *sb)
740{
741 return sb->uuid;
742}
743
[2226cc3]744/** Set UUID of the filesystem.
[9fc72fb3]745 *
[2226cc3]746 * @param sb superblock
747 * @param uuid pointer to UUID array
[9fc72fb3]748 */
[291af81]749void ext4_superblock_set_uuid(ext4_superblock_t *sb, const uint8_t *uuid)
750{
751 memcpy(sb->uuid, uuid, sizeof(sb->uuid));
752}
753
[2226cc3]754/** Get name of the filesystem volume.
755 *
756 * @param sb superblock
757 * @return name of the volume
758 */
[291af81]759const char * ext4_superblock_get_volume_name(ext4_superblock_t *sb)
760{
761 return sb->volume_name;
762}
763
[2226cc3]764/** Set name of the filesystem volume.
[9fc72fb3]765 *
[2226cc3]766 * @param sb superblock
767 * @param name new name of the volume
[9fc72fb3]768 */
[291af81]769void ext4_superblock_set_volume_name(ext4_superblock_t *sb, const char *name)
770{
771 memcpy(sb->volume_name, name, sizeof(sb->volume_name));
772}
773
[2226cc3]774/** Get name of the directory, where this filesystem was mounted at last.
[9fc72fb3]775 *
[2226cc3]776 * @param sb superblock
777 * @return directory name
[9fc72fb3]778 */
[291af81]779const char * ext4_superblock_get_last_mounted(ext4_superblock_t *sb)
780{
781 return sb->last_mounted;
782}
783
[2226cc3]784/** Set name of the directory, where this filesystem was mounted at last.
[9fc72fb3]785 *
[2226cc3]786 * @param sb superblock
787 * @param last directory name
[9fc72fb3]788 */
[291af81]789void ext4_superblock_set_last_mounted(ext4_superblock_t *sb, const char *last)
790{
791 memcpy(sb->last_mounted, last, sizeof(sb->last_mounted));
792}
793
[2226cc3]794/** Get last orphaned i-node index.
795 *
796 * Orphans are stored in linked list.
[9fc72fb3]797 *
[2226cc3]798 * @param sb superblock
799 * @return last orphaned i-node index
[9fc72fb3]800 */
[ebcaff4]801uint32_t ext4_superblock_get_last_orphan(ext4_superblock_t *sb)
802{
803 return uint32_t_le2host(sb->last_orphan);
804}
805
[2226cc3]806/** Set last orphaned i-node index.
807 *
808 * Orphans are stored in linked list.
[9fc72fb3]809 *
[2226cc3]810 * @param sb superblock
811 * @param last_orphan last orphaned i-node index
[9fc72fb3]812 */
[ebcaff4]813void ext4_superblock_set_last_orphan(ext4_superblock_t *sb, uint32_t last_orphan)
814{
815 sb->last_orphan = host2uint32_t_le(last_orphan);
816}
817
[2226cc3]818/** Get hash seed for directory index hash function.
[9fc72fb3]819 *
[2226cc3]820 * @param sb superblock
821 * @return hash seed pointer
[9fc72fb3]822 */
[2226cc3]823const uint32_t * ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
[7bc4508]824{
825 return sb->hash_seed;
826}
827
[2226cc3]828/** Set hash seed for directory index hash function.
[9fc72fb3]829 *
[2226cc3]830 * @param sb superblock
831 * @param seed hash seed pointer
832 */
833void ext4_superblock_set_hash_seed(ext4_superblock_t *sb, const uint32_t *seed)
834{
835 memcpy(sb->hash_seed, seed, sizeof(sb->hash_seed));
836}
837
838/** Get default version of the hash algorithm version for directory index.
839 *
840 * @param sb superblock
841 * @return default hash version
[9fc72fb3]842 */
[7eb033ce]843uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *sb)
844{
845 return sb->default_hash_version;
846}
847
[2226cc3]848/** Set default version of the hash algorithm version for directory index.
[9fc72fb3]849 *
[2226cc3]850 * @param sb superblock
851 * @param version default hash version
[9fc72fb3]852 */
[7eb033ce]853void ext4_superblock_set_default_hash_version(ext4_superblock_t *sb, uint8_t version)
854{
855 sb->default_hash_version = version;
856}
857
[2226cc3]858/** Get size of block group descriptor structure.
[9fc72fb3]859 *
[2226cc3]860 * Output value is checked for minimal size.
861 *
862 * @param sb superblock
863 * @return size of block group descriptor
[9fc72fb3]864 */
[c25e39b]865uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *sb)
866{
867 uint16_t size = uint16_t_le2host(sb->desc_size);
868
[fb04cd90]869 if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
870 size = EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE;
[c25e39b]871 }
872
873 return size;
874}
875
[2226cc3]876/** Set size of block group descriptor structure.
877 *
878 * Input value is checked for minimal size.
[9fc72fb3]879 *
[2226cc3]880 * @param sb superblock
881 * @param size size of block group descriptor
[9fc72fb3]882 */
[fe27eb4]883void ext4_superblock_set_desc_size(ext4_superblock_t *sb, uint16_t size)
884{
[fb04cd90]885 if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
886 sb->desc_size = host2uint16_t_le(EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE);
[2226cc3]887 }
888
[fe27eb4]889 sb->desc_size = host2uint16_t_le(size);
890}
891
[2226cc3]892/** Get superblock flags.
[9fc72fb3]893 *
[2226cc3]894 * @param sb superblock
895 * @return flags from the superblock
[9fc72fb3]896 */
[7bc4508]897uint32_t ext4_superblock_get_flags(ext4_superblock_t *sb)
898{
899 return uint32_t_le2host(sb->flags);
900}
901
[2226cc3]902/** Set superblock flags.
[9fc72fb3]903 *
[2226cc3]904 * @param sb superblock
905 * @param flags flags for the superblock
[9fc72fb3]906 */
[fe27eb4]907void ext4_superblock_set_flags(ext4_superblock_t *sb, uint32_t flags)
908{
909 sb->flags = host2uint32_t_le(flags);
910}
911
[3712434]912/*
[c25e39b]913 * More complex superblock operations
[01ab41b]914 */
[3712434]915
[2226cc3]916/** Check if superblock has specified flag.
[9fc72fb3]917 *
[2226cc3]918 * @param sb superblock
919 * @param flag flag to be checked
920 * @return true, if superblock has the flag
[9fc72fb3]921 */
[7bc4508]922bool ext4_superblock_has_flag(ext4_superblock_t *sb, uint32_t flag)
923{
924 if (ext4_superblock_get_flags(sb) & flag) {
925 return true;
926 }
927 return false;
928}
929
[2226cc3]930/** Check if filesystem supports compatible feature.
[9fc72fb3]931 *
[2226cc3]932 * @param sb superblock
933 * @param feature feature to be checked
934 * @return true, if filesystem supports the feature
[9fc72fb3]935 */
[c25e39b]936bool ext4_superblock_has_feature_compatible(ext4_superblock_t *sb, uint32_t feature)
937{
938 if (ext4_superblock_get_features_compatible(sb) & feature) {
939 return true;
940 }
941 return false;
942}
943
[2226cc3]944/** Check if filesystem supports incompatible feature.
[9fc72fb3]945 *
[2226cc3]946 * @param sb superblock
947 * @param feature feature to be checked
948 * @return true, if filesystem supports the feature
[9fc72fb3]949 */
[c25e39b]950bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *sb, uint32_t feature)
951{
952 if (ext4_superblock_get_features_incompatible(sb) & feature) {
953 return true;
954 }
955 return false;
956}
957
[2226cc3]958/** Check if filesystem supports read-only compatible feature.
[9fc72fb3]959 *
[2226cc3]960 * @param sb superblock
961 * @param feature feature to be checked
962 * @return true, if filesystem supports the feature
[9fc72fb3]963 */
[c25e39b]964bool ext4_superblock_has_feature_read_only(ext4_superblock_t *sb, uint32_t feature)
965{
966 if (ext4_superblock_get_features_read_only(sb) & feature) {
967 return true;
968 }
969 return false;
970}
971
[2226cc3]972/** Read superblock directly from block device.
[9fc72fb3]973 *
[2226cc3]974 * @param service_id block device identifier
975 * @param sb output pointer to memory structure
976 * @return error code.
[9fc72fb3]977 */
[01ab41b]978int ext4_superblock_read_direct(service_id_t service_id,
[2226cc3]979 ext4_superblock_t **sb)
[01ab41b]980{
981 int rc;
982
[06d85e5]983 /* Allocated memory for superblock structure */
[d9bbe45]984 void *data = malloc(EXT4_SUPERBLOCK_SIZE);
[01ab41b]985 if (data == NULL) {
986 return ENOMEM;
987 }
988
[06d85e5]989 /* Read data from block device */
[01ab41b]990 rc = block_read_bytes_direct(service_id, EXT4_SUPERBLOCK_OFFSET,
991 EXT4_SUPERBLOCK_SIZE, data);
992
993 if (rc != EOK) {
994 free(data);
995 return rc;
996 }
997
[06d85e5]998 /* Set output value */
[2226cc3]999 (*sb) = data;
[01ab41b]1000
1001 return EOK;
1002}
1003
[2226cc3]1004/** Write superblock structure directly to block device.
[9fc72fb3]1005 *
[2226cc3]1006 * @param service_id block device identifier
1007 * @param sb superblock to be written
1008 * @return error code
[9fc72fb3]1009 */
[ae3d4f8]1010int ext4_superblock_write_direct(service_id_t service_id,
1011 ext4_superblock_t *sb)
1012{
1013 int rc;
[80bd676]1014 size_t phys_block_size;
[ae3d4f8]1015
[06d85e5]1016 /* Load physical block size from block device */
[ae3d4f8]1017 rc = block_get_bsize(service_id, &phys_block_size);
1018 if (rc != EOK) {
1019 return rc;
1020 }
1021
[06d85e5]1022 /* Compute address of the first block */
[d9bbe45]1023 uint64_t first_block = EXT4_SUPERBLOCK_OFFSET / phys_block_size;
[06d85e5]1024 /* Compute number of block to write */
[80bd676]1025 size_t block_count = EXT4_SUPERBLOCK_SIZE / phys_block_size;
[ae3d4f8]1026
[06d85e5]1027 /* Check alignment */
[ae3d4f8]1028 if (EXT4_SUPERBLOCK_SIZE % phys_block_size) {
1029 block_count++;
1030 }
1031
[06d85e5]1032 /* Write data */
[ae3d4f8]1033 return block_write_direct(service_id, first_block, block_count, sb);
1034
1035}
1036
[5b26747]1037/** Check sanity of the superblock.
[9fc72fb3]1038 *
[5b26747]1039 * This check is performed at mount time.
1040 * Checks are described by one-line comments in the code.
1041 *
1042 * @param sb superblock to check
1043 * @return error code
[9fc72fb3]1044 */
[01ab41b]1045int ext4_superblock_check_sanity(ext4_superblock_t *sb)
1046{
[9c0c0e1]1047 if (ext4_superblock_get_magic(sb) != EXT4_SUPERBLOCK_MAGIC) {
1048 return ENOTSUP;
1049 }
1050
[fb04cd90]1051 if (ext4_superblock_get_inodes_count(sb) == 0) {
1052 return ENOTSUP;
1053 }
1054
1055 if (ext4_superblock_get_blocks_count(sb) == 0) {
1056 return ENOTSUP;
1057 }
1058
1059 if (ext4_superblock_get_blocks_per_group(sb) == 0) {
1060 return ENOTSUP;
1061 }
1062
1063 if (ext4_superblock_get_inodes_per_group(sb) == 0) {
1064 return ENOTSUP;
1065 }
1066
1067 if (ext4_superblock_get_inode_size(sb) < 128) {
1068 return ENOTSUP;
1069 }
[fe27eb4]1070
[fb04cd90]1071 if (ext4_superblock_get_first_inode(sb) < 11) {
1072 return ENOTSUP;
1073 }
1074
1075 if (ext4_superblock_get_desc_size(sb) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
1076 return ENOTSUP;
1077 }
1078
1079 if (ext4_superblock_get_desc_size(sb) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE) {
1080 return ENOTSUP;
1081 }
[fe27eb4]1082
[01ab41b]1083 return EOK;
1084}
[eb91db7]1085
[2226cc3]1086/** Compute number of block groups in the filesystem.
[9fc72fb3]1087 *
[2226cc3]1088 * @param sb superblock
1089 * @return number of block groups
[9fc72fb3]1090 */
[b12ca16]1091uint32_t ext4_superblock_get_block_group_count(ext4_superblock_t *sb)
1092{
1093 uint64_t blocks_count = ext4_superblock_get_blocks_count(sb);
1094 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
1095
1096 uint32_t block_groups_count = blocks_count / blocks_per_group;
1097
1098 if (blocks_count % blocks_per_group) {
1099 block_groups_count++;
1100 }
1101
1102 return block_groups_count;
1103
1104}
1105
[2226cc3]1106/** Compute number of blocks in specified block group.
[9fc72fb3]1107 *
[2226cc3]1108 * @param sb superblock
1109 * @param bgid block group index
1110 * @return number of blocks
[9fc72fb3]1111 */
[b12ca16]1112uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *sb, uint32_t bgid)
1113{
1114 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
1115 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
1116 uint64_t total_blocks = ext4_superblock_get_blocks_count(sb);
1117
1118 if (bgid < block_group_count - 1) {
1119 return blocks_per_group;
1120 } else {
1121 return (total_blocks - ((block_group_count - 1) * blocks_per_group));
1122 }
1123
1124}
1125
[2226cc3]1126/** Compute number of i-nodes in specified block group.
[9fc72fb3]1127 *
[2226cc3]1128 * @param sb superblock
1129 * @param bgid block group index
1130 * @return number of i-nodes
[9fc72fb3]1131 */
[b12ca16]1132uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *sb, uint32_t bgid)
1133{
1134 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
1135 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
1136 uint32_t total_inodes = ext4_superblock_get_inodes_count(sb);
1137
1138 if (bgid < block_group_count - 1) {
1139 return inodes_per_group;
1140 } else {
1141 return (total_inodes - ((block_group_count - 1) * inodes_per_group));
1142 }
1143
1144}
1145
[eb91db7]1146/**
1147 * @}
1148 */
Note: See TracBrowser for help on using the repository browser.