Changeset 3711e7e in mainline for uspace/lib/ext4/libext4_filesystem.c


Ignore:
Timestamp:
2011-10-05T09:35:12Z (13 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3712434
Parents:
cfa1a8a
Message:

Complete mounting skeleton (ported from ext2fs) - some filesystem checks during mount process still missing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4_filesystem.c

    rcfa1a8a r3711e7e  
    3838#include <errno.h>
    3939#include <malloc.h>
    40 #include "libext4_filesystem.h"
     40#include "libext4.h"
    4141
    4242/**
     
    8383
    8484        return EOK;
     85}
     86
     87/**
     88 * TODO doxy
     89 */
     90void ext4_filesystem_fini(ext4_filesystem_t *fs)
     91{
     92        free(fs->superblock);
     93        block_fini(fs->device);
    8594}
    8695
     
    132141 * TODO doxy
    133142 */
    134 void ext4_filesystem_fini(ext4_filesystem_t *fs)
    135 {
    136         free(fs->superblock);
    137         block_fini(fs->device);
    138 }
    139 
     143int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *fs, uint32_t bgid,
     144    ext4_block_group_ref_t **ref)
     145{
     146        int rc;
     147        aoff64_t block_id;
     148        uint32_t descriptors_per_block;
     149        size_t offset;
     150        ext4_block_group_ref_t *newref;
     151
     152        newref = malloc(sizeof(ext4_block_group_ref_t));
     153        if (newref == NULL) {
     154                return ENOMEM;
     155        }
     156
     157        descriptors_per_block = ext4_superblock_get_block_size(fs->superblock)
     158            / EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE;
     159
     160        /* Block group descriptor table starts at the next block after superblock */
     161        block_id = ext4_superblock_get_first_block(fs->superblock) + 1;
     162
     163        /* Find the block containing the descriptor we are looking for */
     164        block_id += bgid / descriptors_per_block;
     165        offset = (bgid % descriptors_per_block) * EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE;
     166
     167        rc = block_get(&newref->block, fs->device, block_id, 0);
     168        if (rc != EOK) {
     169                free(newref);
     170                return rc;
     171        }
     172
     173        newref->block_group = newref->block->data + offset;
     174
     175        *ref = newref;
     176
     177        return EOK;
     178}
     179
     180/**
     181 * TODO doxy
     182 */
     183int ext4_filesystem_get_inode_ref(ext4_filesystem_t *fs, uint32_t index,
     184    ext4_inode_ref_t **ref)
     185{
     186        int rc;
     187        aoff64_t block_id;
     188        uint32_t block_group;
     189        uint32_t offset_in_group;
     190        uint32_t byte_offset_in_group;
     191        size_t offset_in_block;
     192        uint32_t inodes_per_group;
     193        uint32_t inode_table_start;
     194        uint16_t inode_size;
     195        uint32_t block_size;
     196        ext4_block_group_ref_t *bg_ref;
     197        ext4_inode_ref_t *newref;
     198
     199        newref = malloc(sizeof(ext4_inode_ref_t));
     200        if (newref == NULL) {
     201                return ENOMEM;
     202        }
     203
     204        inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock);
     205
     206        /* inode numbers are 1-based, but it is simpler to work with 0-based
     207         * when computing indices
     208         */
     209        index -= 1;
     210        block_group = index / inodes_per_group;
     211        offset_in_group = index % inodes_per_group;
     212
     213        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     214        if (rc != EOK) {
     215                free(newref);
     216                return rc;
     217        }
     218
     219        inode_table_start = ext4_block_group_get_inode_table_first_block(
     220            bg_ref->block_group);
     221
     222        inode_size = ext4_superblock_get_inode_size(fs->superblock);
     223        block_size = ext4_superblock_get_block_size(fs->superblock);
     224
     225        byte_offset_in_group = offset_in_group * inode_size;
     226
     227        block_id = inode_table_start + (byte_offset_in_group / block_size);
     228        offset_in_block = byte_offset_in_group % block_size;
     229
     230        rc = block_get(&newref->block, fs->device, block_id, 0);
     231        if (rc != EOK) {
     232                free(newref);
     233                return rc;
     234        }
     235
     236        newref->inode = newref->block->data + offset_in_block;
     237        /* we decremented index above, but need to store the original value
     238         * in the reference
     239         */
     240        newref->index = index+1;
     241
     242        *ref = newref;
     243
     244        return EOK;
     245}
    140246
    141247/**
Note: See TracChangeset for help on using the changeset viewer.