Changeset 3711e7e in mainline for uspace/srv/fs/ext4fs/ext4fs_ops.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/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.