source: mainline/uspace/lib/ext4/libext4_superblock.c@ 2add9ec

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

Superblock comments

  • Property mode set to 100644
File size: 25.7 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
[9fc72fb3]219/** Get number of data blocks per block group (except last BG)
220 *
221 * @param sb superblock
222 * @return data blocks per block group
223 */
[3712434]224uint32_t ext4_superblock_get_blocks_per_group(ext4_superblock_t *sb)
225{
226 return uint32_t_le2host(sb->blocks_per_group);
227}
228
[9fc72fb3]229/** Set number of data blocks per block group (except last BG)
230 *
231 * @param sb superblock
232 * @param blocks data blocks per block group
233 */
[fe27eb4]234void ext4_superblock_set_blocks_per_group(ext4_superblock_t *sb, uint32_t blocks)
235{
236 sb->blocks_per_group = host2uint32_t_le(blocks);
237}
238
[9fc72fb3]239/** Get number of i-nodes per block group (except last BG)
240 *
241 * @param sb superblock
242 * @return i-nodes per block group
243 */
[3712434]244uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb)
245{
246 return uint32_t_le2host(sb->inodes_per_group);
247}
248
[9fc72fb3]249/** Set number of i-nodes per block group (except last BG)
250 *
251 * @param sb superblock
252 * @param inodes i-nodes per block group
253 */
[fe27eb4]254void ext4_superblock_set_inodes_per_group(ext4_superblock_t *sb, uint32_t inodes)
255{
256 sb->inodes_per_group = host2uint32_t_le(inodes);
257}
258
[9fc72fb3]259/** Get time when filesystem was mounted (POSIX time).
260 *
261 * @param sb superblock
262 * @return mount time
263 */
[3712434]264uint32_t ext4_superblock_get_mount_time(ext4_superblock_t *sb)
265{
266 return uint32_t_le2host(sb->mount_time);
267}
268
[9fc72fb3]269/** Set time when filesystem was mounted (POSIX time).
270 *
271 * @param sb superblock
272 * @param time mount time
273 */
[fe27eb4]274void ext4_superblock_set_mount_time(ext4_superblock_t *sb, uint32_t time)
275{
276 sb->mount_time = host2uint32_t_le(time);
277}
278
[9fc72fb3]279/** Get time when filesystem was last accesed by write operation (POSIX time).
280 *
281 * @param sb superblock
282 * @return write time
283 */
[3712434]284uint32_t ext4_superblock_get_write_time(ext4_superblock_t *sb)
285{
286 return uint32_t_le2host(sb->write_time);
287}
288
[9fc72fb3]289/** Set time when filesystem was last accesed by write operation (POSIX time).
290 *
291 * @param sb superblock
292 * @param time write time
293 */
[fe27eb4]294void ext4_superblock_set_write_time(ext4_superblock_t *sb, uint32_t time)
295{
296 sb->write_time = host2uint32_t_le(time);
297}
298
[9fc72fb3]299/** Get number of mount from last filesystem check.
300 *
301 * @param sb superblock
302 * @return number of mounts
303 */
[3712434]304uint16_t ext4_superblock_get_mount_count(ext4_superblock_t *sb)
305{
306 return uint16_t_le2host(sb->mount_count);
307}
308
[9fc72fb3]309/** Set number of mount from last filesystem check.
310 *
311 * @param sb superblock
312 * @param count number of mounts
313 */
[fe27eb4]314void ext4_superblock_set_mount_count(ext4_superblock_t *sb, uint16_t count)
315{
316 sb->mount_count = host2uint16_t_le(count);
317}
318
[9fc72fb3]319/** Get maximum number of mount from last filesystem check.
320 *
321 * @param sb superblock
322 * @return maximum number of mounts
323 */
[3712434]324uint16_t ext4_superblock_get_max_mount_count(ext4_superblock_t *sb)
325{
326 return uint16_t_le2host(sb->max_mount_count);
327}
328
[9fc72fb3]329/** Set maximum number of mount from last filesystem check.
330 *
331 * @param sb superblock
332 * @param count maximum number of mounts
333 */
[fe27eb4]334void ext4_superblock_set_max_mount_count(ext4_superblock_t *sb, uint16_t count)
335{
336 sb->max_mount_count = host2uint16_t_le(count);
337}
338
[9fc72fb3]339/** Get superblock magic value.
340 *
341 * @param sb superblock
342 * @return magic value
343 */
[3712434]344uint16_t ext4_superblock_get_magic(ext4_superblock_t *sb)
345{
346 return uint16_t_le2host(sb->magic);
347}
348
[9fc72fb3]349/** Set superblock magic value.
350 *
351 * @param sb superblock
352 * @param magic value
353 */
354void ext4_superblock_set_magic(ext4_superblock_t *sb, uint16_t magic)
355{
356 sb->magic = host2uint16_t_le(magic);
357}
358
[2226cc3]359/** Get filesystem state.
[9fc72fb3]360 *
[2226cc3]361 * @param sb superblock
362 * @return filesystem state
[9fc72fb3]363 */
[3712434]364uint16_t ext4_superblock_get_state(ext4_superblock_t *sb)
365{
366 return uint16_t_le2host(sb->state);
367}
368
[2226cc3]369/** Set filesystem state.
[9fc72fb3]370 *
[2226cc3]371 * @param sb superblock
372 * @param state filesystem state
[9fc72fb3]373 */
[fe27eb4]374void ext4_superblock_set_state(ext4_superblock_t *sb, uint16_t state)
375{
376 sb->state = host2uint16_t_le(state);
377}
378
[2226cc3]379/** Get behavior code when errors detected.
[9fc72fb3]380 *
[2226cc3]381 * @param sb superblock
382 * @return behavior code
[9fc72fb3]383 */
[3712434]384uint16_t ext4_superblock_get_errors(ext4_superblock_t *sb)
385{
386 return uint16_t_le2host(sb->errors);
387}
388
[2226cc3]389/** Set behavior code when errors detected.
[9fc72fb3]390 *
[2226cc3]391 * @param sb superblock
392 * @param errors behavior code
[9fc72fb3]393 */
[fe27eb4]394void ext4_superblock_set_errors(ext4_superblock_t *sb, uint16_t errors)
395{
396 sb->errors = host2uint16_t_le(errors);
397}
[3712434]398
[2226cc3]399/** Get minor revision level of the filesystem.
[9fc72fb3]400 *
[2226cc3]401 * @param sb superblock
402 * @return minor revision level
[9fc72fb3]403 */
[3712434]404uint16_t ext4_superblock_get_minor_rev_level(ext4_superblock_t *sb)
405{
406 return uint16_t_le2host(sb->minor_rev_level);
407}
408
[2226cc3]409/** Set minor revision level of the filesystem.
[9fc72fb3]410 *
[2226cc3]411 * @param sb superblock
412 * @param level minor revision level
[9fc72fb3]413 */
[fe27eb4]414void ext4_superblock_set_minor_rev_level(ext4_superblock_t *sb, uint16_t level)
415{
416 sb->minor_rev_level = host2uint16_t_le(level);
417}
418
[2226cc3]419/** Get time of the last filesystem check.
[9fc72fb3]420 *
[2226cc3]421 * @param sb superblock
422 * @return time of the last check (POSIX)
[9fc72fb3]423 */
[3712434]424uint32_t ext4_superblock_get_last_check_time(ext4_superblock_t *sb)
425{
426 return uint32_t_le2host(sb->last_check_time);
427}
428
[2226cc3]429/** Set time of the last filesystem check.
[9fc72fb3]430 *
[2226cc3]431 * @param sb superblock
432 * @param time time of the last check (POSIX)
[9fc72fb3]433 */
[fe27eb4]434void ext4_superblock_set_last_check_time(ext4_superblock_t *sb, uint32_t time)
435{
436 sb->state = host2uint32_t_le(time);
437}
438
[2226cc3]439/** Get maximum time interval between two filesystem checks.
[9fc72fb3]440 *
[2226cc3]441 * @param sb superblock
442 * @return time interval between two check (POSIX)
[9fc72fb3]443 */
[3712434]444uint32_t ext4_superblock_get_check_interval(ext4_superblock_t *sb){
445 return uint32_t_le2host(sb->check_interval);
446}
447
[2226cc3]448/** Set maximum time interval between two filesystem checks.
[9fc72fb3]449 *
[2226cc3]450 * @param sb superblock
451 * @param interval time interval between two check (POSIX)
[9fc72fb3]452 */
[fe27eb4]453void ext4_superblock_set_check_interval(ext4_superblock_t *sb, uint32_t interval)
454{
455 sb->check_interval = host2uint32_t_le(interval);
456}
457
[2226cc3]458/** Get operation system identifier, on which the filesystem was created.
[9fc72fb3]459 *
[2226cc3]460 * @param sb superblock
461 * @return operation system identifier
[9fc72fb3]462 */
[3712434]463uint32_t ext4_superblock_get_creator_os(ext4_superblock_t *sb)
464{
465 return uint32_t_le2host(sb->creator_os);
[01ab41b]466}
467
[2226cc3]468/** Set operation system identifier, on which the filesystem was created.
[9fc72fb3]469 *
[2226cc3]470 * @param sb superblock
471 * @param os operation system identifier
[9fc72fb3]472 */
[fe27eb4]473void ext4_superblock_set_creator_os(ext4_superblock_t *sb, uint32_t os)
474{
475 sb->creator_os = host2uint32_t_le(os);
476}
477
[2226cc3]478/** Get revision level of the filesystem.
[9fc72fb3]479 *
[2226cc3]480 * @param sb superblock
481 * @return revision level
[9fc72fb3]482 */
[9c0c0e1]483uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *sb)
484{
485 return uint32_t_le2host(sb->rev_level);
486}
487
[2226cc3]488/** Set revision level of the filesystem.
[9fc72fb3]489 *
[2226cc3]490 * @param sb superblock
491 * @param level revision level
[9fc72fb3]492 */
[fe27eb4]493void ext4_superblock_set_rev_level(ext4_superblock_t *sb, uint32_t level)
494{
495 sb->rev_level = host2uint32_t_le(level);
496}
497
[2226cc3]498/** Get default user id for reserved blocks.
[9fc72fb3]499 *
[2226cc3]500 * @param sb superblock
501 * @return default user id for reserved blocks.
[9fc72fb3]502 */
[fe27eb4]503uint16_t ext4_superblock_get_def_resuid(ext4_superblock_t *sb)
504{
505 return uint16_t_le2host(sb->def_resuid);
506}
507
[2226cc3]508/** Set default user id for reserved blocks.
[9fc72fb3]509 *
[2226cc3]510 * @param sb superblock
511 * @param uid default user id for reserved blocks.
[9fc72fb3]512 */
[fe27eb4]513void ext4_superblock_set_def_resuid(ext4_superblock_t *sb, uint16_t uid)
514{
515 sb->def_resuid = host2uint16_t_le(uid);
516}
517
[2226cc3]518/** Get default group id for reserved blocks.
[9fc72fb3]519 *
[2226cc3]520 * @param sb superblock
521 * @return default group id for reserved blocks.
[9fc72fb3]522 */
[fe27eb4]523uint16_t ext4_superblock_get_def_resgid(ext4_superblock_t *sb)
524{
525 return uint16_t_le2host(sb->def_resgid);
526}
527
[2226cc3]528/** Set default group id for reserved blocks.
[9fc72fb3]529 *
[2226cc3]530 * @param sb superblock
531 * @param gid default group id for reserved blocks.
[9fc72fb3]532 */
[fe27eb4]533void ext4_superblock_set_def_resgid(ext4_superblock_t *sb, uint16_t gid)
534{
535 sb->def_resgid = host2uint16_t_le(gid);
536}
537
[2226cc3]538/** Get index of the first i-node, which can be used for allocation.
[9fc72fb3]539 *
[2226cc3]540 * @param sb superblock
541 * @return i-node index
[9fc72fb3]542 */
[fe27eb4]543uint32_t ext4_superblock_get_first_inode(ext4_superblock_t *sb)
544{
545 return uint32_t_le2host(sb->first_inode);
546}
547
[2226cc3]548/** Set index of the first i-node, which can be used for allocation.
[9fc72fb3]549 *
[2226cc3]550 * @param sb superblock
551 * @param first_inode i-node index
[9fc72fb3]552 */
[fe27eb4]553void ext4_superblock_set_first_inode(ext4_superblock_t *sb, uint32_t first_inode)
554{
555 sb->first_inode = host2uint32_t_le(first_inode);
556}
557
[2226cc3]558/** Get size of i-node structure.
559 *
560 * For the oldest revision return constant number.
[9fc72fb3]561 *
[2226cc3]562 * @param sb superblock
563 * @return size of i-node structure
[9fc72fb3]564 */
[3711e7e]565uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb)
566{
567 if (ext4_superblock_get_rev_level(sb) == 0) {
568 return EXT4_REV0_INODE_SIZE;
569 }
570 return uint16_t_le2host(sb->inode_size);
571}
572
[2226cc3]573/** Set size of i-node structure.
[9fc72fb3]574 *
[2226cc3]575 * @param sb superblock
576 * @param size size of i-node structure
[9fc72fb3]577 */
[fe27eb4]578void ext4_superblock_set_inode_size(ext4_superblock_t *sb, uint16_t size)
579{
580 sb->inode_size = host2uint16_t_le(size);
581}
582
[2226cc3]583/** Get index of block group, where superblock copy is located.
[9fc72fb3]584 *
[2226cc3]585 * @param sb superblock
586 * @return block group index
[9fc72fb3]587 */
[2226cc3]588uint16_t ext4_superblock_get_block_group_index(ext4_superblock_t *sb)
[3711e7e]589{
[2226cc3]590 return uint16_t_le2host(sb->block_group_index);
[3711e7e]591}
592
[2226cc3]593/** Set index of block group, where superblock copy is located.
[9fc72fb3]594 *
[2226cc3]595 * @param sb superblock
596 * @param bgid block group index
[9fc72fb3]597 */
[2226cc3]598void ext4_superblock_set_block_group_index(ext4_superblock_t *sb, uint16_t bgid)
[fe27eb4]599{
[2226cc3]600 sb->block_group_index = host2uint16_t_le(bgid);
[fe27eb4]601}
602
[2226cc3]603/** Get compatible features supported by the filesystem.
[9fc72fb3]604 *
[2226cc3]605 * @param sb superblock
606 * @return compatible features bitmap
[9fc72fb3]607 */
[9c0c0e1]608uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *sb)
609{
610 return uint32_t_le2host(sb->features_compatible);
611}
612
[2226cc3]613/** Set compatible features supported by the filesystem.
[9fc72fb3]614 *
[2226cc3]615 * @param sb superblock
616 * @param features compatible features bitmap
[9fc72fb3]617 */
[fe27eb4]618void ext4_superblock_set_features_compatible(ext4_superblock_t *sb, uint32_t features)
619{
620 sb->features_compatible = host2uint32_t_le(features);
621}
622
[2226cc3]623/** Get incompatible features supported by the filesystem.
[9fc72fb3]624 *
[2226cc3]625 * @param sb superblock
626 * @return incompatible features bitmap
[9fc72fb3]627 */
[9c0c0e1]628uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *sb)
629{
630 return uint32_t_le2host(sb->features_incompatible);
631}
632
[2226cc3]633/** Set incompatible features supported by the filesystem.
[9fc72fb3]634 *
[2226cc3]635 * @param sb superblock
636 * @param features incompatible features bitmap
[9fc72fb3]637 */
[fe27eb4]638void ext4_superblock_set_features_incompatible(ext4_superblock_t *sb, uint32_t features)
639{
640 sb->features_incompatible = host2uint32_t_le(features);
641}
642
[2226cc3]643/** Get compatible features supported by the filesystem.
[9fc72fb3]644 *
[2226cc3]645 * @param sb superblock
646 * @return read-only compatible features bitmap
[9fc72fb3]647 */
[9c0c0e1]648uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *sb)
649{
650 return uint32_t_le2host(sb->features_read_only);
651}
652
[2226cc3]653/** Set compatible features supported by the filesystem.
[9fc72fb3]654 *
[2226cc3]655 * @param sb superblock
656 * @param feature read-only compatible features bitmap
[9fc72fb3]657 */
[fe27eb4]658void ext4_superblock_set_features_read_only(ext4_superblock_t *sb, uint32_t features)
659{
660 sb->features_read_only = host2uint32_t_le(features);
661}
[01ab41b]662
[2226cc3]663/** Get UUID of the filesystem.
[9fc72fb3]664 *
[2226cc3]665 * @param sb superblock
666 * @return pointer to UUID array
[9fc72fb3]667 */
[291af81]668const uint8_t * ext4_superblock_get_uuid(ext4_superblock_t *sb)
669{
670 return sb->uuid;
671}
672
[2226cc3]673/** Set UUID of the filesystem.
[9fc72fb3]674 *
[2226cc3]675 * @param sb superblock
676 * @param uuid pointer to UUID array
[9fc72fb3]677 */
[291af81]678void ext4_superblock_set_uuid(ext4_superblock_t *sb, const uint8_t *uuid)
679{
680 memcpy(sb->uuid, uuid, sizeof(sb->uuid));
681}
682
[2226cc3]683/** Get name of the filesystem volume.
684 *
685 * @param sb superblock
686 * @return name of the volume
687 */
[291af81]688const char * ext4_superblock_get_volume_name(ext4_superblock_t *sb)
689{
690 return sb->volume_name;
691}
692
[2226cc3]693/** Set name of the filesystem volume.
[9fc72fb3]694 *
[2226cc3]695 * @param sb superblock
696 * @param name new name of the volume
[9fc72fb3]697 */
[291af81]698void ext4_superblock_set_volume_name(ext4_superblock_t *sb, const char *name)
699{
700 memcpy(sb->volume_name, name, sizeof(sb->volume_name));
701}
702
[2226cc3]703/** Get name of the directory, where this filesystem was mounted at last.
[9fc72fb3]704 *
[2226cc3]705 * @param sb superblock
706 * @return directory name
[9fc72fb3]707 */
[291af81]708const char * ext4_superblock_get_last_mounted(ext4_superblock_t *sb)
709{
710 return sb->last_mounted;
711}
712
[2226cc3]713/** Set name of the directory, where this filesystem was mounted at last.
[9fc72fb3]714 *
[2226cc3]715 * @param sb superblock
716 * @param last directory name
[9fc72fb3]717 */
[291af81]718void ext4_superblock_set_last_mounted(ext4_superblock_t *sb, const char *last)
719{
720 memcpy(sb->last_mounted, last, sizeof(sb->last_mounted));
721}
722
[2226cc3]723/** Get last orphaned i-node index.
724 *
725 * Orphans are stored in linked list.
[9fc72fb3]726 *
[2226cc3]727 * @param sb superblock
728 * @return last orphaned i-node index
[9fc72fb3]729 */
[ebcaff4]730uint32_t ext4_superblock_get_last_orphan(ext4_superblock_t *sb)
731{
732 return uint32_t_le2host(sb->last_orphan);
733}
734
[2226cc3]735/** Set last orphaned i-node index.
736 *
737 * Orphans are stored in linked list.
[9fc72fb3]738 *
[2226cc3]739 * @param sb superblock
740 * @param last_orphan last orphaned i-node index
[9fc72fb3]741 */
[ebcaff4]742void ext4_superblock_set_last_orphan(ext4_superblock_t *sb, uint32_t last_orphan)
743{
744 sb->last_orphan = host2uint32_t_le(last_orphan);
745}
746
[2226cc3]747/** Get hash seed for directory index hash function.
[9fc72fb3]748 *
[2226cc3]749 * @param sb superblock
750 * @return hash seed pointer
[9fc72fb3]751 */
[2226cc3]752const uint32_t * ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
[7bc4508]753{
754 return sb->hash_seed;
755}
756
[2226cc3]757/** Set hash seed for directory index hash function.
[9fc72fb3]758 *
[2226cc3]759 * @param sb superblock
760 * @param seed hash seed pointer
761 */
762void ext4_superblock_set_hash_seed(ext4_superblock_t *sb, const uint32_t *seed)
763{
764 memcpy(sb->hash_seed, seed, sizeof(sb->hash_seed));
765}
766
767/** Get default version of the hash algorithm version for directory index.
768 *
769 * @param sb superblock
770 * @return default hash version
[9fc72fb3]771 */
[7eb033ce]772uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *sb)
773{
774 return sb->default_hash_version;
775}
776
[2226cc3]777/** Set default version of the hash algorithm version for directory index.
[9fc72fb3]778 *
[2226cc3]779 * @param sb superblock
780 * @param version default hash version
[9fc72fb3]781 */
[7eb033ce]782void ext4_superblock_set_default_hash_version(ext4_superblock_t *sb, uint8_t version)
783{
784 sb->default_hash_version = version;
785}
786
[2226cc3]787/** Get size of block group descriptor structure.
[9fc72fb3]788 *
[2226cc3]789 * Output value is checked for minimal size.
790 *
791 * @param sb superblock
792 * @return size of block group descriptor
[9fc72fb3]793 */
[c25e39b]794uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *sb)
795{
796 uint16_t size = uint16_t_le2host(sb->desc_size);
797
798 if (size < EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
799 size = EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE;
800 }
801
802 return size;
803}
804
[2226cc3]805/** Set size of block group descriptor structure.
806 *
807 * Input value is checked for minimal size.
[9fc72fb3]808 *
[2226cc3]809 * @param sb superblock
810 * @param size size of block group descriptor
[9fc72fb3]811 */
[fe27eb4]812void ext4_superblock_set_desc_size(ext4_superblock_t *sb, uint16_t size)
813{
[2226cc3]814 if (size < EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
815 sb->desc_size = host2uint16_t_le(EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE);
816 }
817
[fe27eb4]818 sb->desc_size = host2uint16_t_le(size);
819}
820
[2226cc3]821/** Get superblock flags.
[9fc72fb3]822 *
[2226cc3]823 * @param sb superblock
824 * @return flags from the superblock
[9fc72fb3]825 */
[7bc4508]826uint32_t ext4_superblock_get_flags(ext4_superblock_t *sb)
827{
828 return uint32_t_le2host(sb->flags);
829}
830
[2226cc3]831/** Set superblock flags.
[9fc72fb3]832 *
[2226cc3]833 * @param sb superblock
834 * @param flags flags for the superblock
[9fc72fb3]835 */
[fe27eb4]836void ext4_superblock_set_flags(ext4_superblock_t *sb, uint32_t flags)
837{
838 sb->flags = host2uint32_t_le(flags);
839}
840
[3712434]841/*
[c25e39b]842 * More complex superblock operations
[01ab41b]843 */
[3712434]844
[2226cc3]845/** Check if superblock has specified flag.
[9fc72fb3]846 *
[2226cc3]847 * @param sb superblock
848 * @param flag flag to be checked
849 * @return true, if superblock has the flag
[9fc72fb3]850 */
[7bc4508]851bool ext4_superblock_has_flag(ext4_superblock_t *sb, uint32_t flag)
852{
853 if (ext4_superblock_get_flags(sb) & flag) {
854 return true;
855 }
856 return false;
857}
858
[2226cc3]859/** Check if filesystem supports compatible feature.
[9fc72fb3]860 *
[2226cc3]861 * @param sb superblock
862 * @param feature feature to be checked
863 * @return true, if filesystem supports the feature
[9fc72fb3]864 */
[c25e39b]865bool ext4_superblock_has_feature_compatible(ext4_superblock_t *sb, uint32_t feature)
866{
867 if (ext4_superblock_get_features_compatible(sb) & feature) {
868 return true;
869 }
870 return false;
871}
872
[2226cc3]873/** Check if filesystem supports incompatible feature.
[9fc72fb3]874 *
[2226cc3]875 * @param sb superblock
876 * @param feature feature to be checked
877 * @return true, if filesystem supports the feature
[9fc72fb3]878 */
[c25e39b]879bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *sb, uint32_t feature)
880{
881 if (ext4_superblock_get_features_incompatible(sb) & feature) {
882 return true;
883 }
884 return false;
885}
886
[2226cc3]887/** Check if filesystem supports read-only compatible feature.
[9fc72fb3]888 *
[2226cc3]889 * @param sb superblock
890 * @param feature feature to be checked
891 * @return true, if filesystem supports the feature
[9fc72fb3]892 */
[c25e39b]893bool ext4_superblock_has_feature_read_only(ext4_superblock_t *sb, uint32_t feature)
894{
895 if (ext4_superblock_get_features_read_only(sb) & feature) {
896 return true;
897 }
898 return false;
899}
900
[2226cc3]901/** Read superblock directly from block device.
[9fc72fb3]902 *
[2226cc3]903 * @param service_id block device identifier
904 * @param sb output pointer to memory structure
905 * @return error code.
[9fc72fb3]906 */
[01ab41b]907int ext4_superblock_read_direct(service_id_t service_id,
[2226cc3]908 ext4_superblock_t **sb)
[01ab41b]909{
910 int rc;
911
[2226cc3]912 // Allocated memory for superblock structure
[d9bbe45]913 void *data = malloc(EXT4_SUPERBLOCK_SIZE);
[01ab41b]914 if (data == NULL) {
915 return ENOMEM;
916 }
917
[2226cc3]918 // Read data from block device
[01ab41b]919 rc = block_read_bytes_direct(service_id, EXT4_SUPERBLOCK_OFFSET,
920 EXT4_SUPERBLOCK_SIZE, data);
921
922 if (rc != EOK) {
923 free(data);
924 return rc;
925 }
926
[2226cc3]927 // Set output value
928 (*sb) = data;
[01ab41b]929
930 return EOK;
931}
932
[2226cc3]933/** Write superblock structure directly to block device.
[9fc72fb3]934 *
[2226cc3]935 * @param service_id block device identifier
936 * @param sb superblock to be written
937 * @return error code
[9fc72fb3]938 */
[ae3d4f8]939int ext4_superblock_write_direct(service_id_t service_id,
940 ext4_superblock_t *sb)
941{
942 int rc;
943 uint32_t phys_block_size;
944
[2226cc3]945 // Load physical block size from block device
[ae3d4f8]946 rc = block_get_bsize(service_id, &phys_block_size);
947 if (rc != EOK) {
948 return rc;
949 }
950
[2226cc3]951 // Compute address of the first block
[d9bbe45]952 uint64_t first_block = EXT4_SUPERBLOCK_OFFSET / phys_block_size;
[2226cc3]953 // Compute number of block to write
[d9bbe45]954 uint32_t block_count = EXT4_SUPERBLOCK_SIZE / phys_block_size;
[ae3d4f8]955
[2226cc3]956 // Check alignment
[ae3d4f8]957 if (EXT4_SUPERBLOCK_SIZE % phys_block_size) {
958 block_count++;
959 }
960
[2226cc3]961 // Write data
[ae3d4f8]962 return block_write_direct(service_id, first_block, block_count, sb);
963
964}
965
[9fc72fb3]966/** TODO comment
967 *
968 */
[01ab41b]969int ext4_superblock_check_sanity(ext4_superblock_t *sb)
970{
[9c0c0e1]971 if (ext4_superblock_get_magic(sb) != EXT4_SUPERBLOCK_MAGIC) {
972 return ENOTSUP;
973 }
974
[fe27eb4]975 // block size
976 // desc size
977
978
[9c0c0e1]979 // TODO more checks !!!
980
[01ab41b]981 return EOK;
982}
[eb91db7]983
[2226cc3]984/** Compute number of block groups in the filesystem.
[9fc72fb3]985 *
[2226cc3]986 * @param sb superblock
987 * @return number of block groups
[9fc72fb3]988 */
[b12ca16]989uint32_t ext4_superblock_get_block_group_count(ext4_superblock_t *sb)
990{
991 uint64_t blocks_count = ext4_superblock_get_blocks_count(sb);
992 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
993
994 uint32_t block_groups_count = blocks_count / blocks_per_group;
995
996 if (blocks_count % blocks_per_group) {
997 block_groups_count++;
998 }
999
1000 return block_groups_count;
1001
1002}
1003
[2226cc3]1004/** Compute number of blocks in specified block group.
[9fc72fb3]1005 *
[2226cc3]1006 * @param sb superblock
1007 * @param bgid block group index
1008 * @return number of blocks
[9fc72fb3]1009 */
[b12ca16]1010uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *sb, uint32_t bgid)
1011{
1012 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
1013 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
1014 uint64_t total_blocks = ext4_superblock_get_blocks_count(sb);
1015
1016 if (bgid < block_group_count - 1) {
1017 return blocks_per_group;
1018 } else {
1019 return (total_blocks - ((block_group_count - 1) * blocks_per_group));
1020 }
1021
1022}
1023
[2226cc3]1024/** Compute number of i-nodes in specified block group.
[9fc72fb3]1025 *
[2226cc3]1026 * @param sb superblock
1027 * @param bgid block group index
1028 * @return number of i-nodes
[9fc72fb3]1029 */
[b12ca16]1030uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *sb, uint32_t bgid)
1031{
1032 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
1033 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
1034 uint32_t total_inodes = ext4_superblock_get_inodes_count(sb);
1035
1036 if (bgid < block_group_count - 1) {
1037 return inodes_per_group;
1038 } else {
1039 return (total_inodes - ((block_group_count - 1) * inodes_per_group));
1040 }
1041
1042}
1043
[eb91db7]1044/**
1045 * @}
1046 */
Note: See TracBrowser for help on using the repository browser.