Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    r0be611b refcebe1  
    11/*
    22 * Copyright (c) 2008 Jakub Jermar
    3  * Copyright (c) 2011 Oleg Romanenko
    43 * All rights reserved.
    54 *
     
    3029/** @addtogroup fs
    3130 * @{
    32  */
     31 */ 
    3332
    3433/**
     
    4039#include "fat_dentry.h"
    4140#include "fat_fat.h"
    42 #include "fat_directory.h"
    4341#include "../../vfs/vfs.h"
    4442#include <libfs.h>
    4543#include <libblock.h>
    4644#include <ipc/services.h>
    47 #include <ipc/loc.h>
     45#include <ipc/devmap.h>
    4846#include <macros.h>
    4947#include <async.h>
     
    5856#include <align.h>
    5957#include <malloc.h>
    60 #include <str.h>
    6158
    6259#define FAT_NODE(node)  ((node) ? (fat_node_t *) (node)->data : NULL)
     
    7572 * Forward declarations of FAT libfs operations.
    7673 */
    77 static int fat_root_get(fs_node_t **, service_id_t);
     74static int fat_root_get(fs_node_t **, devmap_handle_t);
    7875static int fat_match(fs_node_t **, fs_node_t *, const char *);
    79 static int fat_node_get(fs_node_t **, service_id_t, fs_index_t);
     76static int fat_node_get(fs_node_t **, devmap_handle_t, fs_index_t);
    8077static int fat_node_open(fs_node_t *);
    8178static int fat_node_put(fs_node_t *);
    82 static int fat_create_node(fs_node_t **, service_id_t, int);
     79static int fat_create_node(fs_node_t **, devmap_handle_t, int);
    8380static int fat_destroy_node(fs_node_t *);
    8481static int fat_link(fs_node_t *, fs_node_t *, const char *);
     
    9087static bool fat_is_directory(fs_node_t *);
    9188static bool fat_is_file(fs_node_t *node);
    92 static service_id_t fat_device_get(fs_node_t *node);
     89static devmap_handle_t fat_device_get(fs_node_t *node);
    9390
    9491/*
     
    107104        node->dirty = false;
    108105        node->lastc_cached_valid = false;
    109         node->lastc_cached_value = 0;
     106        node->lastc_cached_value = FAT_CLST_LAST1;
    110107        node->currc_cached_valid = false;
    111108        node->currc_cached_bn = 0;
    112         node->currc_cached_value = 0;
     109        node->currc_cached_value = FAT_CLST_LAST1;
    113110}
    114111
     
    119116        fat_dentry_t *d;
    120117        int rc;
    121 
     118       
    122119        assert(node->dirty);
    123120
    124         bs = block_bb_get(node->idx->service_id);
    125 
     121        bs = block_bb_get(node->idx->devmap_handle);
     122       
    126123        /* Read the block that contains the dentry of interest. */
    127         rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
     124        rc = _fat_block_get(&b, bs, node->idx->devmap_handle, node->idx->pfc,
    128125            NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    129126            BLOCK_FLAGS_NONE);
     
    139136                d->attr = FAT_ATTR_SUBDIR;
    140137        }
    141 
     138       
    142139        /* TODO: update other fields? (e.g time fields) */
    143 
     140       
    144141        b->dirty = true;                /* need to sync block */
    145142        rc = block_put(b);
     
    147144}
    148145
    149 static int fat_node_fini_by_service_id(service_id_t service_id)
     146static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle)
    150147{
    151148        fat_node_t *nodep;
     
    171168                        goto restart;
    172169                }
    173                 if (nodep->idx->service_id != service_id) {
     170                if (nodep->idx->devmap_handle != devmap_handle) {
    174171                        fibril_mutex_unlock(&nodep->idx->lock);
    175172                        fibril_mutex_unlock(&nodep->lock);
     
    258255        fn->data = nodep;
    259256        nodep->bp = fn;
    260 
     257       
    261258        *nodepp = nodep;
    262259        return EOK;
     
    294291         * We must instantiate the node from the file system.
    295292         */
    296 
     293       
    297294        assert(idxp->pfc);
    298295
     
    301298                return rc;
    302299
    303         bs = block_bb_get(idxp->service_id);
     300        bs = block_bb_get(idxp->devmap_handle);
    304301
    305302        /* Read the block that contains the dentry of interest. */
    306         rc = _fat_block_get(&b, bs, idxp->service_id, idxp->pfc, NULL,
     303        rc = _fat_block_get(&b, bs, idxp->devmap_handle, idxp->pfc, NULL,
    307304            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    308305        if (rc != EOK) {
     
    312309
    313310        d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
    314         if (FAT_IS_FAT32(bs)) {
    315                 nodep->firstc = uint16_t_le2host(d->firstc_lo) |
    316                     (uint16_t_le2host(d->firstc_hi) << 16);
    317         } else
    318                 nodep->firstc = uint16_t_le2host(d->firstc);
    319 
    320311        if (d->attr & FAT_ATTR_SUBDIR) {
    321                 /*
     312                /* 
    322313                 * The only directory which does not have this bit set is the
    323314                 * root directory itself. The root directory node is handled
     
    325316                 */
    326317                nodep->type = FAT_DIRECTORY;
    327 
    328318                /*
    329319                 * Unfortunately, the 'size' field of the FAT dentry is not
     
    331321                 * size of the directory by walking the FAT.
    332322                 */
    333                 uint32_t clusters;
    334                 rc = fat_clusters_get(&clusters, bs, idxp->service_id,
    335                     nodep->firstc);
     323                uint16_t clusters;
     324                rc = fat_clusters_get(&clusters, bs, idxp->devmap_handle,
     325                    uint16_t_le2host(d->firstc));
    336326                if (rc != EOK) {
    337327                        (void) block_put(b);
     
    344334                nodep->size = uint32_t_le2host(d->size);
    345335        }
    346 
     336        nodep->firstc = uint16_t_le2host(d->firstc);
    347337        nodep->lnkcnt = 1;
    348338        nodep->refcnt = 1;
     
    366356 */
    367357
    368 int fat_root_get(fs_node_t **rfn, service_id_t service_id)
    369 {
    370         return fat_node_get(rfn, service_id, 0);
     358int fat_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     359{
     360        return fat_node_get(rfn, devmap_handle, 0);
    371361}
    372362
    373363int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    374364{
     365        fat_bs_t *bs;
    375366        fat_node_t *parentp = FAT_NODE(pfn);
    376         char name[FAT_LFN_NAME_SIZE];
     367        char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     368        unsigned i, j;
     369        unsigned blocks;
    377370        fat_dentry_t *d;
    378         service_id_t service_id;
     371        devmap_handle_t devmap_handle;
     372        block_t *b;
    379373        int rc;
    380374
    381375        fibril_mutex_lock(&parentp->idx->lock);
    382         service_id = parentp->idx->service_id;
     376        devmap_handle = parentp->idx->devmap_handle;
    383377        fibril_mutex_unlock(&parentp->idx->lock);
    384        
    385         fat_directory_t di;
    386         rc = fat_directory_open(parentp, &di);
    387         if (rc != EOK)
    388                 return rc;
    389 
    390         while (fat_directory_read(&di, name, &d) == EOK) {
    391                 if (fat_dentry_namecmp(name, component) == 0) {
    392                         /* hit */
    393                         fat_node_t *nodep;
    394                         aoff64_t o = di.pos %
    395                             (BPS(di.bs) / sizeof(fat_dentry_t));
    396                         fat_idx_t *idx = fat_idx_get_by_pos(service_id,
    397                             parentp->firstc, di.bnum * DPS(di.bs) + o);
    398                         if (!idx) {
    399                                 /*
    400                                  * Can happen if memory is low or if we
    401                                  * run out of 32-bit indices.
    402                                  */
    403                                 rc = fat_directory_close(&di);
    404                                 return (rc == EOK) ? ENOMEM : rc;
     378
     379        bs = block_bb_get(devmap_handle);
     380        blocks = parentp->size / BPS(bs);
     381        for (i = 0; i < blocks; i++) {
     382                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     383                if (rc != EOK)
     384                        return rc;
     385                for (j = 0; j < DPS(bs); j++) {
     386                        d = ((fat_dentry_t *)b->data) + j;
     387                        switch (fat_classify_dentry(d)) {
     388                        case FAT_DENTRY_SKIP:
     389                        case FAT_DENTRY_FREE:
     390                                continue;
     391                        case FAT_DENTRY_LAST:
     392                                /* miss */
     393                                rc = block_put(b);
     394                                *rfn = NULL;
     395                                return rc;
     396                        default:
     397                        case FAT_DENTRY_VALID:
     398                                fat_dentry_name_get(d, name);
     399                                break;
    405400                        }
    406                         rc = fat_node_get_core(&nodep, idx);
    407                         fibril_mutex_unlock(&idx->lock);
    408                         if (rc != EOK) {
    409                                 (void) fat_directory_close(&di);
     401                        if (fat_dentry_namecmp(name, component) == 0) {
     402                                /* hit */
     403                                fat_node_t *nodep;
     404                                fat_idx_t *idx = fat_idx_get_by_pos(devmap_handle,
     405                                    parentp->firstc, i * DPS(bs) + j);
     406                                if (!idx) {
     407                                        /*
     408                                         * Can happen if memory is low or if we
     409                                         * run out of 32-bit indices.
     410                                         */
     411                                        rc = block_put(b);
     412                                        return (rc == EOK) ? ENOMEM : rc;
     413                                }
     414                                rc = fat_node_get_core(&nodep, idx);
     415                                fibril_mutex_unlock(&idx->lock);
     416                                if (rc != EOK) {
     417                                        (void) block_put(b);
     418                                        return rc;
     419                                }
     420                                *rfn = FS_NODE(nodep);
     421                                rc = block_put(b);
     422                                if (rc != EOK)
     423                                        (void) fat_node_put(*rfn);
    410424                                return rc;
    411425                        }
    412                         *rfn = FS_NODE(nodep);
    413                         rc = fat_directory_close(&di);
    414                         if (rc != EOK)
    415                                 (void) fat_node_put(*rfn);
    416                         return rc;
    417                 } else {
    418                         rc = fat_directory_next(&di);
    419                         if (rc != EOK)
    420                                 break;
    421                 }
    422         }
    423         (void) fat_directory_close(&di);
     426                }
     427                rc = block_put(b);
     428                if (rc != EOK)
     429                        return rc;
     430        }
     431
    424432        *rfn = NULL;
    425433        return EOK;
     
    427435
    428436/** Instantiate a FAT in-core node. */
    429 int fat_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
     437int fat_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
    430438{
    431439        fat_node_t *nodep;
     
    433441        int rc;
    434442
    435         idxp = fat_idx_get_by_index(service_id, index);
     443        idxp = fat_idx_get_by_index(devmap_handle, index);
    436444        if (!idxp) {
    437445                *rfn = NULL;
     
    484492}
    485493
    486 int fat_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
     494int fat_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int flags)
    487495{
    488496        fat_idx_t *idxp;
     
    492500        int rc;
    493501
    494         bs = block_bb_get(service_id);
     502        bs = block_bb_get(devmap_handle);
    495503        if (flags & L_DIRECTORY) {
    496504                /* allocate a cluster */
    497                 rc = fat_alloc_clusters(bs, service_id, 1, &mcl, &lcl);
     505                rc = fat_alloc_clusters(bs, devmap_handle, 1, &mcl, &lcl);
    498506                if (rc != EOK)
    499507                        return rc;
    500508                /* populate the new cluster with unused dentries */
    501                 rc = fat_zero_cluster(bs, service_id, mcl);
     509                rc = fat_zero_cluster(bs, devmap_handle, mcl);
    502510                if (rc != EOK) {
    503                         (void) fat_free_clusters(bs, service_id, mcl);
     511                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    504512                        return rc;
    505513                }
     
    508516        rc = fat_node_get_new(&nodep);
    509517        if (rc != EOK) {
    510                 (void) fat_free_clusters(bs, service_id, mcl);
    511                 return rc;
    512         }
    513         rc = fat_idx_get_new(&idxp, service_id);
     518                (void) fat_free_clusters(bs, devmap_handle, mcl);
     519                return rc;
     520        }
     521        rc = fat_idx_get_new(&idxp, devmap_handle);
    514522        if (rc != EOK) {
    515                 (void) fat_free_clusters(bs, service_id, mcl); 
     523                (void) fat_free_clusters(bs, devmap_handle, mcl);       
    516524                (void) fat_node_put(FS_NODE(nodep));
    517525                return rc;
     
    562570        assert(!has_children);
    563571
    564         bs = block_bb_get(nodep->idx->service_id);
     572        bs = block_bb_get(nodep->idx->devmap_handle);
    565573        if (nodep->firstc != FAT_CLST_RES0) {
    566574                assert(nodep->size);
    567575                /* Free all clusters allocated to the node. */
    568                 rc = fat_free_clusters(bs, nodep->idx->service_id,
     576                rc = fat_free_clusters(bs, nodep->idx->devmap_handle,
    569577                    nodep->firstc);
    570578        }
     
    583591        fat_bs_t *bs;
    584592        block_t *b;
    585         fat_directory_t di;
    586         fat_dentry_t de;
     593        unsigned i, j;
     594        unsigned blocks;
     595        fat_cluster_t mcl, lcl;
    587596        int rc;
    588597
     
    598607        fibril_mutex_unlock(&childp->lock);
    599608
    600         if (!fat_valid_name(name))
     609        if (!fat_dentry_name_verify(name)) {
     610                /*
     611                 * Attempt to create unsupported name.
     612                 */
    601613                return ENOTSUP;
    602 
     614        }
     615
     616        /*
     617         * Get us an unused parent node's dentry or grow the parent and allocate
     618         * a new one.
     619         */
     620       
    603621        fibril_mutex_lock(&parentp->idx->lock);
    604         bs = block_bb_get(parentp->idx->service_id);
    605         rc = fat_directory_open(parentp, &di);
     622        bs = block_bb_get(parentp->idx->devmap_handle);
     623
     624        blocks = parentp->size / BPS(bs);
     625
     626        for (i = 0; i < blocks; i++) {
     627                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     628                if (rc != EOK) {
     629                        fibril_mutex_unlock(&parentp->idx->lock);
     630                        return rc;
     631                }
     632                for (j = 0; j < DPS(bs); j++) {
     633                        d = ((fat_dentry_t *)b->data) + j;
     634                        switch (fat_classify_dentry(d)) {
     635                        case FAT_DENTRY_SKIP:
     636                        case FAT_DENTRY_VALID:
     637                                /* skipping used and meta entries */
     638                                continue;
     639                        case FAT_DENTRY_FREE:
     640                        case FAT_DENTRY_LAST:
     641                                /* found an empty slot */
     642                                goto hit;
     643                        }
     644                }
     645                rc = block_put(b);
     646                if (rc != EOK) {
     647                        fibril_mutex_unlock(&parentp->idx->lock);
     648                        return rc;
     649                }
     650        }
     651        j = 0;
     652       
     653        /*
     654         * We need to grow the parent in order to create a new unused dentry.
     655         */
     656        if (parentp->firstc == FAT_CLST_ROOT) {
     657                /* Can't grow the root directory. */
     658                fibril_mutex_unlock(&parentp->idx->lock);
     659                return ENOSPC;
     660        }
     661        rc = fat_alloc_clusters(bs, parentp->idx->devmap_handle, 1, &mcl, &lcl);
    606662        if (rc != EOK) {
    607663                fibril_mutex_unlock(&parentp->idx->lock);
    608664                return rc;
    609665        }
    610 
     666        rc = fat_zero_cluster(bs, parentp->idx->devmap_handle, mcl);
     667        if (rc != EOK) {
     668                (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
     669                fibril_mutex_unlock(&parentp->idx->lock);
     670                return rc;
     671        }
     672        rc = fat_append_clusters(bs, parentp, mcl, lcl);
     673        if (rc != EOK) {
     674                (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
     675                fibril_mutex_unlock(&parentp->idx->lock);
     676                return rc;
     677        }
     678        parentp->size += BPS(bs) * SPC(bs);
     679        parentp->dirty = true;          /* need to sync node */
     680        rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     681        if (rc != EOK) {
     682                fibril_mutex_unlock(&parentp->idx->lock);
     683                return rc;
     684        }
     685        d = (fat_dentry_t *)b->data;
     686
     687hit:
    611688        /*
    612689         * At this point we only establish the link between the parent and the
     
    615692         * dentry data is kept in the child node structure.
    616693         */
    617         memset(&de, 0, sizeof(fat_dentry_t));
    618 
    619         rc = fat_directory_write(&di, name, &de);
    620         if (rc != EOK) {
    621                 (void) fat_directory_close(&di);
    622                 fibril_mutex_unlock(&parentp->idx->lock);
    623                 return rc;
    624         }
    625         rc = fat_directory_close(&di);
    626         if (rc != EOK) {
    627                 fibril_mutex_unlock(&parentp->idx->lock);
    628                 return rc;
    629         }
    630 
     694        memset(d, 0, sizeof(fat_dentry_t));
     695        fat_dentry_name_set(d, name);
     696        b->dirty = true;                /* need to sync block */
     697        rc = block_put(b);
    631698        fibril_mutex_unlock(&parentp->idx->lock);
     699        if (rc != EOK)
     700                return rc;
    632701
    633702        fibril_mutex_lock(&childp->idx->lock);
    634 
     703       
    635704        if (childp->type == FAT_DIRECTORY) {
    636705                /*
     
    651720                d = (fat_dentry_t *) b->data;
    652721                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    653                     (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
     722                    (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
    654723                        memset(d, 0, sizeof(fat_dentry_t));
    655724                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     
    661730                d++;
    662731                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    663                     (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
     732                    (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
    664733                        memset(d, 0, sizeof(fat_dentry_t));
    665734                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
    666735                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    667736                        d->attr = FAT_ATTR_SUBDIR;
    668                         d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
    669                             host2uint16_t_le(FAT_CLST_ROOTPAR) :
     737                        d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
     738                            host2uint16_t_le(FAT_CLST_RES0) :
    670739                            host2uint16_t_le(parentp->firstc);
    671740                        /* TODO: initialize also the date/time members. */
     
    681750
    682751        childp->idx->pfc = parentp->firstc;
    683         childp->idx->pdi = di.pos;      /* di.pos holds absolute position of SFN entry */
     752        childp->idx->pdi = i * DPS(bs) + j;
    684753        fibril_mutex_unlock(&childp->idx->lock);
    685754
     
    701770        fat_node_t *parentp = FAT_NODE(pfn);
    702771        fat_node_t *childp = FAT_NODE(cfn);
     772        fat_bs_t *bs;
     773        fat_dentry_t *d;
     774        block_t *b;
    703775        bool has_children;
    704776        int rc;
     
    706778        if (!parentp)
    707779                return EBUSY;
    708 
     780       
    709781        rc = fat_has_children(&has_children, cfn);
    710782        if (rc != EOK)
     
    717789        assert(childp->lnkcnt == 1);
    718790        fibril_mutex_lock(&childp->idx->lock);
    719        
    720         fat_directory_t di;
    721         rc = fat_directory_open(parentp, &di);
    722         if (rc != EOK)
     791        bs = block_bb_get(childp->idx->devmap_handle);
     792
     793        rc = _fat_block_get(&b, bs, childp->idx->devmap_handle, childp->idx->pfc,
     794            NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
     795            BLOCK_FLAGS_NONE);
     796        if (rc != EOK)
    723797                goto error;
    724         rc = fat_directory_seek(&di, childp->idx->pdi);
    725         if (rc != EOK)
    726                 goto error;
    727         rc = fat_directory_erase(&di);
    728         if (rc != EOK)
    729                 goto error;
    730         rc = fat_directory_close(&di);
     798        d = (fat_dentry_t *)b->data +
     799            (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
     800        /* mark the dentry as not-currently-used */
     801        d->name[0] = FAT_DENTRY_ERASED;
     802        b->dirty = true;                /* need to sync block */
     803        rc = block_put(b);
    731804        if (rc != EOK)
    732805                goto error;
     
    747820
    748821error:
    749         (void) fat_directory_close(&di);
     822        fibril_mutex_unlock(&parentp->idx->lock);
     823        fibril_mutex_unlock(&childp->lock);
    750824        fibril_mutex_unlock(&childp->idx->lock);
    751         fibril_mutex_unlock(&childp->lock);
    752         fibril_mutex_unlock(&parentp->lock);
    753825        return rc;
    754826}
     
    767839                return EOK;
    768840        }
    769 
     841       
    770842        fibril_mutex_lock(&nodep->idx->lock);
    771         bs = block_bb_get(nodep->idx->service_id);
     843        bs = block_bb_get(nodep->idx->devmap_handle);
    772844
    773845        blocks = nodep->size / BPS(bs);
     
    775847        for (i = 0; i < blocks; i++) {
    776848                fat_dentry_t *d;
    777 
     849       
    778850                rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
    779851                if (rc != EOK) {
     
    803875                if (rc != EOK) {
    804876                        fibril_mutex_unlock(&nodep->idx->lock);
    805                         return rc;
     877                        return rc;     
    806878                }
    807879        }
     
    838910}
    839911
    840 service_id_t fat_device_get(fs_node_t *node)
     912devmap_handle_t fat_device_get(fs_node_t *node)
    841913{
    842914        return 0;
     
    868940
    869941static int
    870 fat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
     942fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
    871943    aoff64_t *size, unsigned *linkcnt)
    872944{
     
    874946        fat_bs_t *bs;
    875947        int rc;
    876 
     948       
    877949        /* Check for option enabling write through. */
    878950        if (str_cmp(opts, "wtcache") == 0)
     
    882954
    883955        /* initialize libblock */
    884         rc = block_init(EXCHANGE_SERIALIZE, service_id, BS_SIZE);
     956        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
    885957        if (rc != EOK)
    886958                return rc;
    887959
    888960        /* prepare the boot block */
    889         rc = block_bb_read(service_id, BS_BLOCK);
     961        rc = block_bb_read(devmap_handle, BS_BLOCK);
    890962        if (rc != EOK) {
    891                 block_fini(service_id);
     963                block_fini(devmap_handle);
    892964                return rc;
    893965        }
    894966
    895967        /* get the buffer with the boot sector */
    896         bs = block_bb_get(service_id);
     968        bs = block_bb_get(devmap_handle);
    897969       
    898970        if (BPS(bs) != BS_SIZE) {
    899                 block_fini(service_id);
     971                block_fini(devmap_handle);
    900972                return ENOTSUP;
    901973        }
    902974
    903975        /* Initialize the block cache */
    904         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
     976        rc = block_cache_init(devmap_handle, BPS(bs), 0 /* XXX */, cmode);
    905977        if (rc != EOK) {
    906                 block_fini(service_id);
     978                block_fini(devmap_handle);
    907979                return rc;
    908980        }
    909981
    910982        /* Do some simple sanity checks on the file system. */
    911         rc = fat_sanity_check(bs, service_id);
     983        rc = fat_sanity_check(bs, devmap_handle);
    912984        if (rc != EOK) {
    913                 (void) block_cache_fini(service_id);
    914                 block_fini(service_id);
    915                 return rc;
    916         }
    917 
    918         rc = fat_idx_init_by_service_id(service_id);
     985                (void) block_cache_fini(devmap_handle);
     986                block_fini(devmap_handle);
     987                return rc;
     988        }
     989
     990        rc = fat_idx_init_by_devmap_handle(devmap_handle);
    919991        if (rc != EOK) {
    920                 (void) block_cache_fini(service_id);
    921                 block_fini(service_id);
     992                (void) block_cache_fini(devmap_handle);
     993                block_fini(devmap_handle);
    922994                return rc;
    923995        }
     
    926998        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    927999        if (!rfn) {
    928                 (void) block_cache_fini(service_id);
    929                 block_fini(service_id);
    930                 fat_idx_fini_by_service_id(service_id);
     1000                (void) block_cache_fini(devmap_handle);
     1001                block_fini(devmap_handle);
     1002                fat_idx_fini_by_devmap_handle(devmap_handle);
    9311003                return ENOMEM;
    9321004        }
    933 
    9341005        fs_node_initialize(rfn);
    9351006        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    9361007        if (!rootp) {
    9371008                free(rfn);
    938                 (void) block_cache_fini(service_id);
    939                 block_fini(service_id);
    940                 fat_idx_fini_by_service_id(service_id);
     1009                (void) block_cache_fini(devmap_handle);
     1010                block_fini(devmap_handle);
     1011                fat_idx_fini_by_devmap_handle(devmap_handle);
    9411012                return ENOMEM;
    9421013        }
    9431014        fat_node_initialize(rootp);
    9441015
    945         fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
     1016        fat_idx_t *ridxp = fat_idx_get_by_pos(devmap_handle, FAT_CLST_ROOTPAR, 0);
    9461017        if (!ridxp) {
    9471018                free(rfn);
    9481019                free(rootp);
    949                 (void) block_cache_fini(service_id);
    950                 block_fini(service_id);
    951                 fat_idx_fini_by_service_id(service_id);
     1020                (void) block_cache_fini(devmap_handle);
     1021                block_fini(devmap_handle);
     1022                fat_idx_fini_by_devmap_handle(devmap_handle);
    9521023                return ENOMEM;
    9531024        }
     
    9561027
    9571028        rootp->type = FAT_DIRECTORY;
    958         rootp->firstc = FAT_ROOT_CLST(bs);
     1029        rootp->firstc = FAT_CLST_ROOT;
    9591030        rootp->refcnt = 1;
    9601031        rootp->lnkcnt = 0;      /* FS root is not linked */
    961 
    962         if (FAT_IS_FAT32(bs)) {
    963                 uint32_t clusters;
    964                 rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
    965                 if (rc != EOK) {
    966                         free(rfn);
    967                         free(rootp);
    968                         (void) block_cache_fini(service_id);
    969                         block_fini(service_id);
    970                         fat_idx_fini_by_service_id(service_id);
    971                         return ENOTSUP;
    972                 }
    973                 rootp->size = BPS(bs) * SPC(bs) * clusters;
    974         } else
    975                 rootp->size = RDE(bs) * sizeof(fat_dentry_t);
    976 
     1032        rootp->size = RDE(bs) * sizeof(fat_dentry_t);
    9771033        rootp->idx = ridxp;
    9781034        ridxp->nodep = rootp;
    9791035        rootp->bp = rfn;
    9801036        rfn->data = rootp;
    981 
     1037       
    9821038        fibril_mutex_unlock(&ridxp->lock);
    9831039
     
    9891045}
    9901046
    991 static int fat_unmounted(service_id_t service_id)
     1047static int fat_unmounted(devmap_handle_t devmap_handle)
    9921048{
    9931049        fs_node_t *fn;
     
    9951051        int rc;
    9961052
    997         rc = fat_root_get(&fn, service_id);
     1053        rc = fat_root_get(&fn, devmap_handle);
    9981054        if (rc != EOK)
    9991055                return rc;
     
    10081064                return EBUSY;
    10091065        }
    1010 
     1066       
    10111067        /*
    10121068         * Put the root node and force it to the FAT free node list.
     
    10201076         * stop using libblock for this instance.
    10211077         */
    1022         (void) fat_node_fini_by_service_id(service_id);
    1023         fat_idx_fini_by_service_id(service_id);
    1024         (void) block_cache_fini(service_id);
    1025         block_fini(service_id);
     1078        (void) fat_node_fini_by_devmap_handle(devmap_handle);
     1079        fat_idx_fini_by_devmap_handle(devmap_handle);
     1080        (void) block_cache_fini(devmap_handle);
     1081        block_fini(devmap_handle);
    10261082
    10271083        return EOK;
     
    10291085
    10301086static int
    1031 fat_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1087fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
    10321088    size_t *rbytes)
    10331089{
     
    10391095        int rc;
    10401096
    1041         rc = fat_node_get(&fn, service_id, index);
     1097        rc = fat_node_get(&fn, devmap_handle, index);
    10421098        if (rc != EOK)
    10431099                return rc;
     
    10541110        }
    10551111
    1056         bs = block_bb_get(service_id);
     1112        bs = block_bb_get(devmap_handle);
    10571113
    10581114        if (nodep->type == FAT_FILE) {
     
    10851141                }
    10861142        } else {
     1143                unsigned bnum;
    10871144                aoff64_t spos = pos;
    1088                 char name[FAT_LFN_NAME_SIZE];
     1145                char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    10891146                fat_dentry_t *d;
    10901147
     
    10931150                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    10941151
    1095                 fat_directory_t di;
    1096                 rc = fat_directory_open(nodep, &di);
    1097                 if (rc != EOK)
    1098                         goto err;
    1099                 rc = fat_directory_seek(&di, pos);
    1100                 if (rc != EOK) {
    1101                         (void) fat_directory_close(&di);
    1102                         goto err;
    1103                 }
    1104 
    1105                 rc = fat_directory_read(&di, name, &d);
    1106                 if (rc == EOK)
    1107                         goto hit;
    1108                 if (rc == ENOENT)
    1109                         goto miss;
    1110 
    1111 err:
    1112                 (void) fat_node_put(fn);
    1113                 async_answer_0(callid, rc);
    1114                 return rc;
    1115 
     1152                /*
     1153                 * Our strategy for readdir() is to use the position pointer as
     1154                 * an index into the array of all dentries. On entry, it points
     1155                 * to the first unread dentry. If we skip any dentries, we bump
     1156                 * the position pointer accordingly.
     1157                 */
     1158                bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
     1159                while (bnum < nodep->size / BPS(bs)) {
     1160                        aoff64_t o;
     1161
     1162                        rc = fat_block_get(&b, bs, nodep, bnum,
     1163                            BLOCK_FLAGS_NONE);
     1164                        if (rc != EOK)
     1165                                goto err;
     1166                        for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
     1167                            o < BPS(bs) / sizeof(fat_dentry_t);
     1168                            o++, pos++) {
     1169                                d = ((fat_dentry_t *)b->data) + o;
     1170                                switch (fat_classify_dentry(d)) {
     1171                                case FAT_DENTRY_SKIP:
     1172                                case FAT_DENTRY_FREE:
     1173                                        continue;
     1174                                case FAT_DENTRY_LAST:
     1175                                        rc = block_put(b);
     1176                                        if (rc != EOK)
     1177                                                goto err;
     1178                                        goto miss;
     1179                                default:
     1180                                case FAT_DENTRY_VALID:
     1181                                        fat_dentry_name_get(d, name);
     1182                                        rc = block_put(b);
     1183                                        if (rc != EOK)
     1184                                                goto err;
     1185                                        goto hit;
     1186                                }
     1187                        }
     1188                        rc = block_put(b);
     1189                        if (rc != EOK)
     1190                                goto err;
     1191                        bnum++;
     1192                }
    11161193miss:
    1117                 rc = fat_directory_close(&di);
    1118                 if (rc != EOK)
    1119                         goto err;
    11201194                rc = fat_node_put(fn);
    11211195                async_answer_0(callid, rc != EOK ? rc : ENOENT);
     
    11231197                return rc != EOK ? rc : ENOENT;
    11241198
     1199err:
     1200                (void) fat_node_put(fn);
     1201                async_answer_0(callid, rc);
     1202                return rc;
     1203
    11251204hit:
    1126                 pos = di.pos;
    1127                 rc = fat_directory_close(&di);
    1128                 if (rc != EOK)
    1129                         goto err;
    1130                 (void) async_data_read_finalize(callid, name,
    1131                     str_size(name) + 1);
     1205                (void) async_data_read_finalize(callid, name, str_size(name) + 1);
    11321206                bytes = (pos - spos) + 1;
    11331207        }
     
    11391213
    11401214static int
    1141 fat_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1215fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
    11421216    size_t *wbytes, aoff64_t *nsize)
    11431217{
     
    11511225        int rc;
    11521226       
    1153         rc = fat_node_get(&fn, service_id, index);
     1227        rc = fat_node_get(&fn, devmap_handle, index);
    11541228        if (rc != EOK)
    11551229                return rc;
     
    11571231                return ENOENT;
    11581232        nodep = FAT_NODE(fn);
    1159 
     1233       
    11601234        ipc_callid_t callid;
    11611235        size_t len;
     
    11661240        }
    11671241
    1168         bs = block_bb_get(service_id);
     1242        bs = block_bb_get(devmap_handle);
    11691243
    11701244        /*
     
    11731247         * but this one greatly simplifies fat_write(). Note that we can afford
    11741248         * to do this because the client must be ready to handle the return
    1175          * value signalizing a smaller number of bytes written.
    1176          */
     1249         * value signalizing a smaller number of bytes written. 
     1250         */ 
    11771251        bytes = min(len, BPS(bs) - pos % BPS(bs));
    11781252        if (bytes == BPS(bs))
    11791253                flags |= BLOCK_FLAGS_NOREAD;
    1180 
     1254       
    11811255        boundary = ROUND_UP(nodep->size, BPC(bs));
    11821256        if (pos < boundary) {
     
    12211295                 */
    12221296                unsigned nclsts;
    1223                 fat_cluster_t mcl, lcl;
    1224 
     1297                fat_cluster_t mcl, lcl; 
     1298 
    12251299                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    12261300                /* create an independent chain of nclsts clusters in all FATs */
    1227                 rc = fat_alloc_clusters(bs, service_id, nclsts, &mcl, &lcl);
     1301                rc = fat_alloc_clusters(bs, devmap_handle, nclsts, &mcl, &lcl);
    12281302                if (rc != EOK) {
    12291303                        /* could not allocate a chain of nclsts clusters */
     
    12351309                rc = fat_fill_gap(bs, nodep, mcl, pos);
    12361310                if (rc != EOK) {
    1237                         (void) fat_free_clusters(bs, service_id, mcl);
     1311                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12381312                        (void) fat_node_put(fn);
    12391313                        async_answer_0(callid, rc);
    12401314                        return rc;
    12411315                }
    1242                 rc = _fat_block_get(&b, bs, service_id, lcl, NULL,
     1316                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
    12431317                    (pos / BPS(bs)) % SPC(bs), flags);
    12441318                if (rc != EOK) {
    1245                         (void) fat_free_clusters(bs, service_id, mcl);
     1319                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12461320                        (void) fat_node_put(fn);
    12471321                        async_answer_0(callid, rc);
     
    12531327                rc = block_put(b);
    12541328                if (rc != EOK) {
    1255                         (void) fat_free_clusters(bs, service_id, mcl);
     1329                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12561330                        (void) fat_node_put(fn);
    12571331                        return rc;
     
    12631337                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    12641338                if (rc != EOK) {
    1265                         (void) fat_free_clusters(bs, service_id, mcl);
     1339                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12661340                        (void) fat_node_put(fn);
    12671341                        return rc;
     
    12761350
    12771351static int
    1278 fat_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
     1352fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
    12791353{
    12801354        fs_node_t *fn;
     
    12831357        int rc;
    12841358
    1285         rc = fat_node_get(&fn, service_id, index);
     1359        rc = fat_node_get(&fn, devmap_handle, index);
    12861360        if (rc != EOK)
    12871361                return rc;
     
    12901364        nodep = FAT_NODE(fn);
    12911365
    1292         bs = block_bb_get(service_id);
     1366        bs = block_bb_get(devmap_handle);
    12931367
    12941368        if (nodep->size == size) {
     
    13061380                nodep->size = size;
    13071381                nodep->dirty = true;            /* need to sync node */
    1308                 rc = EOK;
     1382                rc = EOK;       
    13091383        } else {
    13101384                /*
     
    13171391                } else {
    13181392                        fat_cluster_t lastc;
    1319                         rc = fat_cluster_walk(bs, service_id, nodep->firstc,
     1393                        rc = fat_cluster_walk(bs, devmap_handle, nodep->firstc,
    13201394                            &lastc, NULL, (size - 1) / BPC(bs));
    13211395                        if (rc != EOK)
     
    13271401                nodep->size = size;
    13281402                nodep->dirty = true;            /* need to sync node */
    1329                 rc = EOK;
     1403                rc = EOK;       
    13301404        }
    13311405out:
     
    13341408}
    13351409
    1336 static int fat_close(service_id_t service_id, fs_index_t index)
     1410static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
    13371411{
    13381412        return EOK;
    13391413}
    13401414
    1341 static int fat_destroy(service_id_t service_id, fs_index_t index)
     1415static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
    13421416{
    13431417        fs_node_t *fn;
     
    13451419        int rc;
    13461420
    1347         rc = fat_node_get(&fn, service_id, index);
     1421        rc = fat_node_get(&fn, devmap_handle, index);
    13481422        if (rc != EOK)
    13491423                return rc;
     
    13621436}
    13631437
    1364 static int fat_sync(service_id_t service_id, fs_index_t index)
     1438static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
    13651439{
    13661440        fs_node_t *fn;
    1367         int rc = fat_node_get(&fn, service_id, index);
     1441        int rc = fat_node_get(&fn, devmap_handle, index);
    13681442        if (rc != EOK)
    13691443                return rc;
    13701444        if (!fn)
    13711445                return ENOENT;
    1372 
     1446       
    13731447        fat_node_t *nodep = FAT_NODE(fn);
    1374 
     1448       
    13751449        nodep->dirty = true;
    13761450        rc = fat_node_sync(nodep);
    1377 
     1451       
    13781452        fat_node_put(fn);
    13791453        return rc;
Note: See TracChangeset for help on using the changeset viewer.