source: mainline/uspace/lib/ext4/libext4_superblock.c@ 1e48a07e

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

added many getters and setters

  • Property mode set to 100644
File size: 13.1 KB
RevLine 
[eb91db7]1/*
2 * Copyright (c) 2011 Frantisek Princ
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
[3712434]44uint32_t ext4_superblock_get_inodes_count(ext4_superblock_t *sb)
[01ab41b]45{
[3712434]46 return uint32_t_le2host(sb->inodes_count);
[01ab41b]47}
48
[fe27eb4]49void ext4_superblock_set_inodes_count(ext4_superblock_t *sb, uint32_t count)
50{
51 sb->inodes_count = host2uint32_t_le(count);
52}
53
[3712434]54uint64_t ext4_superblock_get_blocks_count(ext4_superblock_t *sb)
55{
56 return ((uint64_t)uint32_t_le2host(sb->blocks_count_hi) << 32) |
57 uint32_t_le2host(sb->blocks_count_lo);
58}
59
[fe27eb4]60void ext4_superblock_set_blocks_count(ext4_superblock_t *sb, uint64_t count)
61{
62 sb->blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
63 sb->blocks_count_hi = host2uint32_t_le(count >> 32);
64}
65
[3712434]66uint64_t ext4_superblock_get_reserved_blocks_count(ext4_superblock_t *sb)
67{
68 return ((uint64_t)uint32_t_le2host(sb->reserved_blocks_count_hi) << 32) |
69 uint32_t_le2host(sb->reserved_blocks_count_lo);
70}
71
[fe27eb4]72void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *sb, uint64_t count)
73{
74 sb->reserved_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
75 sb->reserved_blocks_count_hi = host2uint32_t_le(count >> 32);
76}
77
[3712434]78uint64_t ext4_superblock_get_free_blocks_count(ext4_superblock_t *sb)
79{
80 return ((uint64_t)uint32_t_le2host(sb->free_blocks_count_hi) << 32) |
81 uint32_t_le2host(sb->free_blocks_count_lo);
82}
83
[ae3d4f8]84void ext4_superblock_set_free_blocks_count(ext4_superblock_t *sb, uint64_t count)
85{
86 sb->free_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
87 sb->free_blocks_count_hi = host2uint32_t_le(count >> 32);
88}
89
[3712434]90uint32_t ext4_superblock_get_free_inodes_count(ext4_superblock_t *sb)
91{
92 return uint32_t_le2host(sb->free_inodes_count);
93}
94
[fe27eb4]95void ext4_superblock_set_free_inodes_count(ext4_superblock_t *sb, uint32_t count)
96{
97 sb->free_inodes_count = host2uint32_t_le(count);
98}
99
[3712434]100uint32_t ext4_superblock_get_first_data_block(ext4_superblock_t *sb)
[01ab41b]101{
[9c0c0e1]102 return uint32_t_le2host(sb->first_data_block);
[01ab41b]103}
104
[fe27eb4]105void ext4_superblock_set_first_data_block(ext4_superblock_t *sb, uint32_t first)
106{
107 sb->first_data_block = host2uint32_t_le(first);
108}
109
[3712434]110uint32_t ext4_superblock_get_log_block_size(ext4_superblock_t *sb)
[01ab41b]111{
[9c0c0e1]112 return uint32_t_le2host(sb->log_block_size);
[01ab41b]113}
114
[fe27eb4]115void ext4_superblock_set_log_block_size(ext4_superblock_t *sb, uint32_t log_size)
116{
117 sb->log_block_size = host2uint32_t_le(log_size);
118}
119
[01ab41b]120uint32_t ext4_superblock_get_block_size(ext4_superblock_t *sb)
121{
[3712434]122 return 1024 << ext4_superblock_get_log_block_size(sb);
123}
124
[fe27eb4]125void ext4_superblock_set_block_size(ext4_superblock_t *sb, uint32_t size)
126{
127 uint32_t log = 0;
128 uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
129
130 tmp >>= 1;
131 while (tmp) {
132 log++;
133 tmp >>= 1;
134 }
135
136 ext4_superblock_set_log_block_size(sb, log);
137}
[3712434]138
139uint32_t ext4_superblock_get_blocks_per_group(ext4_superblock_t *sb)
140{
141 return uint32_t_le2host(sb->blocks_per_group);
142}
143
[fe27eb4]144void ext4_superblock_set_blocks_per_group(ext4_superblock_t *sb, uint32_t blocks)
145{
146 sb->blocks_per_group = host2uint32_t_le(blocks);
147}
148
[3712434]149uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb)
150{
151 return uint32_t_le2host(sb->inodes_per_group);
152}
153
[fe27eb4]154void ext4_superblock_set_inodes_per_group(ext4_superblock_t *sb, uint32_t inodes)
155{
156 sb->inodes_per_group = host2uint32_t_le(inodes);
157}
158
[3712434]159uint32_t ext4_superblock_get_mount_time(ext4_superblock_t *sb)
160{
161 return uint32_t_le2host(sb->mount_time);
162}
163
[fe27eb4]164void ext4_superblock_set_mount_time(ext4_superblock_t *sb, uint32_t time)
165{
166 sb->mount_time = host2uint32_t_le(time);
167}
168
[3712434]169uint32_t ext4_superblock_get_write_time(ext4_superblock_t *sb)
170{
171 return uint32_t_le2host(sb->write_time);
172}
173
[fe27eb4]174void ext4_superblock_set_write_time(ext4_superblock_t *sb, uint32_t time)
175{
176 sb->write_time = host2uint32_t_le(time);
177}
178
[3712434]179uint16_t ext4_superblock_get_mount_count(ext4_superblock_t *sb)
180{
181 return uint16_t_le2host(sb->mount_count);
182}
183
[fe27eb4]184void ext4_superblock_set_mount_count(ext4_superblock_t *sb, uint16_t count)
185{
186 sb->mount_count = host2uint16_t_le(count);
187}
188
[3712434]189uint16_t ext4_superblock_get_max_mount_count(ext4_superblock_t *sb)
190{
191 return uint16_t_le2host(sb->max_mount_count);
192}
193
[fe27eb4]194void ext4_superblock_set_max_mount_count(ext4_superblock_t *sb, uint16_t count)
195{
196 sb->max_mount_count = host2uint16_t_le(count);
197}
198
[3712434]199uint16_t ext4_superblock_get_magic(ext4_superblock_t *sb)
200{
201 return uint16_t_le2host(sb->magic);
202}
203
204uint16_t ext4_superblock_get_state(ext4_superblock_t *sb)
205{
206 return uint16_t_le2host(sb->state);
207}
208
[fe27eb4]209void ext4_superblock_set_state(ext4_superblock_t *sb, uint16_t state)
210{
211 sb->state = host2uint16_t_le(state);
212}
213
[3712434]214uint16_t ext4_superblock_get_errors(ext4_superblock_t *sb)
215{
216 return uint16_t_le2host(sb->errors);
217}
218
[fe27eb4]219void ext4_superblock_set_errors(ext4_superblock_t *sb, uint16_t errors)
220{
221 sb->errors = host2uint16_t_le(errors);
222}
[3712434]223
224uint16_t ext4_superblock_get_minor_rev_level(ext4_superblock_t *sb)
225{
226 return uint16_t_le2host(sb->minor_rev_level);
227}
228
[fe27eb4]229void ext4_superblock_set_minor_rev_level(ext4_superblock_t *sb, uint16_t level)
230{
231 sb->minor_rev_level = host2uint16_t_le(level);
232}
233
[3712434]234uint32_t ext4_superblock_get_last_check_time(ext4_superblock_t *sb)
235{
236 return uint32_t_le2host(sb->last_check_time);
237}
238
[fe27eb4]239void ext4_superblock_set_last_check_time(ext4_superblock_t *sb, uint32_t time)
240{
241 sb->state = host2uint32_t_le(time);
242}
243
[3712434]244uint32_t ext4_superblock_get_check_interval(ext4_superblock_t *sb){
245 return uint32_t_le2host(sb->check_interval);
246}
247
[fe27eb4]248void ext4_superblock_set_check_interval(ext4_superblock_t *sb, uint32_t interval)
249{
250 sb->check_interval = host2uint32_t_le(interval);
251}
252
[3712434]253uint32_t ext4_superblock_get_creator_os(ext4_superblock_t *sb)
254{
255 return uint32_t_le2host(sb->creator_os);
[01ab41b]256}
257
[fe27eb4]258void ext4_superblock_set_creator_os(ext4_superblock_t *sb, uint32_t os)
259{
260 sb->creator_os = host2uint32_t_le(os);
261}
262
[9c0c0e1]263uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *sb)
264{
265 return uint32_t_le2host(sb->rev_level);
266}
267
[fe27eb4]268void ext4_superblock_set_rev_level(ext4_superblock_t *sb, uint32_t level)
269{
270 sb->rev_level = host2uint32_t_le(level);
271}
272
273uint16_t ext4_superblock_get_def_resuid(ext4_superblock_t *sb)
274{
275 return uint16_t_le2host(sb->def_resuid);
276}
277
278void ext4_superblock_set_def_resuid(ext4_superblock_t *sb, uint16_t uid)
279{
280 sb->def_resuid = host2uint16_t_le(uid);
281}
282
283uint16_t ext4_superblock_get_def_resgid(ext4_superblock_t *sb)
284{
285 return uint16_t_le2host(sb->def_resgid);
286}
287
288void ext4_superblock_set_def_resgid(ext4_superblock_t *sb, uint16_t gid)
289{
290 sb->def_resgid = host2uint16_t_le(gid);
291}
292
293uint32_t ext4_superblock_get_first_inode(ext4_superblock_t *sb)
294{
295 return uint32_t_le2host(sb->first_inode);
296}
297
298void ext4_superblock_set_first_inode(ext4_superblock_t *sb, uint32_t first_inode)
299{
300 sb->first_inode = host2uint32_t_le(first_inode);
301}
302
[3711e7e]303uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb)
304{
305 if (ext4_superblock_get_rev_level(sb) == 0) {
306 return EXT4_REV0_INODE_SIZE;
307 }
308 return uint16_t_le2host(sb->inode_size);
309}
310
[fe27eb4]311void ext4_superblock_set_inode_size(ext4_superblock_t *sb, uint16_t size)
312{
313 sb->inode_size = host2uint16_t_le(size);
314}
315
[3712434]316uint16_t ext4_superblock_get_block_group_number(ext4_superblock_t *sb)
[3711e7e]317{
[3712434]318 return uint16_t_le2host(sb->block_group_number);
[3711e7e]319}
320
[fe27eb4]321void ext4_superblock_set_block_group_number(ext4_superblock_t *sb, uint16_t bg)
322{
323 sb->block_group_number = host2uint16_t_le(bg);
324}
325
[9c0c0e1]326uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *sb)
327{
328 return uint32_t_le2host(sb->features_compatible);
329}
330
[fe27eb4]331void ext4_superblock_set_features_compatible(ext4_superblock_t *sb, uint32_t features)
332{
333 sb->features_compatible = host2uint32_t_le(features);
334}
335
[9c0c0e1]336uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *sb)
337{
338 return uint32_t_le2host(sb->features_incompatible);
339}
340
[fe27eb4]341void ext4_superblock_set_features_incompatible(ext4_superblock_t *sb, uint32_t features)
342{
343 sb->features_incompatible = host2uint32_t_le(features);
344}
345
[9c0c0e1]346uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *sb)
347{
348 return uint32_t_le2host(sb->features_read_only);
349}
350
[fe27eb4]351void ext4_superblock_set_features_read_only(ext4_superblock_t *sb, uint32_t features)
352{
353 sb->features_read_only = host2uint32_t_le(features);
354}
[01ab41b]355
[7bc4508]356uint32_t* ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
357{
358 return sb->hash_seed;
359}
360
[c25e39b]361uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *sb)
362{
363 uint16_t size = uint16_t_le2host(sb->desc_size);
364
365 if (size < EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
366 size = EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE;
367 }
368
369 return size;
370}
371
[fe27eb4]372void ext4_superblock_set_desc_size(ext4_superblock_t *sb, uint16_t size)
373{
374 sb->desc_size = host2uint16_t_le(size);
375}
376
[7bc4508]377uint32_t ext4_superblock_get_flags(ext4_superblock_t *sb)
378{
379 return uint32_t_le2host(sb->flags);
380}
381
[fe27eb4]382void ext4_superblock_set_flags(ext4_superblock_t *sb, uint32_t flags)
383{
384 sb->flags = host2uint32_t_le(flags);
385}
386
[7bc4508]387
[3712434]388/*
[c25e39b]389 * More complex superblock operations
[01ab41b]390 */
[3712434]391
[7bc4508]392bool ext4_superblock_has_flag(ext4_superblock_t *sb, uint32_t flag)
393{
394 if (ext4_superblock_get_flags(sb) & flag) {
395 return true;
396 }
397 return false;
398}
399
[c25e39b]400// Feature checkers
401bool ext4_superblock_has_feature_compatible(ext4_superblock_t *sb, uint32_t feature)
402{
403 if (ext4_superblock_get_features_compatible(sb) & feature) {
404 return true;
405 }
406 return false;
407}
408
409bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *sb, uint32_t feature)
410{
411 if (ext4_superblock_get_features_incompatible(sb) & feature) {
412 return true;
413 }
414 return false;
415}
416
417bool ext4_superblock_has_feature_read_only(ext4_superblock_t *sb, uint32_t feature)
418{
419 if (ext4_superblock_get_features_read_only(sb) & feature) {
420 return true;
421 }
422 return false;
423}
424
425
[01ab41b]426int ext4_superblock_read_direct(service_id_t service_id,
427 ext4_superblock_t **superblock)
428{
429 void *data;
430 int rc;
431
432 data = malloc(EXT4_SUPERBLOCK_SIZE);
433 if (data == NULL) {
434 return ENOMEM;
435 }
436
437 rc = block_read_bytes_direct(service_id, EXT4_SUPERBLOCK_OFFSET,
438 EXT4_SUPERBLOCK_SIZE, data);
439
440 if (rc != EOK) {
441 free(data);
442 return rc;
443 }
444
445 (*superblock) = data;
446
447 return EOK;
448}
449
[ae3d4f8]450int ext4_superblock_write_direct(service_id_t service_id,
451 ext4_superblock_t *sb)
452{
453 int rc;
454 uint32_t phys_block_size;
455 uint64_t first_block;
456 uint32_t block_count;
457
458 rc = block_get_bsize(service_id, &phys_block_size);
459 if (rc != EOK) {
460 // TODO error
461 return rc;
462 }
463
464 first_block = EXT4_SUPERBLOCK_OFFSET / phys_block_size;
465 block_count = EXT4_SUPERBLOCK_SIZE / phys_block_size;
466
467 if (EXT4_SUPERBLOCK_SIZE % phys_block_size) {
468 block_count++;
469 }
470
471 return block_write_direct(service_id, first_block, block_count, sb);
472
473}
474
475
[01ab41b]476int ext4_superblock_check_sanity(ext4_superblock_t *sb)
477{
[9c0c0e1]478 if (ext4_superblock_get_magic(sb) != EXT4_SUPERBLOCK_MAGIC) {
479 return ENOTSUP;
480 }
481
[fe27eb4]482 // block size
483 // desc size
484
485
[9c0c0e1]486 // TODO more checks !!!
487
[01ab41b]488 return EOK;
489}
[eb91db7]490
[b12ca16]491uint32_t ext4_superblock_get_block_group_count(ext4_superblock_t *sb)
492{
493 uint64_t blocks_count = ext4_superblock_get_blocks_count(sb);
494 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
495
496 uint32_t block_groups_count = blocks_count / blocks_per_group;
497
498 if (blocks_count % blocks_per_group) {
499 block_groups_count++;
500 }
501
502 return block_groups_count;
503
504}
505
506uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *sb, uint32_t bgid)
507{
508 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
509 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
510 uint64_t total_blocks = ext4_superblock_get_blocks_count(sb);
511
512 if (bgid < block_group_count - 1) {
513 return blocks_per_group;
514 } else {
515 return (total_blocks - ((block_group_count - 1) * blocks_per_group));
516 }
517
518}
519
520uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *sb, uint32_t bgid)
521{
522 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
523 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
524 uint32_t total_inodes = ext4_superblock_get_inodes_count(sb);
525
526 if (bgid < block_group_count - 1) {
527 return inodes_per_group;
528 } else {
529 return (total_inodes - ((block_group_count - 1) * inodes_per_group));
530 }
531
532}
533
[eb91db7]534/**
535 * @}
536 */
Note: See TracBrowser for help on using the repository browser.