Ignore:
File:
1 edited

Legend:

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

    rb72efe8 rb33870b  
    11/*
    22 * Copyright (c) 2008 Jakub Jermar
     3 * Copyright (c) 2011 Oleg Romanenko
    34 * All rights reserved.
    45 *
     
    2930/** @addtogroup fs
    3031 * @{
    31  */ 
     32 */
    3233
    3334/**
     
    3940#include "fat_dentry.h"
    4041#include "fat_fat.h"
     42#include "fat_directory.h"
    4143#include "../../vfs/vfs.h"
    4244#include <libfs.h>
    4345#include <libblock.h>
    4446#include <ipc/services.h>
    45 #include <ipc/devmap.h>
     47#include <ipc/loc.h>
    4648#include <macros.h>
    4749#include <async.h>
     
    5658#include <align.h>
    5759#include <malloc.h>
     60#include <str.h>
    5861
    5962#define FAT_NODE(node)  ((node) ? (fat_node_t *) (node)->data : NULL)
     
    7275 * Forward declarations of FAT libfs operations.
    7376 */
    74 static int fat_root_get(fs_node_t **, devmap_handle_t);
     77static int fat_root_get(fs_node_t **, service_id_t);
    7578static int fat_match(fs_node_t **, fs_node_t *, const char *);
    76 static int fat_node_get(fs_node_t **, devmap_handle_t, fs_index_t);
     79static int fat_node_get(fs_node_t **, service_id_t, fs_index_t);
    7780static int fat_node_open(fs_node_t *);
    7881static int fat_node_put(fs_node_t *);
    79 static int fat_create_node(fs_node_t **, devmap_handle_t, int);
     82static int fat_create_node(fs_node_t **, service_id_t, int);
    8083static int fat_destroy_node(fs_node_t *);
    8184static int fat_link(fs_node_t *, fs_node_t *, const char *);
     
    8588static aoff64_t fat_size_get(fs_node_t *);
    8689static unsigned fat_lnkcnt_get(fs_node_t *);
    87 static char fat_plb_get_char(unsigned);
    8890static bool fat_is_directory(fs_node_t *);
    8991static bool fat_is_file(fs_node_t *node);
    90 static devmap_handle_t fat_device_get(fs_node_t *node);
     92static service_id_t fat_service_get(fs_node_t *node);
    9193
    9294/*
     
    105107        node->dirty = false;
    106108        node->lastc_cached_valid = false;
    107         node->lastc_cached_value = FAT_CLST_LAST1;
     109        node->lastc_cached_value = 0;
    108110        node->currc_cached_valid = false;
    109111        node->currc_cached_bn = 0;
    110         node->currc_cached_value = FAT_CLST_LAST1;
     112        node->currc_cached_value = 0;
    111113}
    112114
     
    117119        fat_dentry_t *d;
    118120        int rc;
    119        
     121
    120122        assert(node->dirty);
    121123
    122         bs = block_bb_get(node->idx->devmap_handle);
    123        
     124        bs = block_bb_get(node->idx->service_id);
     125
    124126        /* Read the block that contains the dentry of interest. */
    125         rc = _fat_block_get(&b, bs, node->idx->devmap_handle, node->idx->pfc,
     127        rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
    126128            NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    127129            BLOCK_FLAGS_NONE);
     
    137139                d->attr = FAT_ATTR_SUBDIR;
    138140        }
    139        
     141
    140142        /* TODO: update other fields? (e.g time fields) */
    141        
     143
    142144        b->dirty = true;                /* need to sync block */
    143145        rc = block_put(b);
     
    145147}
    146148
    147 static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle)
     149static int fat_node_fini_by_service_id(service_id_t service_id)
    148150{
    149151        fat_node_t *nodep;
     
    169171                        goto restart;
    170172                }
    171                 if (nodep->idx->devmap_handle != devmap_handle) {
     173                if (nodep->idx->service_id != service_id) {
    172174                        fibril_mutex_unlock(&nodep->idx->lock);
    173175                        fibril_mutex_unlock(&nodep->lock);
     
    256258        fn->data = nodep;
    257259        nodep->bp = fn;
    258        
     260
    259261        *nodepp = nodep;
    260262        return EOK;
     
    292294         * We must instantiate the node from the file system.
    293295         */
    294        
     296
    295297        assert(idxp->pfc);
    296298
     
    299301                return rc;
    300302
    301         bs = block_bb_get(idxp->devmap_handle);
     303        bs = block_bb_get(idxp->service_id);
    302304
    303305        /* Read the block that contains the dentry of interest. */
    304         rc = _fat_block_get(&b, bs, idxp->devmap_handle, idxp->pfc, NULL,
     306        rc = _fat_block_get(&b, bs, idxp->service_id, idxp->pfc, NULL,
    305307            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    306308        if (rc != EOK) {
     
    310312
    311313        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
    312320        if (d->attr & FAT_ATTR_SUBDIR) {
    313                 /* 
     321                /*
    314322                 * The only directory which does not have this bit set is the
    315323                 * root directory itself. The root directory node is handled
     
    317325                 */
    318326                nodep->type = FAT_DIRECTORY;
     327
    319328                /*
    320329                 * Unfortunately, the 'size' field of the FAT dentry is not
     
    322331                 * size of the directory by walking the FAT.
    323332                 */
    324                 uint16_t clusters;
    325                 rc = fat_clusters_get(&clusters, bs, idxp->devmap_handle,
    326                     uint16_t_le2host(d->firstc));
     333                uint32_t clusters;
     334                rc = fat_clusters_get(&clusters, bs, idxp->service_id,
     335                    nodep->firstc);
    327336                if (rc != EOK) {
    328337                        (void) block_put(b);
     
    335344                nodep->size = uint32_t_le2host(d->size);
    336345        }
    337         nodep->firstc = uint16_t_le2host(d->firstc);
     346
    338347        nodep->lnkcnt = 1;
    339348        nodep->refcnt = 1;
     
    357366 */
    358367
    359 int fat_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
    360 {
    361         return fat_node_get(rfn, devmap_handle, 0);
     368int fat_root_get(fs_node_t **rfn, service_id_t service_id)
     369{
     370        return fat_node_get(rfn, service_id, 0);
    362371}
    363372
    364373int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    365374{
    366         fat_bs_t *bs;
    367375        fat_node_t *parentp = FAT_NODE(pfn);
    368         char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    369         unsigned i, j;
    370         unsigned blocks;
     376        char name[FAT_LFN_NAME_SIZE];
    371377        fat_dentry_t *d;
    372         devmap_handle_t devmap_handle;
    373         block_t *b;
     378        service_id_t service_id;
    374379        int rc;
    375380
    376381        fibril_mutex_lock(&parentp->idx->lock);
    377         devmap_handle = parentp->idx->devmap_handle;
     382        service_id = parentp->idx->service_id;
    378383        fibril_mutex_unlock(&parentp->idx->lock);
    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;
     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;
    401405                        }
    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);
     406                        rc = fat_node_get_core(&nodep, idx);
     407                        fibril_mutex_unlock(&idx->lock);
     408                        if (rc != EOK) {
     409                                (void) fat_directory_close(&di);
    425410                                return rc;
    426411                        }
    427                 }
    428                 rc = block_put(b);
    429                 if (rc != EOK)
     412                        *rfn = FS_NODE(nodep);
     413                        rc = fat_directory_close(&di);
     414                        if (rc != EOK)
     415                                (void) fat_node_put(*rfn);
    430416                        return rc;
    431         }
    432 
     417                } else {
     418                        rc = fat_directory_next(&di);
     419                        if (rc != EOK)
     420                                break;
     421                }
     422        }
     423        (void) fat_directory_close(&di);
    433424        *rfn = NULL;
    434425        return EOK;
     
    436427
    437428/** Instantiate a FAT in-core node. */
    438 int fat_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
     429int fat_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    439430{
    440431        fat_node_t *nodep;
     
    442433        int rc;
    443434
    444         idxp = fat_idx_get_by_index(devmap_handle, index);
     435        idxp = fat_idx_get_by_index(service_id, index);
    445436        if (!idxp) {
    446437                *rfn = NULL;
     
    493484}
    494485
    495 int fat_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int flags)
     486int fat_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
    496487{
    497488        fat_idx_t *idxp;
     
    501492        int rc;
    502493
    503         bs = block_bb_get(devmap_handle);
     494        bs = block_bb_get(service_id);
    504495        if (flags & L_DIRECTORY) {
    505496                /* allocate a cluster */
    506                 rc = fat_alloc_clusters(bs, devmap_handle, 1, &mcl, &lcl);
     497                rc = fat_alloc_clusters(bs, service_id, 1, &mcl, &lcl);
    507498                if (rc != EOK)
    508499                        return rc;
    509500                /* populate the new cluster with unused dentries */
    510                 rc = fat_zero_cluster(bs, devmap_handle, mcl);
    511                 if (rc != EOK) {
    512                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     501                rc = fat_zero_cluster(bs, service_id, mcl);
     502                if (rc != EOK) {
     503                        (void) fat_free_clusters(bs, service_id, mcl);
    513504                        return rc;
    514505                }
     
    517508        rc = fat_node_get_new(&nodep);
    518509        if (rc != EOK) {
    519                 (void) fat_free_clusters(bs, devmap_handle, mcl);
    520                 return rc;
    521         }
    522         rc = fat_idx_get_new(&idxp, devmap_handle);
     510                (void) fat_free_clusters(bs, service_id, mcl);
     511                return rc;
     512        }
     513        rc = fat_idx_get_new(&idxp, service_id);
    523514        if (rc != EOK) {
    524                 (void) fat_free_clusters(bs, devmap_handle, mcl);       
     515                (void) fat_free_clusters(bs, service_id, mcl); 
    525516                (void) fat_node_put(FS_NODE(nodep));
    526517                return rc;
     
    571562        assert(!has_children);
    572563
    573         bs = block_bb_get(nodep->idx->devmap_handle);
     564        bs = block_bb_get(nodep->idx->service_id);
    574565        if (nodep->firstc != FAT_CLST_RES0) {
    575566                assert(nodep->size);
    576567                /* Free all clusters allocated to the node. */
    577                 rc = fat_free_clusters(bs, nodep->idx->devmap_handle,
     568                rc = fat_free_clusters(bs, nodep->idx->service_id,
    578569                    nodep->firstc);
    579570        }
     
    592583        fat_bs_t *bs;
    593584        block_t *b;
    594         unsigned i, j;
    595         unsigned blocks;
    596         fat_cluster_t mcl, lcl;
     585        fat_directory_t di;
     586        fat_dentry_t de;
    597587        int rc;
    598588
     
    608598        fibril_mutex_unlock(&childp->lock);
    609599
    610         if (!fat_dentry_name_verify(name)) {
    611                 /*
    612                  * Attempt to create unsupported name.
    613                  */
     600        if (!fat_valid_name(name))
    614601                return ENOTSUP;
    615         }
    616 
    617         /*
    618          * Get us an unused parent node's dentry or grow the parent and allocate
    619          * a new one.
    620          */
    621        
     602
    622603        fibril_mutex_lock(&parentp->idx->lock);
    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);
     604        bs = block_bb_get(parentp->idx->service_id);
     605        rc = fat_directory_open(parentp, &di);
    663606        if (rc != EOK) {
    664607                fibril_mutex_unlock(&parentp->idx->lock);
    665608                return rc;
    666609        }
    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 
    688 hit:
     610
    689611        /*
    690612         * At this point we only establish the link between the parent and the
     
    693615         * dentry data is kept in the child node structure.
    694616         */
    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);
     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
    699631        fibril_mutex_unlock(&parentp->idx->lock);
    700         if (rc != EOK)
    701                 return rc;
    702632
    703633        fibril_mutex_lock(&childp->idx->lock);
    704        
     634
    705635        if (childp->type == FAT_DIRECTORY) {
    706636                /*
     
    721651                d = (fat_dentry_t *) b->data;
    722652                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    723                     (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
     653                    (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
    724654                        memset(d, 0, sizeof(fat_dentry_t));
    725655                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     
    731661                d++;
    732662                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    733                     (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
     663                    (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
    734664                        memset(d, 0, sizeof(fat_dentry_t));
    735665                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
    736666                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    737667                        d->attr = FAT_ATTR_SUBDIR;
    738                         d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
    739                             host2uint16_t_le(FAT_CLST_RES0) :
     668                        d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
     669                            host2uint16_t_le(FAT_CLST_ROOTPAR) :
    740670                            host2uint16_t_le(parentp->firstc);
    741671                        /* TODO: initialize also the date/time members. */
     
    751681
    752682        childp->idx->pfc = parentp->firstc;
    753         childp->idx->pdi = i * DPS(bs) + j;
     683        childp->idx->pdi = di.pos;      /* di.pos holds absolute position of SFN entry */
    754684        fibril_mutex_unlock(&childp->idx->lock);
    755685
     
    771701        fat_node_t *parentp = FAT_NODE(pfn);
    772702        fat_node_t *childp = FAT_NODE(cfn);
    773         fat_bs_t *bs;
    774         fat_dentry_t *d;
    775         block_t *b;
    776703        bool has_children;
    777704        int rc;
     
    779706        if (!parentp)
    780707                return EBUSY;
    781        
     708
    782709        rc = fat_has_children(&has_children, cfn);
    783710        if (rc != EOK)
     
    790717        assert(childp->lnkcnt == 1);
    791718        fibril_mutex_lock(&childp->idx->lock);
    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)
     719       
     720        fat_directory_t di;
     721        rc = fat_directory_open(parentp, &di);
     722        if (rc != EOK)
    798723                goto error;
    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);
     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);
    805731        if (rc != EOK)
    806732                goto error;
     
    821747
    822748error:
    823         fibril_mutex_unlock(&parentp->idx->lock);
     749        (void) fat_directory_close(&di);
     750        fibril_mutex_unlock(&childp->idx->lock);
    824751        fibril_mutex_unlock(&childp->lock);
    825         fibril_mutex_unlock(&childp->idx->lock);
     752        fibril_mutex_unlock(&parentp->lock);
    826753        return rc;
    827754}
     
    840767                return EOK;
    841768        }
    842        
     769
    843770        fibril_mutex_lock(&nodep->idx->lock);
    844         bs = block_bb_get(nodep->idx->devmap_handle);
     771        bs = block_bb_get(nodep->idx->service_id);
    845772
    846773        blocks = nodep->size / BPS(bs);
     
    848775        for (i = 0; i < blocks; i++) {
    849776                fat_dentry_t *d;
    850        
     777
    851778                rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
    852779                if (rc != EOK) {
     
    876803                if (rc != EOK) {
    877804                        fibril_mutex_unlock(&nodep->idx->lock);
    878                         return rc;     
     805                        return rc;
    879806                }
    880807        }
     
    901828}
    902829
    903 char fat_plb_get_char(unsigned pos)
    904 {
    905         return fat_reg.plb_ro[pos % PLB_SIZE];
    906 }
    907 
    908830bool fat_is_directory(fs_node_t *fn)
    909831{
     
    916838}
    917839
    918 devmap_handle_t fat_device_get(fs_node_t *node)
     840service_id_t fat_service_get(fs_node_t *node)
    919841{
    920842        return 0;
     
    936858        .size_get = fat_size_get,
    937859        .lnkcnt_get = fat_lnkcnt_get,
    938         .plb_get_char = fat_plb_get_char,
    939860        .is_directory = fat_is_directory,
    940861        .is_file = fat_is_file,
    941         .device_get = fat_device_get
     862        .service_get = fat_service_get
    942863};
    943864
    944865/*
    945  * VFS operations.
     866 * FAT VFS_OUT operations.
    946867 */
    947868
    948 void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
    949 {
    950         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     869static int
     870fat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
     871    aoff64_t *size, unsigned *linkcnt)
     872{
    951873        enum cache_mode cmode;
    952874        fat_bs_t *bs;
    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         }
     875        int rc;
    962876
    963877        /* Check for option enabling write through. */
     
    967881                cmode = CACHE_MODE_WB;
    968882
    969         free(opts);
    970 
    971883        /* initialize libblock */
    972         rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
     884        rc = block_init(EXCHANGE_SERIALIZE, service_id, BS_SIZE);
     885        if (rc != EOK)
     886                return rc;
     887
     888        /* prepare the boot block */
     889        rc = block_bb_read(service_id, BS_BLOCK);
    973890        if (rc != EOK) {
    974                 async_answer_0(rid, rc);
    975                 return;
    976         }
    977 
    978         /* prepare the boot block */
    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;
     891                block_fini(service_id);
     892                return rc;
    984893        }
    985894
    986895        /* get the buffer with the boot sector */
    987         bs = block_bb_get(devmap_handle);
     896        bs = block_bb_get(service_id);
    988897       
    989898        if (BPS(bs) != BS_SIZE) {
    990                 block_fini(devmap_handle);
    991                 async_answer_0(rid, ENOTSUP);
    992                 return;
     899                block_fini(service_id);
     900                return ENOTSUP;
    993901        }
    994902
    995903        /* Initialize the block cache */
    996         rc = block_cache_init(devmap_handle, BPS(bs), 0 /* XXX */, cmode);
     904        rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    997905        if (rc != EOK) {
    998                 block_fini(devmap_handle);
    999                 async_answer_0(rid, rc);
    1000                 return;
     906                block_fini(service_id);
     907                return rc;
    1001908        }
    1002909
    1003910        /* Do some simple sanity checks on the file system. */
    1004         rc = fat_sanity_check(bs, devmap_handle);
     911        rc = fat_sanity_check(bs, service_id);
    1005912        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);
     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);
    1013919        if (rc != EOK) {
    1014                 (void) block_cache_fini(devmap_handle);
    1015                 block_fini(devmap_handle);
    1016                 async_answer_0(rid, rc);
    1017                 return;
     920                (void) block_cache_fini(service_id);
     921                block_fini(service_id);
     922                return rc;
    1018923        }
    1019924
     
    1021926        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    1022927        if (!rfn) {
    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         }
     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
    1029934        fs_node_initialize(rfn);
    1030935        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    1031936        if (!rootp) {
    1032937                free(rfn);
    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;
     938                (void) block_cache_fini(service_id);
     939                block_fini(service_id);
     940                fat_idx_fini_by_service_id(service_id);
     941                return ENOMEM;
    1038942        }
    1039943        fat_node_initialize(rootp);
    1040944
    1041         fat_idx_t *ridxp = fat_idx_get_by_pos(devmap_handle, FAT_CLST_ROOTPAR, 0);
     945        fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
    1042946        if (!ridxp) {
    1043947                free(rfn);
    1044948                free(rootp);
    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;
     949                (void) block_cache_fini(service_id);
     950                block_fini(service_id);
     951                fat_idx_fini_by_service_id(service_id);
     952                return ENOMEM;
    1050953        }
    1051954        assert(ridxp->index == 0);
     
    1053956
    1054957        rootp->type = FAT_DIRECTORY;
    1055         rootp->firstc = FAT_CLST_ROOT;
     958        rootp->firstc = FAT_ROOT_CLST(bs);
    1056959        rootp->refcnt = 1;
    1057960        rootp->lnkcnt = 0;      /* FS root is not linked */
    1058         rootp->size = RDE(bs) * sizeof(fat_dentry_t);
     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
    1059977        rootp->idx = ridxp;
    1060978        ridxp->nodep = rootp;
    1061979        rootp->bp = rfn;
    1062980        rfn->data = rootp;
    1063        
     981
    1064982        fibril_mutex_unlock(&ridxp->lock);
    1065983
    1066         async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
    1067 }
    1068 
    1069 void 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 
    1074 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1075 {
    1076         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     984        *index = ridxp->index;
     985        *size = rootp->size;
     986        *linkcnt = rootp->lnkcnt;
     987
     988        return EOK;
     989}
     990
     991static int fat_unmounted(service_id_t service_id)
     992{
    1077993        fs_node_t *fn;
    1078994        fat_node_t *nodep;
    1079995        int rc;
    1080996
    1081         rc = fat_root_get(&fn, devmap_handle);
    1082         if (rc != EOK) {
    1083                 async_answer_0(rid, rc);
    1084                 return;
    1085         }
     997        rc = fat_root_get(&fn, service_id);
     998        if (rc != EOK)
     999                return rc;
    10861000        nodep = FAT_NODE(fn);
    10871001
     
    10921006        if (nodep->refcnt != 2) {
    10931007                (void) fat_node_put(fn);
    1094                 async_answer_0(rid, EBUSY);
    1095                 return;
    1096         }
    1097        
     1008                return EBUSY;
     1009        }
     1010
    10981011        /*
    10991012         * Put the root node and force it to the FAT free node list.
     
    11071020         * stop using libblock for this instance.
    11081021         */
    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 
    1117 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1118 {
    1119         libfs_unmount(&fat_libfs_ops, rid, request);
    1120 }
    1121 
    1122 void 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 
    1127 void 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));
     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
     1030static int
     1031fat_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1032    size_t *rbytes)
     1033{
    11331034        fs_node_t *fn;
    11341035        fat_node_t *nodep;
     
    11381039        int rc;
    11391040
    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         }
     1041        rc = fat_node_get(&fn, service_id, index);
     1042        if (rc != EOK)
     1043                return rc;
     1044        if (!fn)
     1045                return ENOENT;
    11491046        nodep = FAT_NODE(fn);
    11501047
     
    11541051                fat_node_put(fn);
    11551052                async_answer_0(callid, EINVAL);
    1156                 async_answer_0(rid, EINVAL);
    1157                 return;
    1158         }
    1159 
    1160         bs = block_bb_get(devmap_handle);
     1053                return EINVAL;
     1054        }
     1055
     1056        bs = block_bb_get(service_id);
    11611057
    11621058        if (nodep->type == FAT_FILE) {
     
    11781074                                fat_node_put(fn);
    11791075                                async_answer_0(callid, rc);
    1180                                 async_answer_0(rid, rc);
    1181                                 return;
     1076                                return rc;
    11821077                        }
    11831078                        (void) async_data_read_finalize(callid,
     
    11861081                        if (rc != EOK) {
    11871082                                fat_node_put(fn);
    1188                                 async_answer_0(rid, rc);
    1189                                 return;
     1083                                return rc;
    11901084                        }
    11911085                }
    11921086        } else {
    1193                 unsigned bnum;
    11941087                aoff64_t spos = pos;
    1195                 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     1088                char name[FAT_LFN_NAME_SIZE];
    11961089                fat_dentry_t *d;
    11971090
     
    12001093                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    12011094
    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                 }
    1243 miss:
    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;
     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;
    12481110
    12491111err:
    12501112                (void) fat_node_put(fn);
    12511113                async_answer_0(callid, rc);
    1252                 async_answer_0(rid, rc);
    1253                 return;
     1114                return rc;
     1115
     1116miss:
     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;
    12541124
    12551125hit:
    1256                 (void) async_data_read_finalize(callid, name, str_size(name) + 1);
     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);
    12571132                bytes = (pos - spos) + 1;
    12581133        }
    12591134
    12601135        rc = fat_node_put(fn);
    1261         async_answer_1(rid, rc, (sysarg_t)bytes);
    1262 }
    1263 
    1264 void 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));
     1136        *rbytes = bytes;
     1137        return rc;
     1138}
     1139
     1140static int
     1141fat_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1142    size_t *wbytes, aoff64_t *nsize)
     1143{
    12701144        fs_node_t *fn;
    12711145        fat_node_t *nodep;
    12721146        fat_bs_t *bs;
    1273         size_t bytes, size;
     1147        size_t bytes;
    12741148        block_t *b;
    12751149        aoff64_t boundary;
     
    12771151        int rc;
    12781152       
    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         }
     1153        rc = fat_node_get(&fn, service_id, index);
     1154        if (rc != EOK)
     1155                return rc;
     1156        if (!fn)
     1157                return ENOENT;
    12881158        nodep = FAT_NODE(fn);
    1289        
     1159
    12901160        ipc_callid_t callid;
    12911161        size_t len;
     
    12931163                (void) fat_node_put(fn);
    12941164                async_answer_0(callid, EINVAL);
    1295                 async_answer_0(rid, EINVAL);
    1296                 return;
    1297         }
    1298 
    1299         bs = block_bb_get(devmap_handle);
     1165                return EINVAL;
     1166        }
     1167
     1168        bs = block_bb_get(service_id);
    13001169
    13011170        /*
     
    13041173         * but this one greatly simplifies fat_write(). Note that we can afford
    13051174         * to do this because the client must be ready to handle the return
    1306          * value signalizing a smaller number of bytes written. 
    1307          */ 
     1175         * value signalizing a smaller number of bytes written.
     1176         */
    13081177        bytes = min(len, BPS(bs) - pos % BPS(bs));
    13091178        if (bytes == BPS(bs))
    13101179                flags |= BLOCK_FLAGS_NOREAD;
    1311        
     1180
    13121181        boundary = ROUND_UP(nodep->size, BPC(bs));
    13131182        if (pos < boundary) {
     
    13221191                        (void) fat_node_put(fn);
    13231192                        async_answer_0(callid, rc);
    1324                         async_answer_0(rid, rc);
    1325                         return;
     1193                        return rc;
    13261194                }
    13271195                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    13291197                        (void) fat_node_put(fn);
    13301198                        async_answer_0(callid, rc);
    1331                         async_answer_0(rid, rc);
    1332                         return;
     1199                        return rc;
    13331200                }
    13341201                (void) async_data_write_finalize(callid,
     
    13381205                if (rc != EOK) {
    13391206                        (void) fat_node_put(fn);
    1340                         async_answer_0(rid, rc);
    1341                         return;
     1207                        return rc;
    13421208                }
    13431209                if (pos + bytes > nodep->size) {
     
    13451211                        nodep->dirty = true;    /* need to sync node */
    13461212                }
    1347                 size = nodep->size;
     1213                *wbytes = bytes;
     1214                *nsize = nodep->size;
    13481215                rc = fat_node_put(fn);
    1349                 async_answer_2(rid, rc, bytes, nodep->size);
    1350                 return;
     1216                return rc;
    13511217        } else {
    13521218                /*
     
    13551221                 */
    13561222                unsigned nclsts;
    1357                 fat_cluster_t mcl, lcl; 
    1358  
     1223                fat_cluster_t mcl, lcl;
     1224
    13591225                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    13601226                /* create an independent chain of nclsts clusters in all FATs */
    1361                 rc = fat_alloc_clusters(bs, devmap_handle, nclsts, &mcl, &lcl);
     1227                rc = fat_alloc_clusters(bs, service_id, nclsts, &mcl, &lcl);
    13621228                if (rc != EOK) {
    13631229                        /* could not allocate a chain of nclsts clusters */
    13641230                        (void) fat_node_put(fn);
    13651231                        async_answer_0(callid, rc);
    1366                         async_answer_0(rid, rc);
    1367                         return;
     1232                        return rc;
    13681233                }
    13691234                /* zero fill any gaps */
    13701235                rc = fat_fill_gap(bs, nodep, mcl, pos);
    13711236                if (rc != EOK) {
    1372                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1237                        (void) fat_free_clusters(bs, service_id, mcl);
    13731238                        (void) fat_node_put(fn);
    13741239                        async_answer_0(callid, rc);
    1375                         async_answer_0(rid, rc);
    1376                         return;
    1377                 }
    1378                 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     1240                        return rc;
     1241                }
     1242                rc = _fat_block_get(&b, bs, service_id, lcl, NULL,
    13791243                    (pos / BPS(bs)) % SPC(bs), flags);
    13801244                if (rc != EOK) {
    1381                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1245                        (void) fat_free_clusters(bs, service_id, mcl);
    13821246                        (void) fat_node_put(fn);
    13831247                        async_answer_0(callid, rc);
    1384                         async_answer_0(rid, rc);
    1385                         return;
     1248                        return rc;
    13861249                }
    13871250                (void) async_data_write_finalize(callid,
     
    13901253                rc = block_put(b);
    13911254                if (rc != EOK) {
    1392                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1255                        (void) fat_free_clusters(bs, service_id, mcl);
    13931256                        (void) fat_node_put(fn);
    1394                         async_answer_0(rid, rc);
    1395                         return;
     1257                        return rc;
    13961258                }
    13971259                /*
     
    14011263                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    14021264                if (rc != EOK) {
    1403                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1265                        (void) fat_free_clusters(bs, service_id, mcl);
    14041266                        (void) fat_node_put(fn);
    1405                         async_answer_0(rid, rc);
    1406                         return;
    1407                 }
    1408                 nodep->size = size = pos + bytes;
     1267                        return rc;
     1268                }
     1269                *nsize = nodep->size = pos + bytes;
     1270                rc = fat_node_put(fn);
    14091271                nodep->dirty = true;            /* need to sync node */
    1410                 rc = fat_node_put(fn);
    1411                 async_answer_2(rid, rc, bytes, size);
    1412                 return;
    1413         }
    1414 }
    1415 
    1416 void 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));
     1272                *wbytes = bytes;
     1273                return rc;
     1274        }
     1275}
     1276
     1277static int
     1278fat_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
     1279{
    14221280        fs_node_t *fn;
    14231281        fat_node_t *nodep;
     
    14251283        int rc;
    14261284
    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         }
     1285        rc = fat_node_get(&fn, service_id, index);
     1286        if (rc != EOK)
     1287                return rc;
     1288        if (!fn)
     1289                return ENOENT;
    14361290        nodep = FAT_NODE(fn);
    14371291
    1438         bs = block_bb_get(devmap_handle);
     1292        bs = block_bb_get(service_id);
    14391293
    14401294        if (nodep->size == size) {
     
    14521306                nodep->size = size;
    14531307                nodep->dirty = true;            /* need to sync node */
    1454                 rc = EOK;       
     1308                rc = EOK;
    14551309        } else {
    14561310                /*
     
    14631317                } else {
    14641318                        fat_cluster_t lastc;
    1465                         rc = fat_cluster_walk(bs, devmap_handle, nodep->firstc,
     1319                        rc = fat_cluster_walk(bs, service_id, nodep->firstc,
    14661320                            &lastc, NULL, (size - 1) / BPC(bs));
    14671321                        if (rc != EOK)
     
    14731327                nodep->size = size;
    14741328                nodep->dirty = true;            /* need to sync node */
    1475                 rc = EOK;       
     1329                rc = EOK;
    14761330        }
    14771331out:
    14781332        fat_node_put(fn);
    1479         async_answer_0(rid, rc);
    1480         return;
    1481 }
    1482 
    1483 void fat_close(ipc_callid_t rid, ipc_call_t *request)
    1484 {
    1485         async_answer_0(rid, EOK);
    1486 }
    1487 
    1488 void 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);
     1333        return rc;
     1334}
     1335
     1336static int fat_close(service_id_t service_id, fs_index_t index)
     1337{
     1338        return EOK;
     1339}
     1340
     1341static int fat_destroy(service_id_t service_id, fs_index_t index)
     1342{
    14921343        fs_node_t *fn;
    14931344        fat_node_t *nodep;
    14941345        int rc;
    14951346
    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         }
     1347        rc = fat_node_get(&fn, service_id, index);
     1348        if (rc != EOK)
     1349                return rc;
     1350        if (!fn)
     1351                return ENOENT;
    15051352
    15061353        nodep = FAT_NODE(fn);
     
    15121359
    15131360        rc = fat_destroy_node(fn);
    1514         async_answer_0(rid, rc);
    1515 }
    1516 
    1517 void 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 
    1522 void 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 
    1527 void 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        
     1361        return rc;
     1362}
     1363
     1364static int fat_sync(service_id_t service_id, fs_index_t index)
     1365{
    15321366        fs_node_t *fn;
    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        
     1367        int rc = fat_node_get(&fn, service_id, index);
     1368        if (rc != EOK)
     1369                return rc;
     1370        if (!fn)
     1371                return ENOENT;
     1372
    15431373        fat_node_t *nodep = FAT_NODE(fn);
    1544        
     1374
    15451375        nodep->dirty = true;
    15461376        rc = fat_node_sync(nodep);
    1547        
     1377
    15481378        fat_node_put(fn);
    1549         async_answer_0(rid, rc);
    1550 }
     1379        return rc;
     1380}
     1381
     1382vfs_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};
    15511392
    15521393/**
Note: See TracChangeset for help on using the changeset viewer.