source: mainline/uspace/lib/ext4/libext4_superblock.c@ 49505fe

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 49505fe was 38542dc, checked in by Martin Decky <martin@…>, 13 years ago

ext4 code review and coding style cleanup

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