Ignore:
File:
1 edited

Legend:

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

    r0be611b r79ae36dd  
    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)
     
    7067
    7168/** List of cached free FAT nodes. */
    72 static LIST_INITIALIZE(ffn_list);
     69static LIST_INITIALIZE(ffn_head);
    7370
    7471/*
    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 *);
     
    8885static aoff64_t fat_size_get(fs_node_t *);
    8986static unsigned fat_lnkcnt_get(fs_node_t *);
     87static char fat_plb_get_char(unsigned);
    9088static bool fat_is_directory(fs_node_t *);
    9189static bool fat_is_file(fs_node_t *node);
    92 static service_id_t fat_device_get(fs_node_t *node);
     90static devmap_handle_t fat_device_get(fs_node_t *node);
    9391
    9492/*
     
    107105        node->dirty = false;
    108106        node->lastc_cached_valid = false;
    109         node->lastc_cached_value = 0;
     107        node->lastc_cached_value = FAT_CLST_LAST1;
    110108        node->currc_cached_valid = false;
    111109        node->currc_cached_bn = 0;
    112         node->currc_cached_value = 0;
     110        node->currc_cached_value = FAT_CLST_LAST1;
    113111}
    114112
     
    119117        fat_dentry_t *d;
    120118        int rc;
    121 
     119       
    122120        assert(node->dirty);
    123121
    124         bs = block_bb_get(node->idx->service_id);
    125 
     122        bs = block_bb_get(node->idx->devmap_handle);
     123       
    126124        /* Read the block that contains the dentry of interest. */
    127         rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
     125        rc = _fat_block_get(&b, bs, node->idx->devmap_handle, node->idx->pfc,
    128126            NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    129127            BLOCK_FLAGS_NONE);
     
    139137                d->attr = FAT_ATTR_SUBDIR;
    140138        }
    141 
     139       
    142140        /* TODO: update other fields? (e.g time fields) */
    143 
     141       
    144142        b->dirty = true;                /* need to sync block */
    145143        rc = block_put(b);
     
    147145}
    148146
    149 static int fat_node_fini_by_service_id(service_id_t service_id)
    150 {
     147static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle)
     148{
     149        link_t *lnk;
    151150        fat_node_t *nodep;
    152151        int rc;
     
    160159restart:
    161160        fibril_mutex_lock(&ffn_mutex);
    162         list_foreach(ffn_list, lnk) {
     161        for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
    163162                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
    164163                if (!fibril_mutex_trylock(&nodep->lock)) {
     
    171170                        goto restart;
    172171                }
    173                 if (nodep->idx->service_id != service_id) {
     172                if (nodep->idx->devmap_handle != devmap_handle) {
    174173                        fibril_mutex_unlock(&nodep->idx->lock);
    175174                        fibril_mutex_unlock(&nodep->lock);
     
    197196                free(nodep);
    198197
    199                 /* Need to restart because we changed ffn_list. */
     198                /* Need to restart because we changed the ffn_head list. */
    200199                goto restart;
    201200        }
     
    212211
    213212        fibril_mutex_lock(&ffn_mutex);
    214         if (!list_empty(&ffn_list)) {
     213        if (!list_empty(&ffn_head)) {
    215214                /* Try to use a cached free node structure. */
    216215                fat_idx_t *idxp_tmp;
    217                 nodep = list_get_instance(list_first(&ffn_list), fat_node_t,
    218                     ffn_link);
     216                nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
    219217                if (!fibril_mutex_trylock(&nodep->lock))
    220218                        goto skip_cache;
     
    258256        fn->data = nodep;
    259257        nodep->bp = fn;
    260 
     258       
    261259        *nodepp = nodep;
    262260        return EOK;
     
    294292         * We must instantiate the node from the file system.
    295293         */
    296 
     294       
    297295        assert(idxp->pfc);
    298296
     
    301299                return rc;
    302300
    303         bs = block_bb_get(idxp->service_id);
     301        bs = block_bb_get(idxp->devmap_handle);
    304302
    305303        /* Read the block that contains the dentry of interest. */
    306         rc = _fat_block_get(&b, bs, idxp->service_id, idxp->pfc, NULL,
     304        rc = _fat_block_get(&b, bs, idxp->devmap_handle, idxp->pfc, NULL,
    307305            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    308306        if (rc != EOK) {
     
    312310
    313311        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 
    320312        if (d->attr & FAT_ATTR_SUBDIR) {
    321                 /*
     313                /* 
    322314                 * The only directory which does not have this bit set is the
    323315                 * root directory itself. The root directory node is handled
     
    325317                 */
    326318                nodep->type = FAT_DIRECTORY;
    327 
    328319                /*
    329320                 * Unfortunately, the 'size' field of the FAT dentry is not
     
    331322                 * size of the directory by walking the FAT.
    332323                 */
    333                 uint32_t clusters;
    334                 rc = fat_clusters_get(&clusters, bs, idxp->service_id,
    335                     nodep->firstc);
     324                uint16_t clusters;
     325                rc = fat_clusters_get(&clusters, bs, idxp->devmap_handle,
     326                    uint16_t_le2host(d->firstc));
    336327                if (rc != EOK) {
    337328                        (void) block_put(b);
     
    344335                nodep->size = uint32_t_le2host(d->size);
    345336        }
    346 
     337        nodep->firstc = uint16_t_le2host(d->firstc);
    347338        nodep->lnkcnt = 1;
    348339        nodep->refcnt = 1;
     
    366357 */
    367358
    368 int fat_root_get(fs_node_t **rfn, service_id_t service_id)
    369 {
    370         return fat_node_get(rfn, service_id, 0);
     359int fat_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     360{
     361        return fat_node_get(rfn, devmap_handle, 0);
    371362}
    372363
    373364int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    374365{
     366        fat_bs_t *bs;
    375367        fat_node_t *parentp = FAT_NODE(pfn);
    376         char name[FAT_LFN_NAME_SIZE];
     368        char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     369        unsigned i, j;
     370        unsigned blocks;
    377371        fat_dentry_t *d;
    378         service_id_t service_id;
     372        devmap_handle_t devmap_handle;
     373        block_t *b;
    379374        int rc;
    380375
    381376        fibril_mutex_lock(&parentp->idx->lock);
    382         service_id = parentp->idx->service_id;
     377        devmap_handle = parentp->idx->devmap_handle;
    383378        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;
     379
     380        bs = block_bb_get(devmap_handle);
     381        blocks = parentp->size / BPS(bs);
     382        for (i = 0; i < blocks; i++) {
     383                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     384                if (rc != EOK)
     385                        return rc;
     386                for (j = 0; j < DPS(bs); j++) {
     387                        d = ((fat_dentry_t *)b->data) + j;
     388                        switch (fat_classify_dentry(d)) {
     389                        case FAT_DENTRY_SKIP:
     390                        case FAT_DENTRY_FREE:
     391                                continue;
     392                        case FAT_DENTRY_LAST:
     393                                /* miss */
     394                                rc = block_put(b);
     395                                *rfn = NULL;
     396                                return rc;
     397                        default:
     398                        case FAT_DENTRY_VALID:
     399                                fat_dentry_name_get(d, name);
     400                                break;
    405401                        }
    406                         rc = fat_node_get_core(&nodep, idx);
    407                         fibril_mutex_unlock(&idx->lock);
    408                         if (rc != EOK) {
    409                                 (void) fat_directory_close(&di);
     402                        if (fat_dentry_namecmp(name, component) == 0) {
     403                                /* hit */
     404                                fat_node_t *nodep;
     405                                fat_idx_t *idx = fat_idx_get_by_pos(devmap_handle,
     406                                    parentp->firstc, i * DPS(bs) + j);
     407                                if (!idx) {
     408                                        /*
     409                                         * Can happen if memory is low or if we
     410                                         * run out of 32-bit indices.
     411                                         */
     412                                        rc = block_put(b);
     413                                        return (rc == EOK) ? ENOMEM : rc;
     414                                }
     415                                rc = fat_node_get_core(&nodep, idx);
     416                                fibril_mutex_unlock(&idx->lock);
     417                                if (rc != EOK) {
     418                                        (void) block_put(b);
     419                                        return rc;
     420                                }
     421                                *rfn = FS_NODE(nodep);
     422                                rc = block_put(b);
     423                                if (rc != EOK)
     424                                        (void) fat_node_put(*rfn);
    410425                                return rc;
    411426                        }
    412                         *rfn = FS_NODE(nodep);
    413                         rc = fat_directory_close(&di);
    414                         if (rc != EOK)
    415                                 (void) fat_node_put(*rfn);
     427                }
     428                rc = block_put(b);
     429                if (rc != EOK)
    416430                        return rc;
    417                 } else {
    418                         rc = fat_directory_next(&di);
    419                         if (rc != EOK)
    420                                 break;
    421                 }
    422         }
    423         (void) fat_directory_close(&di);
     431        }
     432
    424433        *rfn = NULL;
    425434        return EOK;
     
    427436
    428437/** Instantiate a FAT in-core node. */
    429 int fat_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
     438int fat_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
    430439{
    431440        fat_node_t *nodep;
     
    433442        int rc;
    434443
    435         idxp = fat_idx_get_by_index(service_id, index);
     444        idxp = fat_idx_get_by_index(devmap_handle, index);
    436445        if (!idxp) {
    437446                *rfn = NULL;
     
    464473                if (nodep->idx) {
    465474                        fibril_mutex_lock(&ffn_mutex);
    466                         list_append(&nodep->ffn_link, &ffn_list);
     475                        list_append(&nodep->ffn_link, &ffn_head);
    467476                        fibril_mutex_unlock(&ffn_mutex);
    468477                } else {
     
    484493}
    485494
    486 int fat_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
     495int fat_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int flags)
    487496{
    488497        fat_idx_t *idxp;
     
    492501        int rc;
    493502
    494         bs = block_bb_get(service_id);
     503        bs = block_bb_get(devmap_handle);
    495504        if (flags & L_DIRECTORY) {
    496505                /* allocate a cluster */
    497                 rc = fat_alloc_clusters(bs, service_id, 1, &mcl, &lcl);
     506                rc = fat_alloc_clusters(bs, devmap_handle, 1, &mcl, &lcl);
    498507                if (rc != EOK)
    499508                        return rc;
    500509                /* populate the new cluster with unused dentries */
    501                 rc = fat_zero_cluster(bs, service_id, mcl);
     510                rc = fat_zero_cluster(bs, devmap_handle, mcl);
    502511                if (rc != EOK) {
    503                         (void) fat_free_clusters(bs, service_id, mcl);
     512                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    504513                        return rc;
    505514                }
     
    508517        rc = fat_node_get_new(&nodep);
    509518        if (rc != EOK) {
    510                 (void) fat_free_clusters(bs, service_id, mcl);
     519                (void) fat_free_clusters(bs, devmap_handle, mcl);
    511520                return rc;
    512521        }
    513         rc = fat_idx_get_new(&idxp, service_id);
    514         if (rc != EOK) {
    515                 (void) fat_free_clusters(bs, service_id, mcl); 
     522        rc = fat_idx_get_new(&idxp, devmap_handle);
     523        if (rc != EOK) {
     524                (void) fat_free_clusters(bs, devmap_handle, mcl);       
    516525                (void) fat_node_put(FS_NODE(nodep));
    517526                return rc;
     
    562571        assert(!has_children);
    563572
    564         bs = block_bb_get(nodep->idx->service_id);
     573        bs = block_bb_get(nodep->idx->devmap_handle);
    565574        if (nodep->firstc != FAT_CLST_RES0) {
    566575                assert(nodep->size);
    567576                /* Free all clusters allocated to the node. */
    568                 rc = fat_free_clusters(bs, nodep->idx->service_id,
     577                rc = fat_free_clusters(bs, nodep->idx->devmap_handle,
    569578                    nodep->firstc);
    570579        }
     
    583592        fat_bs_t *bs;
    584593        block_t *b;
    585         fat_directory_t di;
    586         fat_dentry_t de;
     594        unsigned i, j;
     595        unsigned blocks;
     596        fat_cluster_t mcl, lcl;
    587597        int rc;
    588598
     
    598608        fibril_mutex_unlock(&childp->lock);
    599609
    600         if (!fat_valid_name(name))
     610        if (!fat_dentry_name_verify(name)) {
     611                /*
     612                 * Attempt to create unsupported name.
     613                 */
    601614                return ENOTSUP;
    602 
     615        }
     616
     617        /*
     618         * Get us an unused parent node's dentry or grow the parent and allocate
     619         * a new one.
     620         */
     621       
    603622        fibril_mutex_lock(&parentp->idx->lock);
    604         bs = block_bb_get(parentp->idx->service_id);
    605         rc = fat_directory_open(parentp, &di);
     623        bs = block_bb_get(parentp->idx->devmap_handle);
     624
     625        blocks = parentp->size / BPS(bs);
     626
     627        for (i = 0; i < blocks; i++) {
     628                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     629                if (rc != EOK) {
     630                        fibril_mutex_unlock(&parentp->idx->lock);
     631                        return rc;
     632                }
     633                for (j = 0; j < DPS(bs); j++) {
     634                        d = ((fat_dentry_t *)b->data) + j;
     635                        switch (fat_classify_dentry(d)) {
     636                        case FAT_DENTRY_SKIP:
     637                        case FAT_DENTRY_VALID:
     638                                /* skipping used and meta entries */
     639                                continue;
     640                        case FAT_DENTRY_FREE:
     641                        case FAT_DENTRY_LAST:
     642                                /* found an empty slot */
     643                                goto hit;
     644                        }
     645                }
     646                rc = block_put(b);
     647                if (rc != EOK) {
     648                        fibril_mutex_unlock(&parentp->idx->lock);
     649                        return rc;
     650                }
     651        }
     652        j = 0;
     653       
     654        /*
     655         * We need to grow the parent in order to create a new unused dentry.
     656         */
     657        if (parentp->firstc == FAT_CLST_ROOT) {
     658                /* Can't grow the root directory. */
     659                fibril_mutex_unlock(&parentp->idx->lock);
     660                return ENOSPC;
     661        }
     662        rc = fat_alloc_clusters(bs, parentp->idx->devmap_handle, 1, &mcl, &lcl);
    606663        if (rc != EOK) {
    607664                fibril_mutex_unlock(&parentp->idx->lock);
    608665                return rc;
    609666        }
    610 
     667        rc = fat_zero_cluster(bs, parentp->idx->devmap_handle, mcl);
     668        if (rc != EOK) {
     669                (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
     670                fibril_mutex_unlock(&parentp->idx->lock);
     671                return rc;
     672        }
     673        rc = fat_append_clusters(bs, parentp, mcl, lcl);
     674        if (rc != EOK) {
     675                (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
     676                fibril_mutex_unlock(&parentp->idx->lock);
     677                return rc;
     678        }
     679        parentp->size += BPS(bs) * SPC(bs);
     680        parentp->dirty = true;          /* need to sync node */
     681        rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     682        if (rc != EOK) {
     683                fibril_mutex_unlock(&parentp->idx->lock);
     684                return rc;
     685        }
     686        d = (fat_dentry_t *)b->data;
     687
     688hit:
    611689        /*
    612690         * At this point we only establish the link between the parent and the
     
    615693         * dentry data is kept in the child node structure.
    616694         */
    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);
     695        memset(d, 0, sizeof(fat_dentry_t));
     696        fat_dentry_name_set(d, name);
     697        b->dirty = true;                /* need to sync block */
     698        rc = block_put(b);
     699        fibril_mutex_unlock(&parentp->idx->lock);
     700        if (rc != EOK)
    623701                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 
    631         fibril_mutex_unlock(&parentp->idx->lock);
    632702
    633703        fibril_mutex_lock(&childp->idx->lock);
    634 
     704       
    635705        if (childp->type == FAT_DIRECTORY) {
    636706                /*
     
    651721                d = (fat_dentry_t *) b->data;
    652722                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    653                     (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
     723                    (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
    654724                        memset(d, 0, sizeof(fat_dentry_t));
    655725                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     
    661731                d++;
    662732                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    663                     (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
     733                    (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
    664734                        memset(d, 0, sizeof(fat_dentry_t));
    665735                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
    666736                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    667737                        d->attr = FAT_ATTR_SUBDIR;
    668                         d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
    669                             host2uint16_t_le(FAT_CLST_ROOTPAR) :
     738                        d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
     739                            host2uint16_t_le(FAT_CLST_RES0) :
    670740                            host2uint16_t_le(parentp->firstc);
    671741                        /* TODO: initialize also the date/time members. */
     
    681751
    682752        childp->idx->pfc = parentp->firstc;
    683         childp->idx->pdi = di.pos;      /* di.pos holds absolute position of SFN entry */
     753        childp->idx->pdi = i * DPS(bs) + j;
    684754        fibril_mutex_unlock(&childp->idx->lock);
    685755
     
    701771        fat_node_t *parentp = FAT_NODE(pfn);
    702772        fat_node_t *childp = FAT_NODE(cfn);
     773        fat_bs_t *bs;
     774        fat_dentry_t *d;
     775        block_t *b;
    703776        bool has_children;
    704777        int rc;
     
    706779        if (!parentp)
    707780                return EBUSY;
    708 
     781       
    709782        rc = fat_has_children(&has_children, cfn);
    710783        if (rc != EOK)
     
    717790        assert(childp->lnkcnt == 1);
    718791        fibril_mutex_lock(&childp->idx->lock);
    719        
    720         fat_directory_t di;
    721         rc = fat_directory_open(parentp, &di);
    722         if (rc != EOK)
     792        bs = block_bb_get(childp->idx->devmap_handle);
     793
     794        rc = _fat_block_get(&b, bs, childp->idx->devmap_handle, childp->idx->pfc,
     795            NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
     796            BLOCK_FLAGS_NONE);
     797        if (rc != EOK)
    723798                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);
     799        d = (fat_dentry_t *)b->data +
     800            (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
     801        /* mark the dentry as not-currently-used */
     802        d->name[0] = FAT_DENTRY_ERASED;
     803        b->dirty = true;                /* need to sync block */
     804        rc = block_put(b);
    731805        if (rc != EOK)
    732806                goto error;
     
    747821
    748822error:
    749         (void) fat_directory_close(&di);
     823        fibril_mutex_unlock(&parentp->idx->lock);
     824        fibril_mutex_unlock(&childp->lock);
    750825        fibril_mutex_unlock(&childp->idx->lock);
    751         fibril_mutex_unlock(&childp->lock);
    752         fibril_mutex_unlock(&parentp->lock);
    753826        return rc;
    754827}
     
    767840                return EOK;
    768841        }
    769 
     842       
    770843        fibril_mutex_lock(&nodep->idx->lock);
    771         bs = block_bb_get(nodep->idx->service_id);
     844        bs = block_bb_get(nodep->idx->devmap_handle);
    772845
    773846        blocks = nodep->size / BPS(bs);
     
    775848        for (i = 0; i < blocks; i++) {
    776849                fat_dentry_t *d;
    777 
     850       
    778851                rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
    779852                if (rc != EOK) {
     
    803876                if (rc != EOK) {
    804877                        fibril_mutex_unlock(&nodep->idx->lock);
    805                         return rc;
     878                        return rc;     
    806879                }
    807880        }
     
    828901}
    829902
     903char fat_plb_get_char(unsigned pos)
     904{
     905        return fat_reg.plb_ro[pos % PLB_SIZE];
     906}
     907
    830908bool fat_is_directory(fs_node_t *fn)
    831909{
     
    838916}
    839917
    840 service_id_t fat_device_get(fs_node_t *node)
     918devmap_handle_t fat_device_get(fs_node_t *node)
    841919{
    842920        return 0;
     
    858936        .size_get = fat_size_get,
    859937        .lnkcnt_get = fat_lnkcnt_get,
     938        .plb_get_char = fat_plb_get_char,
    860939        .is_directory = fat_is_directory,
    861940        .is_file = fat_is_file,
     
    864943
    865944/*
    866  * FAT VFS_OUT operations.
     945 * VFS operations.
    867946 */
    868947
    869 static int
    870 fat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
    871     aoff64_t *size, unsigned *linkcnt)
    872 {
     948void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
     949{
     950        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    873951        enum cache_mode cmode;
    874952        fat_bs_t *bs;
    875         int rc;
     953       
     954        /* Accept the mount options */
     955        char *opts;
     956        int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     957       
     958        if (rc != EOK) {
     959                async_answer_0(rid, rc);
     960                return;
     961        }
    876962
    877963        /* Check for option enabling write through. */
     
    881967                cmode = CACHE_MODE_WB;
    882968
     969        free(opts);
     970
    883971        /* initialize libblock */
    884         rc = block_init(EXCHANGE_SERIALIZE, service_id, BS_SIZE);
    885         if (rc != EOK)
    886                 return rc;
     972        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
     973        if (rc != EOK) {
     974                async_answer_0(rid, rc);
     975                return;
     976        }
    887977
    888978        /* prepare the boot block */
    889         rc = block_bb_read(service_id, BS_BLOCK);
    890         if (rc != EOK) {
    891                 block_fini(service_id);
    892                 return rc;
     979        rc = block_bb_read(devmap_handle, BS_BLOCK);
     980        if (rc != EOK) {
     981                block_fini(devmap_handle);
     982                async_answer_0(rid, rc);
     983                return;
    893984        }
    894985
    895986        /* get the buffer with the boot sector */
    896         bs = block_bb_get(service_id);
     987        bs = block_bb_get(devmap_handle);
    897988       
    898989        if (BPS(bs) != BS_SIZE) {
    899                 block_fini(service_id);
    900                 return ENOTSUP;
     990                block_fini(devmap_handle);
     991                async_answer_0(rid, ENOTSUP);
     992                return;
    901993        }
    902994
    903995        /* Initialize the block cache */
    904         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    905         if (rc != EOK) {
    906                 block_fini(service_id);
    907                 return rc;
     996        rc = block_cache_init(devmap_handle, BPS(bs), 0 /* XXX */, cmode);
     997        if (rc != EOK) {
     998                block_fini(devmap_handle);
     999                async_answer_0(rid, rc);
     1000                return;
    9081001        }
    9091002
    9101003        /* Do some simple sanity checks on the file system. */
    911         rc = fat_sanity_check(bs, service_id);
    912         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);
    919         if (rc != EOK) {
    920                 (void) block_cache_fini(service_id);
    921                 block_fini(service_id);
    922                 return rc;
     1004        rc = fat_sanity_check(bs, devmap_handle);
     1005        if (rc != EOK) {
     1006                (void) block_cache_fini(devmap_handle);
     1007                block_fini(devmap_handle);
     1008                async_answer_0(rid, rc);
     1009                return;
     1010        }
     1011
     1012        rc = fat_idx_init_by_devmap_handle(devmap_handle);
     1013        if (rc != EOK) {
     1014                (void) block_cache_fini(devmap_handle);
     1015                block_fini(devmap_handle);
     1016                async_answer_0(rid, rc);
     1017                return;
    9231018        }
    9241019
     
    9261021        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    9271022        if (!rfn) {
    928                 (void) block_cache_fini(service_id);
    929                 block_fini(service_id);
    930                 fat_idx_fini_by_service_id(service_id);
    931                 return ENOMEM;
    932         }
    933 
     1023                (void) block_cache_fini(devmap_handle);
     1024                block_fini(devmap_handle);
     1025                fat_idx_fini_by_devmap_handle(devmap_handle);
     1026                async_answer_0(rid, ENOMEM);
     1027                return;
     1028        }
    9341029        fs_node_initialize(rfn);
    9351030        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    9361031        if (!rootp) {
    9371032                free(rfn);
    938                 (void) block_cache_fini(service_id);
    939                 block_fini(service_id);
    940                 fat_idx_fini_by_service_id(service_id);
    941                 return ENOMEM;
     1033                (void) block_cache_fini(devmap_handle);
     1034                block_fini(devmap_handle);
     1035                fat_idx_fini_by_devmap_handle(devmap_handle);
     1036                async_answer_0(rid, ENOMEM);
     1037                return;
    9421038        }
    9431039        fat_node_initialize(rootp);
    9441040
    945         fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
     1041        fat_idx_t *ridxp = fat_idx_get_by_pos(devmap_handle, FAT_CLST_ROOTPAR, 0);
    9461042        if (!ridxp) {
    9471043                free(rfn);
    9481044                free(rootp);
    949                 (void) block_cache_fini(service_id);
    950                 block_fini(service_id);
    951                 fat_idx_fini_by_service_id(service_id);
    952                 return ENOMEM;
     1045                (void) block_cache_fini(devmap_handle);
     1046                block_fini(devmap_handle);
     1047                fat_idx_fini_by_devmap_handle(devmap_handle);
     1048                async_answer_0(rid, ENOMEM);
     1049                return;
    9531050        }
    9541051        assert(ridxp->index == 0);
     
    9561053
    9571054        rootp->type = FAT_DIRECTORY;
    958         rootp->firstc = FAT_ROOT_CLST(bs);
     1055        rootp->firstc = FAT_CLST_ROOT;
    9591056        rootp->refcnt = 1;
    9601057        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 
     1058        rootp->size = RDE(bs) * sizeof(fat_dentry_t);
    9771059        rootp->idx = ridxp;
    9781060        ridxp->nodep = rootp;
    9791061        rootp->bp = rfn;
    9801062        rfn->data = rootp;
    981 
     1063       
    9821064        fibril_mutex_unlock(&ridxp->lock);
    9831065
    984         *index = ridxp->index;
    985         *size = rootp->size;
    986         *linkcnt = rootp->lnkcnt;
    987 
    988         return EOK;
    989 }
    990 
    991 static int fat_unmounted(service_id_t service_id)
    992 {
     1066        async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
     1067}
     1068
     1069void fat_mount(ipc_callid_t rid, ipc_call_t *request)
     1070{
     1071        libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1072}
     1073
     1074void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
     1075{
     1076        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    9931077        fs_node_t *fn;
    9941078        fat_node_t *nodep;
    9951079        int rc;
    9961080
    997         rc = fat_root_get(&fn, service_id);
    998         if (rc != EOK)
    999                 return rc;
     1081        rc = fat_root_get(&fn, devmap_handle);
     1082        if (rc != EOK) {
     1083                async_answer_0(rid, rc);
     1084                return;
     1085        }
    10001086        nodep = FAT_NODE(fn);
    10011087
     
    10061092        if (nodep->refcnt != 2) {
    10071093                (void) fat_node_put(fn);
    1008                 return EBUSY;
    1009         }
    1010 
     1094                async_answer_0(rid, EBUSY);
     1095                return;
     1096        }
     1097       
    10111098        /*
    10121099         * Put the root node and force it to the FAT free node list.
     
    10201107         * stop using libblock for this instance.
    10211108         */
    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);
    1026 
    1027         return EOK;
    1028 }
    1029 
    1030 static int
    1031 fat_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
    1032     size_t *rbytes)
    1033 {
     1109        (void) fat_node_fini_by_devmap_handle(devmap_handle);
     1110        fat_idx_fini_by_devmap_handle(devmap_handle);
     1111        (void) block_cache_fini(devmap_handle);
     1112        block_fini(devmap_handle);
     1113
     1114        async_answer_0(rid, EOK);
     1115}
     1116
     1117void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
     1118{
     1119        libfs_unmount(&fat_libfs_ops, rid, request);
     1120}
     1121
     1122void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
     1123{
     1124        libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1125}
     1126
     1127void fat_read(ipc_callid_t rid, ipc_call_t *request)
     1128{
     1129        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1130        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1131        aoff64_t pos =
     1132            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    10341133        fs_node_t *fn;
    10351134        fat_node_t *nodep;
     
    10391138        int rc;
    10401139
    1041         rc = fat_node_get(&fn, service_id, index);
    1042         if (rc != EOK)
    1043                 return rc;
    1044         if (!fn)
    1045                 return ENOENT;
     1140        rc = fat_node_get(&fn, devmap_handle, index);
     1141        if (rc != EOK) {
     1142                async_answer_0(rid, rc);
     1143                return;
     1144        }
     1145        if (!fn) {
     1146                async_answer_0(rid, ENOENT);
     1147                return;
     1148        }
    10461149        nodep = FAT_NODE(fn);
    10471150
     
    10511154                fat_node_put(fn);
    10521155                async_answer_0(callid, EINVAL);
    1053                 return EINVAL;
    1054         }
    1055 
    1056         bs = block_bb_get(service_id);
     1156                async_answer_0(rid, EINVAL);
     1157                return;
     1158        }
     1159
     1160        bs = block_bb_get(devmap_handle);
    10571161
    10581162        if (nodep->type == FAT_FILE) {
     
    10741178                                fat_node_put(fn);
    10751179                                async_answer_0(callid, rc);
    1076                                 return rc;
     1180                                async_answer_0(rid, rc);
     1181                                return;
    10771182                        }
    10781183                        (void) async_data_read_finalize(callid,
     
    10811186                        if (rc != EOK) {
    10821187                                fat_node_put(fn);
    1083                                 return rc;
     1188                                async_answer_0(rid, rc);
     1189                                return;
    10841190                        }
    10851191                }
    10861192        } else {
     1193                unsigned bnum;
    10871194                aoff64_t spos = pos;
    1088                 char name[FAT_LFN_NAME_SIZE];
     1195                char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    10891196                fat_dentry_t *d;
    10901197
     
    10931200                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    10941201
    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;
     1202                /*
     1203                 * Our strategy for readdir() is to use the position pointer as
     1204                 * an index into the array of all dentries. On entry, it points
     1205                 * to the first unread dentry. If we skip any dentries, we bump
     1206                 * the position pointer accordingly.
     1207                 */
     1208                bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
     1209                while (bnum < nodep->size / BPS(bs)) {
     1210                        aoff64_t o;
     1211
     1212                        rc = fat_block_get(&b, bs, nodep, bnum,
     1213                            BLOCK_FLAGS_NONE);
     1214                        if (rc != EOK)
     1215                                goto err;
     1216                        for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
     1217                            o < BPS(bs) / sizeof(fat_dentry_t);
     1218                            o++, pos++) {
     1219                                d = ((fat_dentry_t *)b->data) + o;
     1220                                switch (fat_classify_dentry(d)) {
     1221                                case FAT_DENTRY_SKIP:
     1222                                case FAT_DENTRY_FREE:
     1223                                        continue;
     1224                                case FAT_DENTRY_LAST:
     1225                                        rc = block_put(b);
     1226                                        if (rc != EOK)
     1227                                                goto err;
     1228                                        goto miss;
     1229                                default:
     1230                                case FAT_DENTRY_VALID:
     1231                                        fat_dentry_name_get(d, name);
     1232                                        rc = block_put(b);
     1233                                        if (rc != EOK)
     1234                                                goto err;
     1235                                        goto hit;
     1236                                }
     1237                        }
     1238                        rc = block_put(b);
     1239                        if (rc != EOK)
     1240                                goto err;
     1241                        bnum++;
     1242                }
     1243miss:
     1244                rc = fat_node_put(fn);
     1245                async_answer_0(callid, rc != EOK ? rc : ENOENT);
     1246                async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
     1247                return;
    11101248
    11111249err:
    11121250                (void) fat_node_put(fn);
    11131251                async_answer_0(callid, rc);
    1114                 return rc;
    1115 
    1116 miss:
    1117                 rc = fat_directory_close(&di);
    1118                 if (rc != EOK)
    1119                         goto err;
    1120                 rc = fat_node_put(fn);
    1121                 async_answer_0(callid, rc != EOK ? rc : ENOENT);
    1122                 *rbytes = 0;
    1123                 return rc != EOK ? rc : ENOENT;
     1252                async_answer_0(rid, rc);
     1253                return;
    11241254
    11251255hit:
    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);
     1256                (void) async_data_read_finalize(callid, name, str_size(name) + 1);
    11321257                bytes = (pos - spos) + 1;
    11331258        }
    11341259
    11351260        rc = fat_node_put(fn);
    1136         *rbytes = bytes;
    1137         return rc;
    1138 }
    1139 
    1140 static int
    1141 fat_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
    1142     size_t *wbytes, aoff64_t *nsize)
    1143 {
     1261        async_answer_1(rid, rc, (sysarg_t)bytes);
     1262}
     1263
     1264void fat_write(ipc_callid_t rid, ipc_call_t *request)
     1265{
     1266        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1267        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1268        aoff64_t pos =
     1269            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    11441270        fs_node_t *fn;
    11451271        fat_node_t *nodep;
    11461272        fat_bs_t *bs;
    1147         size_t bytes;
     1273        size_t bytes, size;
    11481274        block_t *b;
    11491275        aoff64_t boundary;
     
    11511277        int rc;
    11521278       
    1153         rc = fat_node_get(&fn, service_id, index);
    1154         if (rc != EOK)
    1155                 return rc;
    1156         if (!fn)
    1157                 return ENOENT;
     1279        rc = fat_node_get(&fn, devmap_handle, index);
     1280        if (rc != EOK) {
     1281                async_answer_0(rid, rc);
     1282                return;
     1283        }
     1284        if (!fn) {
     1285                async_answer_0(rid, ENOENT);
     1286                return;
     1287        }
    11581288        nodep = FAT_NODE(fn);
    1159 
     1289       
    11601290        ipc_callid_t callid;
    11611291        size_t len;
     
    11631293                (void) fat_node_put(fn);
    11641294                async_answer_0(callid, EINVAL);
    1165                 return EINVAL;
    1166         }
    1167 
    1168         bs = block_bb_get(service_id);
     1295                async_answer_0(rid, EINVAL);
     1296                return;
     1297        }
     1298
     1299        bs = block_bb_get(devmap_handle);
    11691300
    11701301        /*
     
    11731304         * but this one greatly simplifies fat_write(). Note that we can afford
    11741305         * to do this because the client must be ready to handle the return
    1175          * value signalizing a smaller number of bytes written.
    1176          */
     1306         * value signalizing a smaller number of bytes written. 
     1307         */ 
    11771308        bytes = min(len, BPS(bs) - pos % BPS(bs));
    11781309        if (bytes == BPS(bs))
    11791310                flags |= BLOCK_FLAGS_NOREAD;
    1180 
     1311       
    11811312        boundary = ROUND_UP(nodep->size, BPC(bs));
    11821313        if (pos < boundary) {
     
    11911322                        (void) fat_node_put(fn);
    11921323                        async_answer_0(callid, rc);
    1193                         return rc;
     1324                        async_answer_0(rid, rc);
     1325                        return;
    11941326                }
    11951327                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    11971329                        (void) fat_node_put(fn);
    11981330                        async_answer_0(callid, rc);
    1199                         return rc;
     1331                        async_answer_0(rid, rc);
     1332                        return;
    12001333                }
    12011334                (void) async_data_write_finalize(callid,
     
    12051338                if (rc != EOK) {
    12061339                        (void) fat_node_put(fn);
    1207                         return rc;
     1340                        async_answer_0(rid, rc);
     1341                        return;
    12081342                }
    12091343                if (pos + bytes > nodep->size) {
     
    12111345                        nodep->dirty = true;    /* need to sync node */
    12121346                }
    1213                 *wbytes = bytes;
    1214                 *nsize = nodep->size;
     1347                size = nodep->size;
    12151348                rc = fat_node_put(fn);
    1216                 return rc;
     1349                async_answer_2(rid, rc, bytes, nodep->size);
     1350                return;
    12171351        } else {
    12181352                /*
     
    12211355                 */
    12221356                unsigned nclsts;
    1223                 fat_cluster_t mcl, lcl;
    1224 
     1357                fat_cluster_t mcl, lcl; 
     1358 
    12251359                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    12261360                /* create an independent chain of nclsts clusters in all FATs */
    1227                 rc = fat_alloc_clusters(bs, service_id, nclsts, &mcl, &lcl);
     1361                rc = fat_alloc_clusters(bs, devmap_handle, nclsts, &mcl, &lcl);
    12281362                if (rc != EOK) {
    12291363                        /* could not allocate a chain of nclsts clusters */
    12301364                        (void) fat_node_put(fn);
    12311365                        async_answer_0(callid, rc);
    1232                         return rc;
     1366                        async_answer_0(rid, rc);
     1367                        return;
    12331368                }
    12341369                /* zero fill any gaps */
    12351370                rc = fat_fill_gap(bs, nodep, mcl, pos);
    12361371                if (rc != EOK) {
    1237                         (void) fat_free_clusters(bs, service_id, mcl);
     1372                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12381373                        (void) fat_node_put(fn);
    12391374                        async_answer_0(callid, rc);
    1240                         return rc;
    1241                 }
    1242                 rc = _fat_block_get(&b, bs, service_id, lcl, NULL,
     1375                        async_answer_0(rid, rc);
     1376                        return;
     1377                }
     1378                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
    12431379                    (pos / BPS(bs)) % SPC(bs), flags);
    12441380                if (rc != EOK) {
    1245                         (void) fat_free_clusters(bs, service_id, mcl);
     1381                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12461382                        (void) fat_node_put(fn);
    12471383                        async_answer_0(callid, rc);
    1248                         return rc;
     1384                        async_answer_0(rid, rc);
     1385                        return;
    12491386                }
    12501387                (void) async_data_write_finalize(callid,
     
    12531390                rc = block_put(b);
    12541391                if (rc != EOK) {
    1255                         (void) fat_free_clusters(bs, service_id, mcl);
     1392                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12561393                        (void) fat_node_put(fn);
    1257                         return rc;
     1394                        async_answer_0(rid, rc);
     1395                        return;
    12581396                }
    12591397                /*
     
    12631401                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    12641402                if (rc != EOK) {
    1265                         (void) fat_free_clusters(bs, service_id, mcl);
     1403                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    12661404                        (void) fat_node_put(fn);
    1267                         return rc;
    1268                 }
    1269                 *nsize = nodep->size = pos + bytes;
     1405                        async_answer_0(rid, rc);
     1406                        return;
     1407                }
     1408                nodep->size = size = pos + bytes;
     1409                nodep->dirty = true;            /* need to sync node */
    12701410                rc = fat_node_put(fn);
    1271                 nodep->dirty = true;            /* need to sync node */
    1272                 *wbytes = bytes;
    1273                 return rc;
    1274         }
    1275 }
    1276 
    1277 static int
    1278 fat_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
    1279 {
     1411                async_answer_2(rid, rc, bytes, size);
     1412                return;
     1413        }
     1414}
     1415
     1416void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
     1417{
     1418        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1419        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1420        aoff64_t size =
     1421            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    12801422        fs_node_t *fn;
    12811423        fat_node_t *nodep;
     
    12831425        int rc;
    12841426
    1285         rc = fat_node_get(&fn, service_id, index);
    1286         if (rc != EOK)
    1287                 return rc;
    1288         if (!fn)
    1289                 return ENOENT;
     1427        rc = fat_node_get(&fn, devmap_handle, index);
     1428        if (rc != EOK) {
     1429                async_answer_0(rid, rc);
     1430                return;
     1431        }
     1432        if (!fn) {
     1433                async_answer_0(rid, ENOENT);
     1434                return;
     1435        }
    12901436        nodep = FAT_NODE(fn);
    12911437
    1292         bs = block_bb_get(service_id);
     1438        bs = block_bb_get(devmap_handle);
    12931439
    12941440        if (nodep->size == size) {
     
    13061452                nodep->size = size;
    13071453                nodep->dirty = true;            /* need to sync node */
    1308                 rc = EOK;
     1454                rc = EOK;       
    13091455        } else {
    13101456                /*
     
    13171463                } else {
    13181464                        fat_cluster_t lastc;
    1319                         rc = fat_cluster_walk(bs, service_id, nodep->firstc,
     1465                        rc = fat_cluster_walk(bs, devmap_handle, nodep->firstc,
    13201466                            &lastc, NULL, (size - 1) / BPC(bs));
    13211467                        if (rc != EOK)
     
    13271473                nodep->size = size;
    13281474                nodep->dirty = true;            /* need to sync node */
    1329                 rc = EOK;
     1475                rc = EOK;       
    13301476        }
    13311477out:
    13321478        fat_node_put(fn);
    1333         return rc;
    1334 }
    1335 
    1336 static int fat_close(service_id_t service_id, fs_index_t index)
    1337 {
    1338         return EOK;
    1339 }
    1340 
    1341 static int fat_destroy(service_id_t service_id, fs_index_t index)
    1342 {
     1479        async_answer_0(rid, rc);
     1480        return;
     1481}
     1482
     1483void fat_close(ipc_callid_t rid, ipc_call_t *request)
     1484{
     1485        async_answer_0(rid, EOK);
     1486}
     1487
     1488void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
     1489{
     1490        devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
     1491        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    13431492        fs_node_t *fn;
    13441493        fat_node_t *nodep;
    13451494        int rc;
    13461495
    1347         rc = fat_node_get(&fn, service_id, index);
    1348         if (rc != EOK)
    1349                 return rc;
    1350         if (!fn)
    1351                 return ENOENT;
     1496        rc = fat_node_get(&fn, devmap_handle, index);
     1497        if (rc != EOK) {
     1498                async_answer_0(rid, rc);
     1499                return;
     1500        }
     1501        if (!fn) {
     1502                async_answer_0(rid, ENOENT);
     1503                return;
     1504        }
    13521505
    13531506        nodep = FAT_NODE(fn);
     
    13591512
    13601513        rc = fat_destroy_node(fn);
    1361         return rc;
    1362 }
    1363 
    1364 static int fat_sync(service_id_t service_id, fs_index_t index)
    1365 {
     1514        async_answer_0(rid, rc);
     1515}
     1516
     1517void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
     1518{
     1519        libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1520}
     1521
     1522void fat_stat(ipc_callid_t rid, ipc_call_t *request)
     1523{
     1524        libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1525}
     1526
     1527void fat_sync(ipc_callid_t rid, ipc_call_t *request)
     1528{
     1529        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1530        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1531       
    13661532        fs_node_t *fn;
    1367         int rc = fat_node_get(&fn, service_id, index);
    1368         if (rc != EOK)
    1369                 return rc;
    1370         if (!fn)
    1371                 return ENOENT;
    1372 
     1533        int rc = fat_node_get(&fn, devmap_handle, index);
     1534        if (rc != EOK) {
     1535                async_answer_0(rid, rc);
     1536                return;
     1537        }
     1538        if (!fn) {
     1539                async_answer_0(rid, ENOENT);
     1540                return;
     1541        }
     1542       
    13731543        fat_node_t *nodep = FAT_NODE(fn);
    1374 
     1544       
    13751545        nodep->dirty = true;
    13761546        rc = fat_node_sync(nodep);
    1377 
     1547       
    13781548        fat_node_put(fn);
    1379         return rc;
    1380 }
    1381 
    1382 vfs_out_ops_t fat_ops = {
    1383         .mounted = fat_mounted,
    1384         .unmounted = fat_unmounted,
    1385         .read = fat_read,
    1386         .write = fat_write,
    1387         .truncate = fat_truncate,
    1388         .close = fat_close,
    1389         .destroy = fat_destroy,
    1390         .sync = fat_sync,
    1391 };
     1549        async_answer_0(rid, rc);
     1550}
    13921551
    13931552/**
Note: See TracChangeset for help on using the changeset viewer.