Changeset 3711e7e in mainline


Ignore:
Timestamp:
2011-10-05T09:35:12Z (12 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

Location:
uspace
Files:
9 edited

Legend:

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

    rcfa1a8a r3711e7e  
    3636 */
    3737
    38 #include "libext4_block_group.h"
     38#include <byteorder.h>
     39#include "libext4.h"
    3940
     41uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *bg)
     42{
     43        return ((uint64_t)uint32_t_le2host(bg->inode_table_first_hi) << 32) |
     44                        uint32_t_le2host(bg->inode_table_first_lo);
     45}
    4046
    4147/**
  • uspace/lib/ext4/libext4_block_group.h

    rcfa1a8a r3711e7e  
    3434#define LIBEXT4_LIBEXT4_BLOCK_GROUP_H_
    3535
     36#include <libblock.h>
    3637#include <sys/types.h>
    37 
     38#include "libext4_block_group.h"
    3839/*
    3940 * Structure of a blocks group descriptor
     
    4243        uint32_t block_bitmap_lo; // Blocks bitmap block
    4344        uint32_t inode_bitmap_lo; // Inodes bitmap block
    44         uint32_t inode_table_lo; // Inodes table block
     45        uint32_t inode_table_first_lo; // Inodes table block
    4546        uint16_t free_blocks_count_lo; // Free blocks count
    4647        uint16_t free_inodes_count_lo; // Free inodes count
     
    5253        uint32_t block_bitmap_hi; // Blocks bitmap block MSB
    5354        uint32_t inode_bitmap_hi; // Inodes bitmap block MSB
    54         uint32_t inode_table_hi; // Inodes table block MSB
     55        uint32_t inode_table_first_hi; // Inodes table block MSB
    5556        uint16_t free_blocks_count_hi; // Free blocks count MSB
    5657        uint16_t free_inodes_count_hi; // Free inodes count MSB
     
    5859        uint16_t itable_unused_hi;  // Unused inodes count MSB
    5960        uint32_t reserved2[3]; // Padding
    60 } ext4_group_desc_t;
     61} ext4_block_group_t;
     62
     63typedef struct ext4_block_group_ref {
     64        block_t *block; // Reference to a block containing this block group descr
     65        ext4_block_group_t *block_group;
     66} ext4_block_group_ref_t;
     67
     68// TODO check value
     69#define EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE 32
     70
     71extern uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *);
    6172
    6273#endif
  • uspace/lib/ext4/libext4_directory.c

    rcfa1a8a r3711e7e  
    3636 */
    3737
    38 #include "libext4_directory.h"
     38#include "libext4.h"
    3939
    4040
  • 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/**
  • uspace/lib/ext4/libext4_filesystem.h

    rcfa1a8a r3711e7e  
    3535
    3636#include <libblock.h>
     37#include "libext4_block_group.h"
     38#include "libext4_inode.h"
    3739#include "libext4_superblock.h"
    3840
     
    4244} ext4_filesystem_t;
    4345
    44 #define EXT4_MAX_BLOCK_SIZE 65536 //64 KiB
    45 
     46#define EXT4_MAX_BLOCK_SIZE     65536 //64 KiB
     47#define EXT4_REV0_INODE_SIZE    128
    4648
    4749/* Compatible features */
     
    99101
    100102extern int ext4_filesystem_init(ext4_filesystem_t *, service_id_t);
     103extern void ext4_filesystem_fini(ext4_filesystem_t *fs);
    101104extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
    102105extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
    103 extern void ext4_filesystem_fini(ext4_filesystem_t *fs);
     106extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t,
     107    ext4_block_group_ref_t **);
     108extern int ext4_filesystem_get_inode_ref(ext4_filesystem_t *, uint32_t,
     109                ext4_inode_ref_t **);
     110
    104111
    105112#endif
  • uspace/lib/ext4/libext4_inode.c

    rcfa1a8a r3711e7e  
    3737
    3838#include <byteorder.h>
    39 #include "libext4_inode.h"
     39#include "libext4.h"
    4040
    4141// TODO check return type
  • uspace/lib/ext4/libext4_superblock.c

    rcfa1a8a r3711e7e  
    4040#include <libblock.h>
    4141#include <malloc.h>
    42 #include "libext4_superblock.h"
     42#include "libext4.h"
    4343
    4444/**
     
    8080{
    8181        return uint32_t_le2host(sb->rev_level);
     82}
     83
     84/**
     85 * TODO doxy
     86 */
     87uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb)
     88{
     89        if (ext4_superblock_get_rev_level(sb) == 0) {
     90                return EXT4_REV0_INODE_SIZE;
     91        }
     92        return uint16_t_le2host(sb->inode_size);
     93}
     94
     95/**
     96 * TODO doxy
     97 */
     98uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb)
     99{
     100        return uint32_t_le2host(sb->inodes_per_group);
    82101}
    83102
  • uspace/lib/ext4/libext4_superblock.h

    rcfa1a8a r3711e7e  
    5151        uint32_t s_blocks_per_group; // Number of blocks per group
    5252        uint32_t s_obso_frags_per_group; // Obsoleted fragments per group
    53         uint32_t s_inodes_per_group; // Number of inodes per group
     53        uint32_t inodes_per_group; // Number of inodes per group
    5454        uint32_t s_mtime; // Mount time
    5555        uint32_t s_wtime; // Write time
     
    6969        // Fields for EXT4_DYNAMIC_REV superblocks only.
    7070        uint32_t s_first_ino; // First non-reserved inode
    71         uint16_t s_inode_size; // Size of inode structure
     71        uint16_t inode_size; // Size of inode structure
    7272        uint16_t s_block_group_nr; // Block group number of this superblock
    7373        uint32_t features_compatible; // Compatible feature set
     
    147147extern uint32_t ext4_superblock_get_block_size(ext4_superblock_t *);
    148148extern uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *);
     149extern uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *);
     150extern uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *);
    149151extern uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *);
    150152extern uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *);
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rcfa1a8a r3711e7e  
    4242#include <malloc.h>
    4343#include <stdio.h>
     44#include <adt/hash_table.h>
    4445#include <ipc/loc.h>
    4546#include "ext4fs.h"
     
    4849#define EXT4FS_NODE(node)       ((node) ? (ext4fs_node_t *) (node)->data : NULL)
    4950#define EXT4FS_DBG(format, ...) {if (true) printf("ext4fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);}
     51
     52#define OPEN_NODES_KEYS 2
     53#define OPEN_NODES_DEV_HANDLE_KEY 0
     54#define OPEN_NODES_INODE_KEY 1
     55#define OPEN_NODES_BUCKETS 256
    5056
    5157typedef struct ext4fs_instance {
     
    96102static LIST_INITIALIZE(instance_list);
    97103static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex);
     104static hash_table_t open_nodes;
    98105static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
    99106
    100 
    101 /**
    102  *      TODO doxy
    103  */
     107/* Hash table interface for open nodes hash table */
     108static hash_index_t open_nodes_hash(unsigned long key[])
     109{
     110        /* TODO: This is very simple and probably can be improved */
     111        return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;
     112}
     113
     114static int open_nodes_compare(unsigned long key[], hash_count_t keys,
     115    link_t *item)
     116{
     117        ext4fs_node_t *enode = hash_table_get_instance(item, ext4fs_node_t, link);
     118        assert(keys > 0);
     119        if (enode->instance->service_id !=
     120            ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
     121                return false;
     122        }
     123        if (keys == 1) {
     124                return true;
     125        }
     126        assert(keys == 2);
     127        return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]);
     128}
     129
     130static void open_nodes_remove_cb(link_t *link)
     131{
     132        /* We don't use remove callback for this hash table */
     133}
     134
     135static hash_table_operations_t open_nodes_ops = {
     136        .hash = open_nodes_hash,
     137        .compare = open_nodes_compare,
     138        .remove_callback = open_nodes_remove_cb,
     139};
     140
     141
    104142int ext4fs_global_init(void)
    105143{
    106         // TODO
    107         return EOK;
    108 }
    109 
    110 /**
    111  * TODO doxy
    112  */
     144        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
     145            OPEN_NODES_KEYS, &open_nodes_ops)) {
     146                return ENOMEM;
     147        }
     148        return EOK;
     149}
     150
     151
    113152int ext4fs_global_fini(void)
    114153{
    115         // TODO
     154        hash_table_destroy(&open_nodes);
    116155        return EOK;
    117156}
     
    122161 */
    123162
    124 /**
    125  * TODO doxy
    126  */
    127163int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
    128164{
     165        EXT4FS_DBG("");
     166
    129167        ext4fs_instance_t *tmp;
    130168
    131169        fibril_mutex_lock(&instance_list_mutex);
     170
     171        EXT4FS_DBG("Checking lists");
    132172
    133173        if (list_empty(&instance_list)) {
     
    135175                return EINVAL;
    136176        }
     177
     178        EXT4FS_DBG("checked");
    137179
    138180        list_foreach(instance_list, link) {
     
    146188        }
    147189
     190        EXT4FS_DBG("Not found");
     191
    148192        fibril_mutex_unlock(&instance_list_mutex);
    149193        return EINVAL;
    150194}
    151195
    152 /**
    153  * TODO doxy
    154  */
     196
    155197int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
    156198{
     
    158200}
    159201
    160 /**
    161  * TODO doxy
    162  */
     202
    163203int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    164204{
     
    167207}
    168208
    169 /**
    170  * TODO doxy
    171  */
     209
    172210int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    173211{
     
    183221}
    184222
    185 /**
    186  * TODO doxy
    187  */
     223
    188224int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
    189225                fs_index_t index)
    190226{
    191         // TODO
    192         return EOK;
    193 }
    194 
    195 /**
    196  * TODO doxy
    197  */
     227
     228        int rc;
     229        fs_node_t *node = NULL;
     230        ext4fs_node_t *enode = NULL;
     231
     232        ext4_inode_ref_t *inode_ref = NULL;
     233
     234        fibril_mutex_lock(&open_nodes_lock);
     235
     236        /* Check if the node is not already open */
     237        unsigned long key[] = {
     238                [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
     239                [OPEN_NODES_INODE_KEY] = index,
     240        };
     241        link_t *already_open = hash_table_find(&open_nodes, key);
     242
     243        if (already_open) {
     244                enode = hash_table_get_instance(already_open, ext4fs_node_t, link);
     245                *rfn = enode->fs_node;
     246                enode->references++;
     247
     248                fibril_mutex_unlock(&open_nodes_lock);
     249                return EOK;
     250        }
     251
     252        enode = malloc(sizeof(ext4fs_node_t));
     253        if (enode == NULL) {
     254                fibril_mutex_unlock(&open_nodes_lock);
     255                return ENOMEM;
     256        }
     257
     258        node = malloc(sizeof(fs_node_t));
     259        if (node == NULL) {
     260                free(enode);
     261                fibril_mutex_unlock(&open_nodes_lock);
     262                return ENOMEM;
     263        }
     264        fs_node_initialize(node);
     265
     266        rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref);
     267        if (rc != EOK) {
     268                free(enode);
     269                free(node);
     270                fibril_mutex_unlock(&open_nodes_lock);
     271                return rc;
     272        }
     273
     274        enode->inode_ref = inode_ref;
     275        enode->instance = inst;
     276        enode->references = 1;
     277        enode->fs_node = node;
     278        link_initialize(&enode->link);
     279
     280        node->data = enode;
     281        *rfn = node;
     282
     283        hash_table_insert(&open_nodes, key, &enode->link);
     284        inst->open_nodes_count++;
     285
     286        fibril_mutex_unlock(&open_nodes_lock);
     287
     288        return EOK;
     289}
     290
     291
    198292int ext4fs_node_put_core(ext4fs_node_t *enode) {
    199293        // TODO
     
    201295}
    202296
    203 /**
    204  * TODO doxy
    205  */
     297
    206298int ext4fs_node_open(fs_node_t *fn)
    207299{
     
    233325}
    234326
     327
    235328int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
    236329{
     
    239332}
    240333
     334
    241335int ext4fs_destroy_node(fs_node_t *fn)
    242336{
     
    245339}
    246340
     341
    247342int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    248343{
     
    251346}
    252347
     348
    253349int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
    254350{
     
    257353}
    258354
     355
    259356int ext4fs_has_children(bool *has_children, fs_node_t *fn)
    260357{
     
    270367}
    271368
     369
    272370aoff64_t ext4fs_size_get(fs_node_t *fn)
    273371{
     
    276374}
    277375
     376
    278377unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
    279378{
     
    282381}
    283382
     383
    284384bool ext4fs_is_directory(fs_node_t *fn)
    285385{
     
    288388}
    289389
     390
    290391bool ext4fs_is_file(fs_node_t *fn)
    291392{
     
    293394        return false;
    294395}
     396
    295397
    296398service_id_t ext4fs_service_get(fs_node_t *fn)
     
    327429 */
    328430
    329 /**
    330  * TODO doxy
    331  */
    332431static int ext4fs_mounted(service_id_t service_id, const char *opts,
    333432   fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
    334433{
    335 
    336         EXT4FS_DBG("Mounting...");
    337434
    338435        int rc;
     
    353450                return ENOMEM;
    354451        }
    355 
    356         EXT4FS_DBG("Basic structures allocated");
    357452
    358453        /* Initialize the filesystem */
     
    363458                return rc;
    364459        }
    365 
    366         EXT4FS_DBG("initialized");
    367460
    368461        /* Do some sanity checking */
     
    375468        }
    376469
    377         EXT4FS_DBG("Checked and clean");
    378 
    379470        /* Check flags */
    380471        rc = ext4_filesystem_check_features(fs, &read_only);
     
    386477        }
    387478
    388         EXT4FS_DBG("Features checked");
    389 
    390479        /* Initialize instance */
    391480        link_initialize(&inst->link);
     
    394483        inst->open_nodes_count = 0;
    395484
    396         EXT4FS_DBG("Instance initialized");
    397 
    398485        /* Read root node */
    399486        fs_node_t *root_node;
    400         rc = ext4fs_root_get(&root_node, inst->service_id);
     487        rc = ext4fs_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
    401488        if (rc != EOK) {
    402489                ext4_filesystem_fini(fs);
     
    407494        ext4fs_node_t *enode = EXT4FS_NODE(root_node);
    408495
    409         EXT4FS_DBG("Root node found");
    410 
    411496        /* Add instance to the list */
    412497        fibril_mutex_lock(&instance_list_mutex);
     
    414499        fibril_mutex_unlock(&instance_list_mutex);
    415500
    416         EXT4FS_DBG("Instance added");
    417 
    418501        *index = EXT4_INODE_ROOT_INDEX;
    419502        *size = 0;
    420503        *lnkcnt = ext4_inode_get_usage_count(enode->inode_ref->inode);
    421504
    422         EXT4FS_DBG("Return values set");
    423 
    424505        ext4fs_node_put(root_node);
    425506
    426         EXT4FS_DBG("Mounting finished");
    427 
    428         return EOK;
    429 }
    430 
    431 /**
    432  * TODO doxy
    433  */
     507        return EOK;
     508}
     509
     510
    434511static int ext4fs_unmounted(service_id_t service_id)
    435512{
     
    463540}
    464541
    465 /**
    466  * TODO doxy
    467  */
     542
    468543static int
    469544ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
     
    474549}
    475550
    476 /**
    477  * TODO doxy
    478  */
     551
    479552static int
    480553ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
     
    485558}
    486559
    487 /**
    488  * TODO doxy
    489  */
     560
    490561static int
    491562ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
     
    495566}
    496567
    497 /**
    498  * TODO doxy
    499  */
     568
    500569static int ext4fs_close(service_id_t service_id, fs_index_t index)
    501570{
     
    504573}
    505574
    506 /**
    507  * TODO doxy
    508  */
     575
    509576static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
    510577{
     
    513580}
    514581
    515 /**
    516  * TODO doxy
    517  */
     582
    518583static int ext4fs_sync(service_id_t service_id, fs_index_t index)
    519584{
Note: See TracChangeset for help on using the changeset viewer.