Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 0003e0f5 in mainline


Ignore:
Timestamp:
2014-08-07T15:29:11Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
993d608
Parents:
d4b63fa
Message:

Add CDFS filesystem state structure.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/cdfs/cdfs_ops.c

    rd4b63fa r0003e0f5  
    3939#include "cdfs_ops.h"
    4040#include <stdbool.h>
     41#include <adt/list.h>
    4142#include <adt/hash_table.h>
    4243#include <adt/hash.h>
     
    195196typedef uint32_t cdfs_lba_t;
    196197
     198/** Mounted CDFS filesystem */
     199typedef struct {
     200        link_t link;
     201        service_id_t service_id;  /**< Service ID of block device */
     202} cdfs_t;
     203
    197204typedef struct {
    198205        fs_node_t *fs_node;       /**< FS node */
    199206        fs_index_t index;         /**< Node index */
    200         service_id_t service_id;  /**< Service ID of block device */
     207        cdfs_t *fs;               /**< File system */
    201208       
    202209        ht_link_t nh_link;        /**< Nodes hash table link */
     
    212219} cdfs_node_t;
    213220
     221/** List of all instances */
     222static LIST_INITIALIZE(cdfs_instances);
     223
    214224/** Shared index of nodes */
    215225static fs_index_t cdfs_index = 1;
     
    239249{
    240250        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    241         return hash_combine(node->service_id, node->index);
     251        return hash_combine(node->fs->service_id, node->index);
    242252}
    243253
     
    247257        ht_key_t *key = (ht_key_t*)k;
    248258       
    249         return key->service_id == node->service_id && key->index == node->index;
     259        return key->service_id == node->fs->service_id && key->index == node->index;
    250260}
    251261
     
    305315        node->fs_node = NULL;
    306316        node->index = 0;
    307         node->service_id = 0;
     317        node->fs = NULL;
    308318        node->type = CDFS_NONE;
    309319        node->lnkcnt = 0;
     
    316326}
    317327
    318 static int create_node(fs_node_t **rfn, service_id_t service_id, int lflag,
     328static int create_node(fs_node_t **rfn, cdfs_t *fs, int lflag,
    319329    fs_index_t index)
    320330{
     
    337347       
    338348        fs_node_t *rootfn;
    339         int rc = cdfs_root_get(&rootfn, service_id);
     349        int rc = cdfs_root_get(&rootfn, fs->service_id);
    340350       
    341351        assert(rc == EOK);
     
    346356                node->index = index;
    347357       
    348         node->service_id = service_id;
     358        node->fs = fs;
    349359       
    350360        if (lflag & L_DIRECTORY)
     
    436446}
    437447
    438 static bool cdfs_readdir(service_id_t service_id, fs_node_t *fs_node)
     448static bool cdfs_readdir(cdfs_t *fs, fs_node_t *fs_node)
    439449{
    440450        cdfs_node_t *node = CDFS_NODE(fs_node);
     
    450460        for (uint32_t i = 0; i < blocks; i++) {
    451461                block_t *block;
    452                 int rc = block_get(&block, service_id, node->lba + i, BLOCK_FLAGS_NONE);
     462                int rc = block_get(&block, fs->service_id, node->lba + i, BLOCK_FLAGS_NONE);
    453463                if (rc != EOK)
    454464                        return false;
     
    484494                       
    485495                        fs_node_t *fn;
    486                         int rc = create_node(&fn, service_id, dentry_type,
     496                        int rc = create_node(&fn, fs, dentry_type,
    487497                            (node->lba + i) * BLOCK_SIZE + offset);
    488498                        if ((rc != EOK) || (fn == NULL))
     
    514524}
    515525
    516 static fs_node_t *get_uncached_node(service_id_t service_id, fs_index_t index)
     526static fs_node_t *get_uncached_node(cdfs_t *fs, fs_index_t index)
    517527{
    518528        cdfs_lba_t lba = index / BLOCK_SIZE;
     
    520530       
    521531        block_t *block;
    522         int rc = block_get(&block, service_id, lba, BLOCK_FLAGS_NONE);
     532        int rc = block_get(&block, fs->service_id, lba, BLOCK_FLAGS_NONE);
    523533        if (rc != EOK)
    524534                return NULL;
     
    533543       
    534544        fs_node_t *fn;
    535         rc = create_node(&fn, service_id, dentry_type, index);
     545        rc = create_node(&fn, fs, dentry_type, index);
    536546        if ((rc != EOK) || (fn == NULL))
    537547                return NULL;
     
    549559}
    550560
    551 static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index)
     561static fs_node_t *get_cached_node(cdfs_t *fs, fs_index_t index)
    552562{
    553563        ht_key_t key = {
    554564                .index = index,
    555                 .service_id = service_id
     565                .service_id = fs->service_id
    556566        };
    557567       
     
    563573        }
    564574       
    565         return get_uncached_node(service_id, index);
     575        return get_uncached_node(fs, index);
    566576}
    567577
     
    571581       
    572582        if (!parent->processed) {
    573                 int rc = cdfs_readdir(parent->service_id, pfn);
     583                int rc = cdfs_readdir(parent->fs, pfn);
    574584                if (rc != EOK)
    575585                        return rc;
     
    578588        list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
    579589                if (str_cmp(dentry->name, component) == 0) {
    580                         *fn = get_cached_node(parent->service_id, dentry->index);
     590                        *fn = get_cached_node(parent->fs, dentry->index);
    581591                        return EOK;
    582592                }
     
    592602       
    593603        if (!node->processed)
    594                 cdfs_readdir(node->service_id, fn);
     604                cdfs_readdir(node->fs, fn);
    595605       
    596606        node->opened++;
     
    633643       
    634644        if ((node->type == CDFS_DIRECTORY) && (!node->processed))
    635                 cdfs_readdir(node->service_id, fn);
     645                cdfs_readdir(node->fs, fn);
    636646       
    637647        *has_children = !list_empty(&node->cs_list);
     
    717727};
    718728
    719 static bool iso_readfs(service_id_t service_id, fs_node_t *rfn,
     729static bool iso_readfs(cdfs_t *fs, fs_node_t *rfn,
    720730    cdfs_lba_t altroot)
    721731{
    722732        /* First 16 blocks of isofs are empty */
    723733        block_t *block;
    724         int rc = block_get(&block, service_id, altroot + 16, BLOCK_FLAGS_NONE);
     734        int rc = block_get(&block, fs->service_id, altroot + 16, BLOCK_FLAGS_NONE);
    725735        if (rc != EOK)
    726736                return false;
     
    771781        node->size = uint32_lb(vol_desc->data.primary.root_dir.size);
    772782       
    773         if (!cdfs_readdir(service_id, rfn)) {
     783        if (!cdfs_readdir(fs, rfn)) {
    774784                block_put(block);
    775785                return false;
     
    783793 *
    784794 */
    785 static bool cdfs_instance_init(service_id_t service_id, cdfs_lba_t altroot)
    786 {
     795static cdfs_t *cdfs_fs_create(service_id_t sid, cdfs_lba_t altroot)
     796{
     797        cdfs_t *fs = NULL;
     798        fs_node_t *rfn = NULL;
     799
     800        fs = calloc(1, sizeof(cdfs_t));
     801        if (fs == NULL)
     802                goto error;
     803
     804        fs->service_id = sid;
     805
    787806        /* Create root node */
    788         fs_node_t *rfn;
    789         int rc = create_node(&rfn, service_id, L_DIRECTORY, cdfs_index++);
     807        int rc = create_node(&rfn, fs, L_DIRECTORY, cdfs_index++);
    790808       
    791809        if ((rc != EOK) || (!rfn))
    792                 return false;
     810                goto error;
    793811       
    794812        /* FS root is not linked */
     
    798816       
    799817        /* Check if there is cdfs in given session */
    800         if (!iso_readfs(service_id, rfn, altroot)) {
    801                 // XXX destroy node
    802                 return false;
    803         }
    804        
    805         return true;
     818        if (!iso_readfs(fs, rfn, altroot))
     819                goto error;
     820       
     821        list_append(&fs->link, &cdfs_instances);
     822        return fs;
     823error:
     824        // XXX destroy node
     825        free(fs);
     826        return NULL;
    806827}
    807828
     
    847868        }
    848869       
    849         /* Initialize cdfs instance */
    850         if (!cdfs_instance_init(service_id, altroot)) {
     870        /* Create cdfs instance */
     871        if (cdfs_fs_create(service_id, altroot) == NULL) {
    851872                block_cache_fini(service_id);
    852873                block_fini(service_id);
     
    871892        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    872893       
    873         if (node->service_id == service_id) {
     894        if (node->fs->service_id == service_id) {
    874895                hash_table_remove_item(&nodes, &node->nh_link);
    875896        }
     
    878899}
    879900
    880 static void cdfs_instance_done(service_id_t service_id)
    881 {
    882         hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
    883         block_cache_fini(service_id);
    884         block_fini(service_id);
     901static void cdfs_fs_destroy(cdfs_t *fs)
     902{
     903        list_remove(&fs->link);
     904        hash_table_apply(&nodes, rm_service_id_nodes, &fs->service_id);
     905        block_cache_fini(fs->service_id);
     906        block_fini(fs->service_id);
     907        free(fs);
     908}
     909
     910static cdfs_t *cdfs_find_by_sid(service_id_t service_id)
     911{
     912        list_foreach(cdfs_instances, link, cdfs_t, fs) {
     913                if (fs->service_id == service_id)
     914                        return fs;
     915        }
     916       
     917        return NULL;
    885918}
    886919
    887920static int cdfs_unmounted(service_id_t service_id)
    888921{
    889         cdfs_instance_done(service_id);
     922        cdfs_t *fs;
     923
     924        fs = cdfs_find_by_sid(service_id);
     925        if (fs == NULL)
     926                return ENOENT;
     927
     928        cdfs_fs_destroy(fs);
    890929        return EOK;
    891930}
     
    907946       
    908947        if (!node->processed) {
    909                 int rc = cdfs_readdir(service_id, FS_NODE(node));
     948                int rc = cdfs_readdir(node->fs, FS_NODE(node));
    910949                if (rc != EOK)
    911950                        return rc;
Note: See TracChangeset for help on using the changeset viewer.