Ignore:
File:
1 edited

Legend:

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

    rfc22069 r44ecf89  
    3939#include "cdfs_ops.h"
    4040#include <stdbool.h>
    41 #include <adt/list.h>
    4241#include <adt/hash_table.h>
    4342#include <adt/hash.h>
     
    4847#include <errno.h>
    4948#include <block.h>
    50 #include <scsi/mmc.h>
    5149#include <str.h>
    5250#include <byteorder.h>
     
    6765
    6866#define CDFS_STANDARD_IDENT  "CD001"
    69 
    70 enum {
    71         CDFS_NAME_CURDIR = '\x00',
    72         CDFS_NAME_PARENTDIR = '\x01'
    73 };
    7467
    7568typedef enum {
     
    133126
    134127typedef struct {
    135         uint8_t flags; /* reserved in primary */
     128        uint8_t res0;
    136129       
    137130        uint8_t system_ident[32];
     
    141134        uint32_t_lb lba_size;
    142135       
    143         uint8_t esc_seq[32]; /* reserved in primary */
     136        uint8_t res2[32];
    144137        uint16_t_lb set_size;
    145138        uint16_t_lb sequence_nr;
     
    171164       
    172165        uint8_t fs_version;
    173 } __attribute__((packed)) cdfs_vol_desc_prisec_t;
     166} __attribute__((packed)) cdfs_vol_desc_primary_t;
    174167
    175168typedef struct {
     
    179172        union {
    180173                cdfs_vol_desc_boot_t boot;
    181                 cdfs_vol_desc_prisec_t prisec;
     174                cdfs_vol_desc_primary_t primary;
    182175        } data;
    183176} __attribute__((packed)) cdfs_vol_desc_t;
    184 
    185 typedef 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;
    191177
    192178typedef enum {
     
    205191
    206192typedef 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 
    212 typedef struct {
    213193        fs_node_t *fs_node;       /**< FS node */
    214194        fs_index_t index;         /**< Node index */
    215         cdfs_t *fs;               /**< File system */
     195        service_id_t service_id;  /**< Service ID of block device */
    216196       
    217197        ht_link_t nh_link;        /**< Nodes hash table link */
     
    227207} cdfs_node_t;
    228208
    229 /** String encoding */
    230 enum {
    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 */
    238 static 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 */
    245 static LIST_INITIALIZE(cdfs_instances);
    246 
    247209/** Shared index of nodes */
    248210static fs_index_t cdfs_index = 1;
     
    272234{
    273235        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    274         return hash_combine(node->fs->service_id, node->index);
     236        return hash_combine(node->service_id, node->index);
    275237}
    276238
     
    280242        ht_key_t *key = (ht_key_t*)k;
    281243       
    282         return key->service_id == node->fs->service_id && key->index == node->index;
     244        return key->service_id == node->service_id && key->index == node->index;
    283245}
    284246
     
    287249        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    288250       
    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                 }
     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);
    296258        }
    297259       
     
    338300        node->fs_node = NULL;
    339301        node->index = 0;
    340         node->fs = NULL;
     302        node->service_id = 0;
    341303        node->type = CDFS_NONE;
    342304        node->lnkcnt = 0;
     
    349311}
    350312
    351 static int create_node(fs_node_t **rfn, cdfs_t *fs, int lflag,
     313static int create_node(fs_node_t **rfn, service_id_t service_id, int lflag,
    352314    fs_index_t index)
    353315{
     
    370332       
    371333        fs_node_t *rootfn;
    372         int rc = cdfs_root_get(&rootfn, fs->service_id);
     334        int rc = cdfs_root_get(&rootfn, service_id);
    373335       
    374336        assert(rc == EOK);
     
    379341                node->index = index;
    380342       
    381         node->fs = fs;
     343        node->service_id = service_id;
    382344       
    383345        if (lflag & L_DIRECTORY)
     
    403365       
    404366        /* Check for duplicate entries */
    405         list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
     367        list_foreach(parent->cs_list, link) {
     368                cdfs_dentry_t *dentry =
     369                    list_get_instance(link, cdfs_dentry_t, link);
     370               
    406371                if (str_cmp(dentry->name, name) == 0)
    407372                        return EEXIST;
     
    429394}
    430395
    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  */
    438 static 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  */
    488 static 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 
    519 static bool cdfs_readdir(cdfs_t *fs, fs_node_t *fs_node)
     396static bool cdfs_readdir(service_id_t service_id, fs_node_t *fs_node)
    520397{
    521398        cdfs_node_t *node = CDFS_NODE(fs_node);
     
    531408        for (uint32_t i = 0; i < blocks; i++) {
    532409                block_t *block;
    533                 int rc = block_get(&block, fs->service_id, node->lba + i, BLOCK_FLAGS_NONE);
     410                int rc = block_get(&block, service_id, node->lba + i, BLOCK_FLAGS_NONE);
    534411                if (rc != EOK)
    535412                        return false;
    536413               
    537                 cdfs_dir_t *dir;
    538                
    539                 for (size_t offset = 0; offset < BLOCK_SIZE;
     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);
    540420                    offset += dir->length) {
    541421                        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                         }
    548422                       
    549423                        cdfs_dentry_type_t dentry_type;
     
    553427                                dentry_type = CDFS_FILE;
    554428                       
    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                        
    564429                        // FIXME: hack - indexing by dentry byte offset on disc
    565430                       
    566431                        fs_node_t *fn;
    567                         int rc = create_node(&fn, fs, dentry_type,
     432                        int rc = create_node(&fn, service_id, dentry_type,
    568433                            (node->lba + i) * BLOCK_SIZE + offset);
    569434                        if ((rc != EOK) || (fn == NULL))
     
    574439                        cur->size = uint32_lb(dir->size);
    575440                       
    576                         char *name = cdfs_decode_name(dir->name,
    577                             dir->name_length, node->fs->enc, dentry_type);
     441                        char *name = (char *) malloc(dir->name_length + 1);
    578442                        if (name == NULL)
    579443                                return false;
     444                       
     445                        memcpy(name, dir->name, dir->name_length);
     446                        name[dir->name_length] = 0;
    580447                       
    581448                        // FIXME: check return value
     
    595462}
    596463
    597 static fs_node_t *get_uncached_node(cdfs_t *fs, fs_index_t index)
     464static fs_node_t *get_uncached_node(service_id_t service_id, fs_index_t index)
    598465{
    599466        cdfs_lba_t lba = index / BLOCK_SIZE;
     
    601468       
    602469        block_t *block;
    603         int rc = block_get(&block, fs->service_id, lba, BLOCK_FLAGS_NONE);
     470        int rc = block_get(&block, service_id, lba, BLOCK_FLAGS_NONE);
    604471        if (rc != EOK)
    605472                return NULL;
     
    614481       
    615482        fs_node_t *fn;
    616         rc = create_node(&fn, fs, dentry_type, index);
     483        rc = create_node(&fn, service_id, dentry_type, index);
    617484        if ((rc != EOK) || (fn == NULL))
    618485                return NULL;
     
    630497}
    631498
    632 static fs_node_t *get_cached_node(cdfs_t *fs, fs_index_t index)
     499static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index)
    633500{
    634501        ht_key_t key = {
    635502                .index = index,
    636                 .service_id = fs->service_id
     503                .service_id = service_id
    637504        };
    638505       
     
    644511        }
    645512       
    646         return get_uncached_node(fs, index);
     513        return get_uncached_node(service_id, index);
    647514}
    648515
     
    652519       
    653520        if (!parent->processed) {
    654                 int rc = cdfs_readdir(parent->fs, pfn);
     521                int rc = cdfs_readdir(parent->service_id, pfn);
    655522                if (rc != EOK)
    656523                        return rc;
    657524        }
    658525       
    659         list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) {
     526        list_foreach(parent->cs_list, link) {
     527                cdfs_dentry_t *dentry =
     528                    list_get_instance(link, cdfs_dentry_t, link);
     529               
    660530                if (str_cmp(dentry->name, component) == 0) {
    661                         *fn = get_cached_node(parent->fs, dentry->index);
     531                        *fn = get_cached_node(parent->service_id, dentry->index);
    662532                        return EOK;
    663533                }
     
    673543       
    674544        if (!node->processed)
    675                 cdfs_readdir(node->fs, fn);
     545                cdfs_readdir(node->service_id, fn);
    676546       
    677547        node->opened++;
     
    714584       
    715585        if ((node->type == CDFS_DIRECTORY) && (!node->processed))
    716                 cdfs_readdir(node->fs, fn);
     586                cdfs_readdir(node->service_id, fn);
    717587       
    718588        *has_children = !list_empty(&node->cs_list);
     
    753623{
    754624        return 0;
    755 }
    756 
    757 static int cdfs_size_block(service_id_t service_id, uint32_t *size)
    758 {
    759         *size = BLOCK_SIZE;
    760        
    761         return EOK;
    762 }
    763 
    764 static int cdfs_total_block_count(service_id_t service_id, uint64_t *count)
    765 {
    766         *count = 0;
    767        
    768         return EOK;
    769 }
    770 
    771 static int cdfs_free_block_count(service_id_t service_id, uint64_t *count)
    772 {
    773         *count = 0;
    774        
    775         return EOK;
    776625}
    777626
     
    792641        .is_directory = cdfs_is_directory,
    793642        .is_file = cdfs_is_file,
    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
     643        .service_get = cdfs_service_get
    798644};
    799645
    800 /** Verify that escape sequence corresonds to one of the allowed encoding
    801  * escape sequences allowed for Joliet. */
    802 static 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  */
    845 static 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 
    908 static bool iso_readfs(cdfs_t *fs, fs_node_t *rfn,
     646static bool iso_readfs(service_id_t service_id, fs_node_t *rfn,
    909647    cdfs_lba_t altroot)
    910648{
    911649        /* First 16 blocks of isofs are empty */
    912650        block_t *block;
    913         int rc = block_get(&block, fs->service_id, altroot + 16, BLOCK_FLAGS_NONE);
     651        int rc = block_get(&block, service_id, altroot + 16, BLOCK_FLAGS_NONE);
    914652        if (rc != EOK)
    915653                return false;
     
    928666        }
    929667       
    930         uint16_t set_size = uint16_lb(vol_desc->data.prisec.set_size);
     668        uint16_t set_size = uint16_lb(vol_desc->data.primary.set_size);
    931669        if (set_size > 1) {
    932670                /*
     
    938676        }
    939677       
    940         uint16_t sequence_nr = uint16_lb(vol_desc->data.prisec.sequence_nr);
     678        uint16_t sequence_nr = uint16_lb(vol_desc->data.primary.sequence_nr);
    941679        if (sequence_nr != 1) {
    942680                /*
     
    948686        }
    949687       
    950         uint16_t block_size = uint16_lb(vol_desc->data.prisec.block_size);
     688        uint16_t block_size = uint16_lb(vol_desc->data.primary.block_size);
    951689        if (block_size != BLOCK_SIZE) {
    952690                block_put(block);
     
    957695       
    958696        cdfs_node_t *node = CDFS_NODE(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)) {
     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)) {
    978701                block_put(block);
    979702                return false;
     
    987710 *
    988711 */
    989 static 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        
     712static bool cdfs_instance_init(service_id_t service_id, cdfs_lba_t altroot)
     713{
    1000714        /* Create root node */
    1001         int rc = create_node(&rfn, fs, L_DIRECTORY, cdfs_index++);
     715        fs_node_t *rfn;
     716        int rc = create_node(&rfn, service_id, L_DIRECTORY, cdfs_index++);
    1002717       
    1003718        if ((rc != EOK) || (!rfn))
    1004                 goto error;
     719                return false;
    1005720       
    1006721        /* FS root is not linked */
     
    1010725       
    1011726        /* Check if there is cdfs in given session */
    1012         if (!iso_readfs(fs, rfn, altroot))
    1013                 goto error;
    1014        
    1015         list_append(&fs->link, &cdfs_instances);
    1016         return fs;
    1017 error:
    1018         // XXX destroy node
    1019         free(fs);
    1020         return NULL;
     727        if (!iso_readfs(service_id, rfn, altroot)) {
     728                // XXX destroy node
     729                return false;
     730        }
     731       
     732        return true;
    1021733}
    1022734
     
    1025737{
    1026738        /* Initialize the block layer */
    1027         int rc = block_init(service_id, BLOCK_SIZE);
     739        int rc = block_init(EXCHANGE_SERIALIZE, service_id, BLOCK_SIZE);
    1028740        if (rc != EOK)
    1029741                return rc;
     
    1036748                        altroot = 0;
    1037749        } else {
    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);
     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                }
    1047756        }
    1048757       
     
    1065774        }
    1066775       
    1067         /* Create cdfs instance */
    1068         if (cdfs_fs_create(service_id, altroot) == NULL) {
     776        /* Initialize cdfs instance */
     777        if (!cdfs_instance_init(service_id, altroot)) {
    1069778                block_cache_fini(service_id);
    1070779                block_fini(service_id);
     
    1089798        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    1090799       
    1091         if (node->fs->service_id == service_id) {
     800        if (node->service_id == service_id) {
    1092801                hash_table_remove_item(&nodes, &node->nh_link);
    1093802        }
     
    1096805}
    1097806
    1098 static 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 
    1107 static 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;
     807static 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);
    1115812}
    1116813
    1117814static int cdfs_unmounted(service_id_t service_id)
    1118815{
    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);
     816        cdfs_instance_done(service_id);
    1126817        return EOK;
    1127818}
     
    1143834       
    1144835        if (!node->processed) {
    1145                 int rc = cdfs_readdir(node->fs, FS_NODE(node));
     836                int rc = cdfs_readdir(service_id, FS_NODE(node));
    1146837                if (rc != EOK)
    1147838                        return rc;
     
    1226917        /* Some nodes were requested to be removed from the cache. */
    1227918        if (0 < *premove_cnt) {
    1228                 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
     919                cdfs_node_t *node =     hash_table_get_inst(item, cdfs_node_t, nh_link);
    1229920
    1230921                if (!node->opened) {
Note: See TracChangeset for help on using the changeset viewer.