Ignore:
File:
1 edited

Legend:

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

    r44ecf89 rfc22069  
    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>
     
    4748#include <errno.h>
    4849#include <block.h>
     50#include <scsi/mmc.h>
    4951#include <str.h>
    5052#include <byteorder.h>
     
    6567
    6668#define CDFS_STANDARD_IDENT  "CD001"
     69
     70enum {
     71        CDFS_NAME_CURDIR = '\x00',
     72        CDFS_NAME_PARENTDIR = '\x01'
     73};
    6774
    6875typedef enum {
     
    126133
    127134typedef struct {
    128         uint8_t res0;
     135        uint8_t flags; /* reserved in primary */
    129136       
    130137        uint8_t system_ident[32];
     
    134141        uint32_t_lb lba_size;
    135142       
    136         uint8_t res2[32];
     143        uint8_t esc_seq[32]; /* reserved in primary */
    137144        uint16_t_lb set_size;
    138145        uint16_t_lb sequence_nr;
     
    164171       
    165172        uint8_t fs_version;
    166 } __attribute__((packed)) cdfs_vol_desc_primary_t;
     173} __attribute__((packed)) cdfs_vol_desc_prisec_t;
    167174
    168175typedef struct {
     
    172179        union {
    173180                cdfs_vol_desc_boot_t boot;
    174                 cdfs_vol_desc_primary_t primary;
     181                cdfs_vol_desc_prisec_t prisec;
    175182        } data;
    176183} __attribute__((packed)) cdfs_vol_desc_t;
     184
     185typedef enum {
     186        /** ASCII character set / encoding (base ISO 9660) */
     187        enc_ascii,
     188        /** UCS-2 character set / encoding (Joliet) */
     189        enc_ucs2
     190} cdfs_enc_t;
    177191
    178192typedef enum {
     
    191205
    192206typedef struct {
     207        link_t link;              /**< Link to list of all instances */
     208        service_id_t service_id;  /**< Service ID of block device */
     209        cdfs_enc_t enc;           /**< Filesystem string encoding */
     210} cdfs_t;
     211
     212typedef struct {
    193213        fs_node_t *fs_node;       /**< FS node */
    194214        fs_index_t index;         /**< Node index */
    195         service_id_t service_id;  /**< Service ID of block device */
     215        cdfs_t *fs;               /**< File system */
    196216       
    197217        ht_link_t nh_link;        /**< Nodes hash table link */
     
    207227} cdfs_node_t;
    208228
     229/** String encoding */
     230enum {
     231        /** ASCII - standard ISO 9660 */
     232        ucs2_esc_seq_no = 3,
     233        /** USC-2 - Joliet */
     234        ucs2_esc_seq_len = 3
     235};
     236
     237/** Joliet SVD UCS-2 escape sequences */
     238static uint8_t ucs2_esc_seq[ucs2_esc_seq_no][ucs2_esc_seq_len] = {
     239        { 0x25, 0x2f, 0x40 },
     240        { 0x25, 0x2f, 0x43 },
     241        { 0x25, 0x2f, 0x45 }
     242};
     243
     244/** List of all instances */
     245static LIST_INITIALIZE(cdfs_instances);
     246
    209247/** Shared index of nodes */
    210248static fs_index_t cdfs_index = 1;
     
    234272{
    235273        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    236         return hash_combine(node->service_id, node->index);
     274        return hash_combine(node->fs->service_id, node->index);
    237275}
    238276
     
    242280        ht_key_t *key = (ht_key_t*)k;
    243281       
    244         return key->service_id == node->service_id && key->index == node->index;
     282        return key->service_id == node->fs->service_id && key->index == node->index;
    245283}
    246284
     
    249287        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    250288       
    251         assert(node->type == CDFS_DIRECTORY);
    252        
    253         link_t *link;
    254         while ((link = list_first(&node->cs_list)) != NULL) {
    255                 cdfs_dentry_t *dentry = list_get_instance(link, cdfs_dentry_t, link);
    256                 list_remove(&dentry->link);
    257                 free(dentry);
     289        if (node->type == CDFS_DIRECTORY) {
     290                link_t *link;
     291                while ((link = list_first(&node->cs_list)) != NULL) {
     292                        cdfs_dentry_t *dentry = list_get_instance(link, cdfs_dentry_t, link);
     293                        list_remove(&dentry->link);
     294                        free(dentry);
     295                }
    258296        }
    259297       
     
    300338        node->fs_node = NULL;
    301339        node->index = 0;
    302         node->service_id = 0;
     340        node->fs = NULL;
    303341        node->type = CDFS_NONE;
    304342        node->lnkcnt = 0;
     
    311349}
    312350
    313 static int create_node(fs_node_t **rfn, service_id_t service_id, int lflag,
     351static int create_node(fs_node_t **rfn, cdfs_t *fs, int lflag,
    314352    fs_index_t index)
    315353{
     
    332370       
    333371        fs_node_t *rootfn;
    334         int rc = cdfs_root_get(&rootfn, service_id);
     372        int rc = cdfs_root_get(&rootfn, fs->service_id);
    335373       
    336374        assert(rc == EOK);
     
    341379                node->index = index;
    342380       
    343         node->service_id = service_id;
     381        node->fs = fs;
    344382       
    345383        if (lflag & L_DIRECTORY)
     
    365403       
    366404        /* Check for duplicate entries */
    367         list_foreach(parent->cs_list, link) {
    368                 cdfs_dentry_t *dentry =
    369                     list_get_instance(link, cdfs_dentry_t, link);
    370                
     405        list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
    371406                if (str_cmp(dentry->name, name) == 0)
    372407                        return EEXIST;
     
    394429}
    395430
    396 static bool cdfs_readdir(service_id_t service_id, fs_node_t *fs_node)
     431/** Decode CDFS string.
     432 *
     433 * @param data  Pointer to string data
     434 * @param dsize Size of data in bytes
     435 * @param enc   String encoding
     436 * @return      Decoded string
     437 */
     438static char *cdfs_decode_str(void *data, size_t dsize, cdfs_enc_t enc)
     439{
     440        int rc;
     441        char *str;
     442        uint16_t *buf;
     443       
     444        switch (enc) {
     445        case enc_ascii:
     446                str = malloc(dsize + 1);
     447                if (str == NULL)
     448                        return NULL;
     449                memcpy(str, data, dsize);
     450                str[dsize] = '\0';
     451                break;
     452        case enc_ucs2:
     453                buf = calloc(dsize + 2, 1);
     454                if (buf == NULL)
     455                        return NULL;
     456               
     457                size_t i;
     458                for (i = 0; i < dsize / sizeof(uint16_t); i++) {
     459                        buf[i] = uint16_t_be2host(((uint16_t *)data)[i]);
     460                }
     461               
     462                size_t dstr_size = dsize / sizeof(uint16_t) * 4 + 1;
     463                str = malloc(dstr_size);
     464                if (str == NULL)
     465                        return NULL;
     466               
     467                rc = utf16_to_str(str, dstr_size, buf);
     468                free(buf);
     469               
     470                if (rc != EOK)
     471                        return NULL;
     472                break;
     473        default:
     474                assert(false);
     475                str = NULL;
     476        }
     477       
     478        return str;
     479}
     480
     481/** Decode file name.
     482 *
     483 * @param data  File name buffer
     484 * @param dsize Fine name buffer size
     485 * @param dtype Directory entry type
     486 * @return      Decoded file name (allocated string)
     487 */
     488static char *cdfs_decode_name(void *data, size_t dsize, cdfs_enc_t enc,
     489    cdfs_dentry_type_t dtype)
     490{
     491        char *name;
     492        char *dot;
     493        char *scolon;
     494       
     495        name = cdfs_decode_str(data, dsize, enc);
     496        if (name == NULL)
     497                return NULL;
     498       
     499        if (dtype == CDFS_DIRECTORY)
     500                return name;
     501       
     502        dot = str_chr(name, '.');
     503       
     504        if (dot != NULL) {
     505                scolon = str_chr(dot, ';');
     506                if (scolon != NULL) {
     507                        /* Trim version part */
     508                        *scolon = '\0';
     509                }
     510       
     511                /* If the extension is an empty string, trim the dot separator. */
     512                if (dot[1] == '\0')
     513                        *dot = '\0';
     514        }
     515       
     516        return name;
     517}
     518
     519static bool cdfs_readdir(cdfs_t *fs, fs_node_t *fs_node)
    397520{
    398521        cdfs_node_t *node = CDFS_NODE(fs_node);
     
    408531        for (uint32_t i = 0; i < blocks; i++) {
    409532                block_t *block;
    410                 int rc = block_get(&block, service_id, node->lba + i, BLOCK_FLAGS_NONE);
     533                int rc = block_get(&block, fs->service_id, node->lba + i, BLOCK_FLAGS_NONE);
    411534                if (rc != EOK)
    412535                        return false;
    413536               
    414                 cdfs_dir_t *dir = (cdfs_dir_t *) block->data;
    415                
    416                 // FIXME: skip '.' and '..'
    417                
    418                 for (size_t offset = 0;
    419                     (dir->length != 0) && (offset < BLOCK_SIZE);
     537                cdfs_dir_t *dir;
     538               
     539                for (size_t offset = 0; offset < BLOCK_SIZE;
    420540                    offset += dir->length) {
    421541                        dir = (cdfs_dir_t *) (block->data + offset);
     542                        if (dir->length == 0)
     543                                break;
     544                        if (offset + dir->length > BLOCK_SIZE) {
     545                                /* XXX Incorrect FS structure */
     546                                break;
     547                        }
    422548                       
    423549                        cdfs_dentry_type_t dentry_type;
     
    427553                                dentry_type = CDFS_FILE;
    428554                       
     555                        /* Skip special entries */
     556                       
     557                        if (dir->name_length == 1 &&
     558                            dir->name[0] == CDFS_NAME_CURDIR)
     559                                continue;
     560                        if (dir->name_length == 1 &&
     561                            dir->name[0] == CDFS_NAME_PARENTDIR)
     562                                continue;
     563                       
    429564                        // FIXME: hack - indexing by dentry byte offset on disc
    430565                       
    431566                        fs_node_t *fn;
    432                         int rc = create_node(&fn, service_id, dentry_type,
     567                        int rc = create_node(&fn, fs, dentry_type,
    433568                            (node->lba + i) * BLOCK_SIZE + offset);
    434569                        if ((rc != EOK) || (fn == NULL))
     
    439574                        cur->size = uint32_lb(dir->size);
    440575                       
    441                         char *name = (char *) malloc(dir->name_length + 1);
     576                        char *name = cdfs_decode_name(dir->name,
     577                            dir->name_length, node->fs->enc, dentry_type);
    442578                        if (name == NULL)
    443579                                return false;
    444                        
    445                         memcpy(name, dir->name, dir->name_length);
    446                         name[dir->name_length] = 0;
    447580                       
    448581                        // FIXME: check return value
     
    462595}
    463596
    464 static fs_node_t *get_uncached_node(service_id_t service_id, fs_index_t index)
     597static fs_node_t *get_uncached_node(cdfs_t *fs, fs_index_t index)
    465598{
    466599        cdfs_lba_t lba = index / BLOCK_SIZE;
     
    468601       
    469602        block_t *block;
    470         int rc = block_get(&block, service_id, lba, BLOCK_FLAGS_NONE);
     603        int rc = block_get(&block, fs->service_id, lba, BLOCK_FLAGS_NONE);
    471604        if (rc != EOK)
    472605                return NULL;
     
    481614       
    482615        fs_node_t *fn;
    483         rc = create_node(&fn, service_id, dentry_type, index);
     616        rc = create_node(&fn, fs, dentry_type, index);
    484617        if ((rc != EOK) || (fn == NULL))
    485618                return NULL;
     
    497630}
    498631
    499 static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index)
     632static fs_node_t *get_cached_node(cdfs_t *fs, fs_index_t index)
    500633{
    501634        ht_key_t key = {
    502635                .index = index,
    503                 .service_id = service_id
     636                .service_id = fs->service_id
    504637        };
    505638       
     
    511644        }
    512645       
    513         return get_uncached_node(service_id, index);
     646        return get_uncached_node(fs, index);
    514647}
    515648
     
    519652       
    520653        if (!parent->processed) {
    521                 int rc = cdfs_readdir(parent->service_id, pfn);
     654                int rc = cdfs_readdir(parent->fs, pfn);
    522655                if (rc != EOK)
    523656                        return rc;
    524657        }
    525658       
    526         list_foreach(parent->cs_list, link) {
    527                 cdfs_dentry_t *dentry =
    528                     list_get_instance(link, cdfs_dentry_t, link);
    529                
     659        list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
    530660                if (str_cmp(dentry->name, component) == 0) {
    531                         *fn = get_cached_node(parent->service_id, dentry->index);
     661                        *fn = get_cached_node(parent->fs, dentry->index);
    532662                        return EOK;
    533663                }
     
    543673       
    544674        if (!node->processed)
    545                 cdfs_readdir(node->service_id, fn);
     675                cdfs_readdir(node->fs, fn);
    546676       
    547677        node->opened++;
     
    584714       
    585715        if ((node->type == CDFS_DIRECTORY) && (!node->processed))
    586                 cdfs_readdir(node->service_id, fn);
     716                cdfs_readdir(node->fs, fn);
    587717       
    588718        *has_children = !list_empty(&node->cs_list);
     
    623753{
    624754        return 0;
     755}
     756
     757static int cdfs_size_block(service_id_t service_id, uint32_t *size)
     758{
     759        *size = BLOCK_SIZE;
     760       
     761        return EOK;
     762}
     763
     764static int cdfs_total_block_count(service_id_t service_id, uint64_t *count)
     765{
     766        *count = 0;
     767       
     768        return EOK;
     769}
     770
     771static int cdfs_free_block_count(service_id_t service_id, uint64_t *count)
     772{
     773        *count = 0;
     774       
     775        return EOK;
    625776}
    626777
     
    641792        .is_directory = cdfs_is_directory,
    642793        .is_file = cdfs_is_file,
    643         .service_get = cdfs_service_get
     794        .service_get = cdfs_service_get,
     795        .size_block = cdfs_size_block,
     796        .total_block_count = cdfs_total_block_count,
     797        .free_block_count = cdfs_free_block_count
    644798};
    645799
    646 static bool iso_readfs(service_id_t service_id, fs_node_t *rfn,
     800/** Verify that escape sequence corresonds to one of the allowed encoding
     801 * escape sequences allowed for Joliet. */
     802static int cdfs_verify_joliet_esc_seq(uint8_t *seq)
     803{
     804        size_t i, j, k;
     805        bool match;
     806       
     807        i = 0;
     808        while (i + ucs2_esc_seq_len <= 32) {
     809                if (seq[i] == 0)
     810                        break;
     811               
     812                for (j = 0; j < ucs2_esc_seq_no; j++) {
     813                        match = true;
     814                        for (k = 0; k < ucs2_esc_seq_len; k++)
     815                                if (seq[i + k] != ucs2_esc_seq[j][k])
     816                                        match = false;
     817                        if (match) {
     818                                break;
     819                        }
     820                }
     821               
     822                if (!match)
     823                        return EINVAL;
     824               
     825                i += ucs2_esc_seq_len;
     826        }
     827       
     828        while (i < 32) {
     829                if (seq[i] != 0)
     830                        return EINVAL;
     831                ++i;
     832        }
     833       
     834        return EOK;
     835}
     836
     837/** Find Joliet supplementary volume descriptor.
     838 *
     839 * @param sid           Block device service ID
     840 * @param altroot       First filesystem block
     841 * @param rlba          Place to store LBA of root dir
     842 * @param rsize         Place to store size of root dir
     843 * @return              EOK if found, ENOENT if not
     844 */
     845static int cdfs_find_joliet_svd(service_id_t sid, cdfs_lba_t altroot,
     846    uint32_t *rlba, uint32_t *rsize)
     847{
     848        cdfs_lba_t bi;
     849
     850        for (bi = altroot + 17; ; bi++) {
     851                block_t *block;
     852                int rc = block_get(&block, sid, bi, BLOCK_FLAGS_NONE);
     853                if (rc != EOK)
     854                        break;
     855               
     856                cdfs_vol_desc_t *vol_desc = (cdfs_vol_desc_t *) block->data;
     857               
     858                if (vol_desc->type == VOL_DESC_SET_TERMINATOR) {
     859                        block_put(block);
     860                        break;
     861                }
     862               
     863                if ((vol_desc->type != VOL_DESC_SUPPLEMENTARY) ||
     864                    (memcmp(vol_desc->standard_ident, CDFS_STANDARD_IDENT, 5) != 0) ||
     865                    (vol_desc->version != 1)) {
     866                        block_put(block);
     867                        continue;
     868                }
     869               
     870                uint16_t set_size = uint16_lb(vol_desc->data.prisec.set_size);
     871                if (set_size > 1) {
     872                        /*
     873                         * Technically, we don't support multi-disc sets.
     874                         * But one can encounter erroneously mastered
     875                         * images in the wild and it might actually work
     876                         * for the first disc in the set.
     877                         */
     878                }
     879               
     880                uint16_t sequence_nr = uint16_lb(vol_desc->data.prisec.sequence_nr);
     881                if (sequence_nr != 1) {
     882                        /*
     883                         * We only support the first disc
     884                         * in multi-disc sets.
     885                         */
     886                        block_put(block);
     887                        continue;
     888                }
     889               
     890                uint16_t block_size = uint16_lb(vol_desc->data.prisec.block_size);
     891                if (block_size != BLOCK_SIZE) {
     892                        block_put(block);
     893                        continue;
     894                }
     895               
     896                rc = cdfs_verify_joliet_esc_seq(vol_desc->data.prisec.esc_seq);
     897                if (rc != EOK)
     898                        continue;
     899                *rlba = uint32_lb(vol_desc->data.prisec.root_dir.lba);
     900                *rsize = uint32_lb(vol_desc->data.prisec.root_dir.size);
     901                block_put(block);
     902                return EOK;
     903        }
     904       
     905        return ENOENT;
     906}
     907
     908static bool iso_readfs(cdfs_t *fs, fs_node_t *rfn,
    647909    cdfs_lba_t altroot)
    648910{
    649911        /* First 16 blocks of isofs are empty */
    650912        block_t *block;
    651         int rc = block_get(&block, service_id, altroot + 16, BLOCK_FLAGS_NONE);
     913        int rc = block_get(&block, fs->service_id, altroot + 16, BLOCK_FLAGS_NONE);
    652914        if (rc != EOK)
    653915                return false;
     
    666928        }
    667929       
    668         uint16_t set_size = uint16_lb(vol_desc->data.primary.set_size);
     930        uint16_t set_size = uint16_lb(vol_desc->data.prisec.set_size);
    669931        if (set_size > 1) {
    670932                /*
     
    676938        }
    677939       
    678         uint16_t sequence_nr = uint16_lb(vol_desc->data.primary.sequence_nr);
     940        uint16_t sequence_nr = uint16_lb(vol_desc->data.prisec.sequence_nr);
    679941        if (sequence_nr != 1) {
    680942                /*
     
    686948        }
    687949       
    688         uint16_t block_size = uint16_lb(vol_desc->data.primary.block_size);
     950        uint16_t block_size = uint16_lb(vol_desc->data.prisec.block_size);
    689951        if (block_size != BLOCK_SIZE) {
    690952                block_put(block);
     
    695957       
    696958        cdfs_node_t *node = CDFS_NODE(rfn);
    697         node->lba = uint32_lb(vol_desc->data.primary.root_dir.lba);
    698         node->size = uint32_lb(vol_desc->data.primary.root_dir.size);
    699        
    700         if (!cdfs_readdir(service_id, rfn)) {
     959       
     960        /* Search for Joliet SVD */
     961       
     962        uint32_t jrlba;
     963        uint32_t jrsize;
     964       
     965        rc = cdfs_find_joliet_svd(fs->service_id, altroot, &jrlba, &jrsize);
     966        if (rc == EOK) {
     967                /* Found */
     968                node->lba = jrlba;
     969                node->size = jrsize;
     970                fs->enc = enc_ucs2;
     971        } else {
     972                node->lba = uint32_lb(vol_desc->data.prisec.root_dir.lba);
     973                node->size = uint32_lb(vol_desc->data.prisec.root_dir.size);
     974                fs->enc = enc_ascii;
     975        }
     976       
     977        if (!cdfs_readdir(fs, rfn)) {
    701978                block_put(block);
    702979                return false;
     
    710987 *
    711988 */
    712 static bool cdfs_instance_init(service_id_t service_id, cdfs_lba_t altroot)
    713 {
     989static cdfs_t *cdfs_fs_create(service_id_t sid, cdfs_lba_t altroot)
     990{
     991        cdfs_t *fs = NULL;
     992        fs_node_t *rfn = NULL;
     993
     994        fs = calloc(1, sizeof(cdfs_t));
     995        if (fs == NULL)
     996                goto error;
     997       
     998        fs->service_id = sid;
     999       
    7141000        /* Create root node */
    715         fs_node_t *rfn;
    716         int rc = create_node(&rfn, service_id, L_DIRECTORY, cdfs_index++);
     1001        int rc = create_node(&rfn, fs, L_DIRECTORY, cdfs_index++);
    7171002       
    7181003        if ((rc != EOK) || (!rfn))
    719                 return false;
     1004                goto error;
    7201005       
    7211006        /* FS root is not linked */
     
    7251010       
    7261011        /* Check if there is cdfs in given session */
    727         if (!iso_readfs(service_id, rfn, altroot)) {
    728                 // XXX destroy node
    729                 return false;
    730         }
    731        
    732         return true;
     1012        if (!iso_readfs(fs, rfn, altroot))
     1013                goto error;
     1014       
     1015        list_append(&fs->link, &cdfs_instances);
     1016        return fs;
     1017error:
     1018        // XXX destroy node
     1019        free(fs);
     1020        return NULL;
    7331021}
    7341022
     
    7371025{
    7381026        /* Initialize the block layer */
    739         int rc = block_init(EXCHANGE_SERIALIZE, service_id, BLOCK_SIZE);
     1027        int rc = block_init(service_id, BLOCK_SIZE);
    7401028        if (rc != EOK)
    7411029                return rc;
     
    7481036                        altroot = 0;
    7491037        } else {
    750                 /* Read TOC and find the last session */
    751                 toc_block_t *toc = block_get_toc(service_id, 1);
    752                 if ((toc != NULL) && (uint16_t_be2host(toc->size) == 10)) {
    753                         altroot = uint32_t_be2host(toc->first_lba);
    754                         free(toc);
    755                 }
     1038                /*
     1039                 * Read TOC multisession information and get the start address
     1040                 * of the first track in the last session
     1041                 */
     1042                scsi_toc_multisess_data_t toc;
     1043
     1044                rc = block_read_toc(service_id, 1, &toc, sizeof(toc));
     1045                if (rc == EOK && (uint16_t_be2host(toc.toc_len) == 10))
     1046                        altroot = uint32_t_be2host(toc.ftrack_lsess.start_addr);
    7561047        }
    7571048       
     
    7741065        }
    7751066       
    776         /* Initialize cdfs instance */
    777         if (!cdfs_instance_init(service_id, altroot)) {
     1067        /* Create cdfs instance */
     1068        if (cdfs_fs_create(service_id, altroot) == NULL) {
    7781069                block_cache_fini(service_id);
    7791070                block_fini(service_id);
     
    7981089        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    7991090       
    800         if (node->service_id == service_id) {
     1091        if (node->fs->service_id == service_id) {
    8011092                hash_table_remove_item(&nodes, &node->nh_link);
    8021093        }
     
    8051096}
    8061097
    807 static void cdfs_instance_done(service_id_t service_id)
    808 {
    809         hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
    810         block_cache_fini(service_id);
    811         block_fini(service_id);
     1098static void cdfs_fs_destroy(cdfs_t *fs)
     1099{
     1100        list_remove(&fs->link);
     1101        hash_table_apply(&nodes, rm_service_id_nodes, &fs->service_id);
     1102        block_cache_fini(fs->service_id);
     1103        block_fini(fs->service_id);
     1104        free(fs);
     1105}
     1106
     1107static cdfs_t *cdfs_find_by_sid(service_id_t service_id)
     1108{
     1109        list_foreach(cdfs_instances, link, cdfs_t, fs) {
     1110                if (fs->service_id == service_id)
     1111                        return fs;
     1112        }
     1113       
     1114        return NULL;
    8121115}
    8131116
    8141117static int cdfs_unmounted(service_id_t service_id)
    8151118{
    816         cdfs_instance_done(service_id);
     1119        cdfs_t *fs;
     1120
     1121        fs = cdfs_find_by_sid(service_id);
     1122        if (fs == NULL)
     1123                return ENOENT;
     1124       
     1125        cdfs_fs_destroy(fs);
    8171126        return EOK;
    8181127}
     
    8341143       
    8351144        if (!node->processed) {
    836                 int rc = cdfs_readdir(service_id, FS_NODE(node));
     1145                int rc = cdfs_readdir(node->fs, FS_NODE(node));
    8371146                if (rc != EOK)
    8381147                        return rc;
     
    9171226        /* Some nodes were requested to be removed from the cache. */
    9181227        if (0 < *premove_cnt) {
    919                 cdfs_node_t *node =     hash_table_get_inst(item, cdfs_node_t, nh_link);
     1228                cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    9201229
    9211230                if (!node->opened) {
Note: See TracChangeset for help on using the changeset viewer.