Changeset 925a21e in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2011-09-24T14:20:29Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5bf76c1
Parents:
867e2555 (diff), 1ab4aca (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r867e2555 r925a21e  
    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 *);
     
    8790static bool fat_is_directory(fs_node_t *);
    8891static bool fat_is_file(fs_node_t *node);
    89 static devmap_handle_t fat_device_get(fs_node_t *node);
     92static service_id_t fat_service_get(fs_node_t *node);
    9093
    9194/*
     
    104107        node->dirty = false;
    105108        node->lastc_cached_valid = false;
    106         node->lastc_cached_value = FAT_CLST_LAST1;
     109        node->lastc_cached_value = 0;
    107110        node->currc_cached_valid = false;
    108111        node->currc_cached_bn = 0;
    109         node->currc_cached_value = FAT_CLST_LAST1;
     112        node->currc_cached_value = 0;
    110113}
    111114
     
    116119        fat_dentry_t *d;
    117120        int rc;
    118        
     121
    119122        assert(node->dirty);
    120123
    121         bs = block_bb_get(node->idx->devmap_handle);
    122        
     124        bs = block_bb_get(node->idx->service_id);
     125
    123126        /* Read the block that contains the dentry of interest. */
    124         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,
    125128            NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    126129            BLOCK_FLAGS_NONE);
     
    136139                d->attr = FAT_ATTR_SUBDIR;
    137140        }
    138        
     141
    139142        /* TODO: update other fields? (e.g time fields) */
    140        
     143
    141144        b->dirty = true;                /* need to sync block */
    142145        rc = block_put(b);
     
    144147}
    145148
    146 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)
    147150{
    148151        fat_node_t *nodep;
     
    168171                        goto restart;
    169172                }
    170                 if (nodep->idx->devmap_handle != devmap_handle) {
     173                if (nodep->idx->service_id != service_id) {
    171174                        fibril_mutex_unlock(&nodep->idx->lock);
    172175                        fibril_mutex_unlock(&nodep->lock);
     
    255258        fn->data = nodep;
    256259        nodep->bp = fn;
    257        
     260
    258261        *nodepp = nodep;
    259262        return EOK;
     
    291294         * We must instantiate the node from the file system.
    292295         */
    293        
     296
    294297        assert(idxp->pfc);
    295298
     
    298301                return rc;
    299302
    300         bs = block_bb_get(idxp->devmap_handle);
     303        bs = block_bb_get(idxp->service_id);
    301304
    302305        /* Read the block that contains the dentry of interest. */
    303         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,
    304307            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    305308        if (rc != EOK) {
     
    309312
    310313        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
    311320        if (d->attr & FAT_ATTR_SUBDIR) {
    312                 /* 
     321                /*
    313322                 * The only directory which does not have this bit set is the
    314323                 * root directory itself. The root directory node is handled
     
    316325                 */
    317326                nodep->type = FAT_DIRECTORY;
     327
    318328                /*
    319329                 * Unfortunately, the 'size' field of the FAT dentry is not
     
    321331                 * size of the directory by walking the FAT.
    322332                 */
    323                 uint16_t clusters;
    324                 rc = fat_clusters_get(&clusters, bs, idxp->devmap_handle,
    325                     uint16_t_le2host(d->firstc));
     333                uint32_t clusters;
     334                rc = fat_clusters_get(&clusters, bs, idxp->service_id,
     335                    nodep->firstc);
    326336                if (rc != EOK) {
    327337                        (void) block_put(b);
     
    334344                nodep->size = uint32_t_le2host(d->size);
    335345        }
    336         nodep->firstc = uint16_t_le2host(d->firstc);
     346
    337347        nodep->lnkcnt = 1;
    338348        nodep->refcnt = 1;
     
    356366 */
    357367
    358 int fat_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
    359 {
    360         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);
    361371}
    362372
    363373int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    364374{
    365         fat_bs_t *bs;
    366375        fat_node_t *parentp = FAT_NODE(pfn);
    367         char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    368         unsigned i, j;
    369         unsigned blocks;
     376        char name[FAT_LFN_NAME_SIZE];
    370377        fat_dentry_t *d;
    371         devmap_handle_t devmap_handle;
    372         block_t *b;
     378        service_id_t service_id;
    373379        int rc;
    374380
    375381        fibril_mutex_lock(&parentp->idx->lock);
    376         devmap_handle = parentp->idx->devmap_handle;
     382        service_id = parentp->idx->service_id;
    377383        fibril_mutex_unlock(&parentp->idx->lock);
    378 
    379         bs = block_bb_get(devmap_handle);
    380         blocks = parentp->size / BPS(bs);
    381         for (i = 0; i < blocks; i++) {
    382                 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    383                 if (rc != EOK)
    384                         return rc;
    385                 for (j = 0; j < DPS(bs); j++) {
    386                         d = ((fat_dentry_t *)b->data) + j;
    387                         switch (fat_classify_dentry(d)) {
    388                         case FAT_DENTRY_SKIP:
    389                         case FAT_DENTRY_FREE:
    390                                 continue;
    391                         case FAT_DENTRY_LAST:
    392                                 /* miss */
    393                                 rc = block_put(b);
    394                                 *rfn = NULL;
    395                                 return rc;
    396                         default:
    397                         case FAT_DENTRY_VALID:
    398                                 fat_dentry_name_get(d, name);
    399                                 break;
     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;
    400405                        }
    401                         if (fat_dentry_namecmp(name, component) == 0) {
    402                                 /* hit */
    403                                 fat_node_t *nodep;
    404                                 fat_idx_t *idx = fat_idx_get_by_pos(devmap_handle,
    405                                     parentp->firstc, i * DPS(bs) + j);
    406                                 if (!idx) {
    407                                         /*
    408                                          * Can happen if memory is low or if we
    409                                          * run out of 32-bit indices.
    410                                          */
    411                                         rc = block_put(b);
    412                                         return (rc == EOK) ? ENOMEM : rc;
    413                                 }
    414                                 rc = fat_node_get_core(&nodep, idx);
    415                                 fibril_mutex_unlock(&idx->lock);
    416                                 if (rc != EOK) {
    417                                         (void) block_put(b);
    418                                         return rc;
    419                                 }
    420                                 *rfn = FS_NODE(nodep);
    421                                 rc = block_put(b);
    422                                 if (rc != EOK)
    423                                         (void) fat_node_put(*rfn);
     406                        rc = fat_node_get_core(&nodep, idx);
     407                        fibril_mutex_unlock(&idx->lock);
     408                        if (rc != EOK) {
     409                                (void) fat_directory_close(&di);
    424410                                return rc;
    425411                        }
    426                 }
    427                 rc = block_put(b);
    428                 if (rc != EOK)
     412                        *rfn = FS_NODE(nodep);
     413                        rc = fat_directory_close(&di);
     414                        if (rc != EOK)
     415                                (void) fat_node_put(*rfn);
    429416                        return rc;
    430         }
    431 
     417                } else {
     418                        rc = fat_directory_next(&di);
     419                        if (rc != EOK)
     420                                break;
     421                }
     422        }
     423        (void) fat_directory_close(&di);
    432424        *rfn = NULL;
    433425        return EOK;
     
    435427
    436428/** Instantiate a FAT in-core node. */
    437 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)
    438430{
    439431        fat_node_t *nodep;
     
    441433        int rc;
    442434
    443         idxp = fat_idx_get_by_index(devmap_handle, index);
     435        idxp = fat_idx_get_by_index(service_id, index);
    444436        if (!idxp) {
    445437                *rfn = NULL;
     
    492484}
    493485
    494 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)
    495487{
    496488        fat_idx_t *idxp;
     
    500492        int rc;
    501493
    502         bs = block_bb_get(devmap_handle);
     494        bs = block_bb_get(service_id);
    503495        if (flags & L_DIRECTORY) {
    504496                /* allocate a cluster */
    505                 rc = fat_alloc_clusters(bs, devmap_handle, 1, &mcl, &lcl);
     497                rc = fat_alloc_clusters(bs, service_id, 1, &mcl, &lcl);
    506498                if (rc != EOK)
    507499                        return rc;
    508500                /* populate the new cluster with unused dentries */
    509                 rc = fat_zero_cluster(bs, devmap_handle, mcl);
    510                 if (rc != EOK) {
    511                         (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);
    512504                        return rc;
    513505                }
     
    516508        rc = fat_node_get_new(&nodep);
    517509        if (rc != EOK) {
    518                 (void) fat_free_clusters(bs, devmap_handle, mcl);
    519                 return rc;
    520         }
    521         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);
    522514        if (rc != EOK) {
    523                 (void) fat_free_clusters(bs, devmap_handle, mcl);       
     515                (void) fat_free_clusters(bs, service_id, mcl); 
    524516                (void) fat_node_put(FS_NODE(nodep));
    525517                return rc;
     
    570562        assert(!has_children);
    571563
    572         bs = block_bb_get(nodep->idx->devmap_handle);
     564        bs = block_bb_get(nodep->idx->service_id);
    573565        if (nodep->firstc != FAT_CLST_RES0) {
    574566                assert(nodep->size);
    575567                /* Free all clusters allocated to the node. */
    576                 rc = fat_free_clusters(bs, nodep->idx->devmap_handle,
     568                rc = fat_free_clusters(bs, nodep->idx->service_id,
    577569                    nodep->firstc);
    578570        }
     
    591583        fat_bs_t *bs;
    592584        block_t *b;
    593         unsigned i, j;
    594         unsigned blocks;
    595         fat_cluster_t mcl, lcl;
     585        fat_directory_t di;
     586        fat_dentry_t de;
    596587        int rc;
    597588
     
    607598        fibril_mutex_unlock(&childp->lock);
    608599
    609         if (!fat_dentry_name_verify(name)) {
    610                 /*
    611                  * Attempt to create unsupported name.
    612                  */
     600        if (!fat_valid_name(name))
    613601                return ENOTSUP;
    614         }
    615 
    616         /*
    617          * Get us an unused parent node's dentry or grow the parent and allocate
    618          * a new one.
    619          */
    620        
     602
    621603        fibril_mutex_lock(&parentp->idx->lock);
    622         bs = block_bb_get(parentp->idx->devmap_handle);
    623 
    624         blocks = parentp->size / BPS(bs);
    625 
    626         for (i = 0; i < blocks; i++) {
    627                 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    628                 if (rc != EOK) {
    629                         fibril_mutex_unlock(&parentp->idx->lock);
    630                         return rc;
    631                 }
    632                 for (j = 0; j < DPS(bs); j++) {
    633                         d = ((fat_dentry_t *)b->data) + j;
    634                         switch (fat_classify_dentry(d)) {
    635                         case FAT_DENTRY_SKIP:
    636                         case FAT_DENTRY_VALID:
    637                                 /* skipping used and meta entries */
    638                                 continue;
    639                         case FAT_DENTRY_FREE:
    640                         case FAT_DENTRY_LAST:
    641                                 /* found an empty slot */
    642                                 goto hit;
    643                         }
    644                 }
    645                 rc = block_put(b);
    646                 if (rc != EOK) {
    647                         fibril_mutex_unlock(&parentp->idx->lock);
    648                         return rc;
    649                 }
    650         }
    651         j = 0;
    652        
    653         /*
    654          * We need to grow the parent in order to create a new unused dentry.
    655          */
    656         if (parentp->firstc == FAT_CLST_ROOT) {
    657                 /* Can't grow the root directory. */
    658                 fibril_mutex_unlock(&parentp->idx->lock);
    659                 return ENOSPC;
    660         }
    661         rc = fat_alloc_clusters(bs, parentp->idx->devmap_handle, 1, &mcl, &lcl);
     604        bs = block_bb_get(parentp->idx->service_id);
     605        rc = fat_directory_open(parentp, &di);
    662606        if (rc != EOK) {
    663607                fibril_mutex_unlock(&parentp->idx->lock);
    664608                return rc;
    665609        }
    666         rc = fat_zero_cluster(bs, parentp->idx->devmap_handle, mcl);
    667         if (rc != EOK) {
    668                 (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
    669                 fibril_mutex_unlock(&parentp->idx->lock);
    670                 return rc;
    671         }
    672         rc = fat_append_clusters(bs, parentp, mcl, lcl);
    673         if (rc != EOK) {
    674                 (void) fat_free_clusters(bs, parentp->idx->devmap_handle, mcl);
    675                 fibril_mutex_unlock(&parentp->idx->lock);
    676                 return rc;
    677         }
    678         parentp->size += BPS(bs) * SPC(bs);
    679         parentp->dirty = true;          /* need to sync node */
    680         rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    681         if (rc != EOK) {
    682                 fibril_mutex_unlock(&parentp->idx->lock);
    683                 return rc;
    684         }
    685         d = (fat_dentry_t *)b->data;
    686 
    687 hit:
     610
    688611        /*
    689612         * At this point we only establish the link between the parent and the
     
    692615         * dentry data is kept in the child node structure.
    693616         */
    694         memset(d, 0, sizeof(fat_dentry_t));
    695         fat_dentry_name_set(d, name);
    696         b->dirty = true;                /* need to sync block */
    697         rc = block_put(b);
     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
    698631        fibril_mutex_unlock(&parentp->idx->lock);
    699         if (rc != EOK)
    700                 return rc;
    701632
    702633        fibril_mutex_lock(&childp->idx->lock);
    703        
     634
    704635        if (childp->type == FAT_DIRECTORY) {
    705636                /*
     
    720651                d = (fat_dentry_t *) b->data;
    721652                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    722                     (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
     653                    (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
    723654                        memset(d, 0, sizeof(fat_dentry_t));
    724655                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     
    730661                d++;
    731662                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
    732                     (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
     663                    (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
    733664                        memset(d, 0, sizeof(fat_dentry_t));
    734665                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
    735666                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    736667                        d->attr = FAT_ATTR_SUBDIR;
    737                         d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
    738                             host2uint16_t_le(FAT_CLST_RES0) :
     668                        d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
     669                            host2uint16_t_le(FAT_CLST_ROOTPAR) :
    739670                            host2uint16_t_le(parentp->firstc);
    740671                        /* TODO: initialize also the date/time members. */
     
    750681
    751682        childp->idx->pfc = parentp->firstc;
    752         childp->idx->pdi = i * DPS(bs) + j;
     683        childp->idx->pdi = di.pos;      /* di.pos holds absolute position of SFN entry */
    753684        fibril_mutex_unlock(&childp->idx->lock);
    754685
     
    770701        fat_node_t *parentp = FAT_NODE(pfn);
    771702        fat_node_t *childp = FAT_NODE(cfn);
    772         fat_bs_t *bs;
    773         fat_dentry_t *d;
    774         block_t *b;
    775703        bool has_children;
    776704        int rc;
     
    778706        if (!parentp)
    779707                return EBUSY;
    780        
     708
    781709        rc = fat_has_children(&has_children, cfn);
    782710        if (rc != EOK)
     
    789717        assert(childp->lnkcnt == 1);
    790718        fibril_mutex_lock(&childp->idx->lock);
    791         bs = block_bb_get(childp->idx->devmap_handle);
    792 
    793         rc = _fat_block_get(&b, bs, childp->idx->devmap_handle, childp->idx->pfc,
    794             NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    795             BLOCK_FLAGS_NONE);
    796         if (rc != EOK)
     719       
     720        fat_directory_t di;
     721        rc = fat_directory_open(parentp, &di);
     722        if (rc != EOK)
    797723                goto error;
    798         d = (fat_dentry_t *)b->data +
    799             (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
    800         /* mark the dentry as not-currently-used */
    801         d->name[0] = FAT_DENTRY_ERASED;
    802         b->dirty = true;                /* need to sync block */
    803         rc = block_put(b);
     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);
    804731        if (rc != EOK)
    805732                goto error;
     
    820747
    821748error:
    822         fibril_mutex_unlock(&parentp->idx->lock);
     749        (void) fat_directory_close(&di);
     750        fibril_mutex_unlock(&childp->idx->lock);
    823751        fibril_mutex_unlock(&childp->lock);
    824         fibril_mutex_unlock(&childp->idx->lock);
     752        fibril_mutex_unlock(&parentp->lock);
    825753        return rc;
    826754}
     
    839767                return EOK;
    840768        }
    841        
     769
    842770        fibril_mutex_lock(&nodep->idx->lock);
    843         bs = block_bb_get(nodep->idx->devmap_handle);
     771        bs = block_bb_get(nodep->idx->service_id);
    844772
    845773        blocks = nodep->size / BPS(bs);
     
    847775        for (i = 0; i < blocks; i++) {
    848776                fat_dentry_t *d;
    849        
     777
    850778                rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
    851779                if (rc != EOK) {
     
    875803                if (rc != EOK) {
    876804                        fibril_mutex_unlock(&nodep->idx->lock);
    877                         return rc;     
     805                        return rc;
    878806                }
    879807        }
     
    910838}
    911839
    912 devmap_handle_t fat_device_get(fs_node_t *node)
     840service_id_t fat_service_get(fs_node_t *node)
    913841{
    914842        return 0;
     
    932860        .is_directory = fat_is_directory,
    933861        .is_file = fat_is_file,
    934         .device_get = fat_device_get
     862        .service_get = fat_service_get
    935863};
    936864
     
    940868
    941869static int
    942 fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
     870fat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
    943871    aoff64_t *size, unsigned *linkcnt)
    944872{
     
    946874        fat_bs_t *bs;
    947875        int rc;
    948        
     876
    949877        /* Check for option enabling write through. */
    950878        if (str_cmp(opts, "wtcache") == 0)
     
    954882
    955883        /* initialize libblock */
    956         rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
     884        rc = block_init(EXCHANGE_SERIALIZE, service_id, BS_SIZE);
    957885        if (rc != EOK)
    958886                return rc;
    959887
    960888        /* prepare the boot block */
    961         rc = block_bb_read(devmap_handle, BS_BLOCK);
     889        rc = block_bb_read(service_id, BS_BLOCK);
    962890        if (rc != EOK) {
    963                 block_fini(devmap_handle);
     891                block_fini(service_id);
    964892                return rc;
    965893        }
    966894
    967895        /* get the buffer with the boot sector */
    968         bs = block_bb_get(devmap_handle);
     896        bs = block_bb_get(service_id);
    969897       
    970898        if (BPS(bs) != BS_SIZE) {
    971                 block_fini(devmap_handle);
     899                block_fini(service_id);
    972900                return ENOTSUP;
    973901        }
    974902
    975903        /* Initialize the block cache */
    976         rc = block_cache_init(devmap_handle, BPS(bs), 0 /* XXX */, cmode);
     904        rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    977905        if (rc != EOK) {
    978                 block_fini(devmap_handle);
     906                block_fini(service_id);
    979907                return rc;
    980908        }
    981909
    982910        /* Do some simple sanity checks on the file system. */
    983         rc = fat_sanity_check(bs, devmap_handle);
     911        rc = fat_sanity_check(bs, service_id);
    984912        if (rc != EOK) {
    985                 (void) block_cache_fini(devmap_handle);
    986                 block_fini(devmap_handle);
    987                 return rc;
    988         }
    989 
    990         rc = fat_idx_init_by_devmap_handle(devmap_handle);
     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);
    991919        if (rc != EOK) {
    992                 (void) block_cache_fini(devmap_handle);
    993                 block_fini(devmap_handle);
     920                (void) block_cache_fini(service_id);
     921                block_fini(service_id);
    994922                return rc;
    995923        }
     
    998926        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    999927        if (!rfn) {
    1000                 (void) block_cache_fini(devmap_handle);
    1001                 block_fini(devmap_handle);
    1002                 fat_idx_fini_by_devmap_handle(devmap_handle);
     928                (void) block_cache_fini(service_id);
     929                block_fini(service_id);
     930                fat_idx_fini_by_service_id(service_id);
    1003931                return ENOMEM;
    1004932        }
     933
    1005934        fs_node_initialize(rfn);
    1006935        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    1007936        if (!rootp) {
    1008937                free(rfn);
    1009                 (void) block_cache_fini(devmap_handle);
    1010                 block_fini(devmap_handle);
    1011                 fat_idx_fini_by_devmap_handle(devmap_handle);
     938                (void) block_cache_fini(service_id);
     939                block_fini(service_id);
     940                fat_idx_fini_by_service_id(service_id);
    1012941                return ENOMEM;
    1013942        }
    1014943        fat_node_initialize(rootp);
    1015944
    1016         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);
    1017946        if (!ridxp) {
    1018947                free(rfn);
    1019948                free(rootp);
    1020                 (void) block_cache_fini(devmap_handle);
    1021                 block_fini(devmap_handle);
    1022                 fat_idx_fini_by_devmap_handle(devmap_handle);
     949                (void) block_cache_fini(service_id);
     950                block_fini(service_id);
     951                fat_idx_fini_by_service_id(service_id);
    1023952                return ENOMEM;
    1024953        }
     
    1027956
    1028957        rootp->type = FAT_DIRECTORY;
    1029         rootp->firstc = FAT_CLST_ROOT;
     958        rootp->firstc = FAT_ROOT_CLST(bs);
    1030959        rootp->refcnt = 1;
    1031960        rootp->lnkcnt = 0;      /* FS root is not linked */
    1032         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
    1033977        rootp->idx = ridxp;
    1034978        ridxp->nodep = rootp;
    1035979        rootp->bp = rfn;
    1036980        rfn->data = rootp;
    1037        
     981
    1038982        fibril_mutex_unlock(&ridxp->lock);
    1039983
     
    1045989}
    1046990
    1047 static int fat_unmounted(devmap_handle_t devmap_handle)
     991static int fat_unmounted(service_id_t service_id)
    1048992{
    1049993        fs_node_t *fn;
     
    1051995        int rc;
    1052996
    1053         rc = fat_root_get(&fn, devmap_handle);
     997        rc = fat_root_get(&fn, service_id);
    1054998        if (rc != EOK)
    1055999                return rc;
     
    10641008                return EBUSY;
    10651009        }
    1066        
     1010
    10671011        /*
    10681012         * Put the root node and force it to the FAT free node list.
     
    10761020         * stop using libblock for this instance.
    10771021         */
    1078         (void) fat_node_fini_by_devmap_handle(devmap_handle);
    1079         fat_idx_fini_by_devmap_handle(devmap_handle);
    1080         (void) block_cache_fini(devmap_handle);
    1081         block_fini(devmap_handle);
     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);
    10821026
    10831027        return EOK;
     
    10851029
    10861030static int
    1087 fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1031fat_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
    10881032    size_t *rbytes)
    10891033{
     
    10951039        int rc;
    10961040
    1097         rc = fat_node_get(&fn, devmap_handle, index);
     1041        rc = fat_node_get(&fn, service_id, index);
    10981042        if (rc != EOK)
    10991043                return rc;
     
    11101054        }
    11111055
    1112         bs = block_bb_get(devmap_handle);
     1056        bs = block_bb_get(service_id);
    11131057
    11141058        if (nodep->type == FAT_FILE) {
     
    11411085                }
    11421086        } else {
    1143                 unsigned bnum;
    11441087                aoff64_t spos = pos;
    1145                 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     1088                char name[FAT_LFN_NAME_SIZE];
    11461089                fat_dentry_t *d;
    11471090
     
    11501093                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    11511094
    1152                 /*
    1153                  * Our strategy for readdir() is to use the position pointer as
    1154                  * an index into the array of all dentries. On entry, it points
    1155                  * to the first unread dentry. If we skip any dentries, we bump
    1156                  * the position pointer accordingly.
    1157                  */
    1158                 bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
    1159                 while (bnum < nodep->size / BPS(bs)) {
    1160                         aoff64_t o;
    1161 
    1162                         rc = fat_block_get(&b, bs, nodep, bnum,
    1163                             BLOCK_FLAGS_NONE);
    1164                         if (rc != EOK)
    1165                                 goto err;
    1166                         for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
    1167                             o < BPS(bs) / sizeof(fat_dentry_t);
    1168                             o++, pos++) {
    1169                                 d = ((fat_dentry_t *)b->data) + o;
    1170                                 switch (fat_classify_dentry(d)) {
    1171                                 case FAT_DENTRY_SKIP:
    1172                                 case FAT_DENTRY_FREE:
    1173                                         continue;
    1174                                 case FAT_DENTRY_LAST:
    1175                                         rc = block_put(b);
    1176                                         if (rc != EOK)
    1177                                                 goto err;
    1178                                         goto miss;
    1179                                 default:
    1180                                 case FAT_DENTRY_VALID:
    1181                                         fat_dentry_name_get(d, name);
    1182                                         rc = block_put(b);
    1183                                         if (rc != EOK)
    1184                                                 goto err;
    1185                                         goto hit;
    1186                                 }
    1187                         }
    1188                         rc = block_put(b);
    1189                         if (rc != EOK)
    1190                                 goto err;
    1191                         bnum++;
    1192                 }
     1095                fat_directory_t di;
     1096                rc = fat_directory_open(nodep, &di);
     1097                if (rc != EOK)
     1098                        goto err;
     1099                rc = fat_directory_seek(&di, pos);
     1100                if (rc != EOK) {
     1101                        (void) fat_directory_close(&di);
     1102                        goto err;
     1103                }
     1104
     1105                rc = fat_directory_read(&di, name, &d);
     1106                if (rc == EOK)
     1107                        goto hit;
     1108                if (rc == ENOENT)
     1109                        goto miss;
     1110
     1111err:
     1112                (void) fat_node_put(fn);
     1113                async_answer_0(callid, rc);
     1114                return rc;
     1115
    11931116miss:
     1117                rc = fat_directory_close(&di);
     1118                if (rc != EOK)
     1119                        goto err;
    11941120                rc = fat_node_put(fn);
    11951121                async_answer_0(callid, rc != EOK ? rc : ENOENT);
     
    11971123                return rc != EOK ? rc : ENOENT;
    11981124
    1199 err:
    1200                 (void) fat_node_put(fn);
    1201                 async_answer_0(callid, rc);
    1202                 return rc;
    1203 
    12041125hit:
    1205                 (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);
    12061132                bytes = (pos - spos) + 1;
    12071133        }
     
    12131139
    12141140static int
    1215 fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1141fat_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
    12161142    size_t *wbytes, aoff64_t *nsize)
    12171143{
     
    12251151        int rc;
    12261152       
    1227         rc = fat_node_get(&fn, devmap_handle, index);
     1153        rc = fat_node_get(&fn, service_id, index);
    12281154        if (rc != EOK)
    12291155                return rc;
     
    12311157                return ENOENT;
    12321158        nodep = FAT_NODE(fn);
    1233        
     1159
    12341160        ipc_callid_t callid;
    12351161        size_t len;
     
    12401166        }
    12411167
    1242         bs = block_bb_get(devmap_handle);
     1168        bs = block_bb_get(service_id);
    12431169
    12441170        /*
     
    12471173         * but this one greatly simplifies fat_write(). Note that we can afford
    12481174         * to do this because the client must be ready to handle the return
    1249          * value signalizing a smaller number of bytes written. 
    1250          */ 
     1175         * value signalizing a smaller number of bytes written.
     1176         */
    12511177        bytes = min(len, BPS(bs) - pos % BPS(bs));
    12521178        if (bytes == BPS(bs))
    12531179                flags |= BLOCK_FLAGS_NOREAD;
    1254        
     1180
    12551181        boundary = ROUND_UP(nodep->size, BPC(bs));
    12561182        if (pos < boundary) {
     
    12951221                 */
    12961222                unsigned nclsts;
    1297                 fat_cluster_t mcl, lcl; 
    1298  
     1223                fat_cluster_t mcl, lcl;
     1224
    12991225                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    13001226                /* create an independent chain of nclsts clusters in all FATs */
    1301                 rc = fat_alloc_clusters(bs, devmap_handle, nclsts, &mcl, &lcl);
     1227                rc = fat_alloc_clusters(bs, service_id, nclsts, &mcl, &lcl);
    13021228                if (rc != EOK) {
    13031229                        /* could not allocate a chain of nclsts clusters */
     
    13091235                rc = fat_fill_gap(bs, nodep, mcl, pos);
    13101236                if (rc != EOK) {
    1311                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1237                        (void) fat_free_clusters(bs, service_id, mcl);
    13121238                        (void) fat_node_put(fn);
    13131239                        async_answer_0(callid, rc);
    13141240                        return rc;
    13151241                }
    1316                 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     1242                rc = _fat_block_get(&b, bs, service_id, lcl, NULL,
    13171243                    (pos / BPS(bs)) % SPC(bs), flags);
    13181244                if (rc != EOK) {
    1319                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1245                        (void) fat_free_clusters(bs, service_id, mcl);
    13201246                        (void) fat_node_put(fn);
    13211247                        async_answer_0(callid, rc);
     
    13271253                rc = block_put(b);
    13281254                if (rc != EOK) {
    1329                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1255                        (void) fat_free_clusters(bs, service_id, mcl);
    13301256                        (void) fat_node_put(fn);
    13311257                        return rc;
     
    13371263                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    13381264                if (rc != EOK) {
    1339                         (void) fat_free_clusters(bs, devmap_handle, mcl);
     1265                        (void) fat_free_clusters(bs, service_id, mcl);
    13401266                        (void) fat_node_put(fn);
    13411267                        return rc;
     
    13501276
    13511277static int
    1352 fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     1278fat_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
    13531279{
    13541280        fs_node_t *fn;
     
    13571283        int rc;
    13581284
    1359         rc = fat_node_get(&fn, devmap_handle, index);
     1285        rc = fat_node_get(&fn, service_id, index);
    13601286        if (rc != EOK)
    13611287                return rc;
     
    13641290        nodep = FAT_NODE(fn);
    13651291
    1366         bs = block_bb_get(devmap_handle);
     1292        bs = block_bb_get(service_id);
    13671293
    13681294        if (nodep->size == size) {
     
    13801306                nodep->size = size;
    13811307                nodep->dirty = true;            /* need to sync node */
    1382                 rc = EOK;       
     1308                rc = EOK;
    13831309        } else {
    13841310                /*
     
    13911317                } else {
    13921318                        fat_cluster_t lastc;
    1393                         rc = fat_cluster_walk(bs, devmap_handle, nodep->firstc,
     1319                        rc = fat_cluster_walk(bs, service_id, nodep->firstc,
    13941320                            &lastc, NULL, (size - 1) / BPC(bs));
    13951321                        if (rc != EOK)
     
    14011327                nodep->size = size;
    14021328                nodep->dirty = true;            /* need to sync node */
    1403                 rc = EOK;       
     1329                rc = EOK;
    14041330        }
    14051331out:
     
    14081334}
    14091335
    1410 static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
     1336static int fat_close(service_id_t service_id, fs_index_t index)
    14111337{
    14121338        return EOK;
    14131339}
    14141340
    1415 static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     1341static int fat_destroy(service_id_t service_id, fs_index_t index)
    14161342{
    14171343        fs_node_t *fn;
     
    14191345        int rc;
    14201346
    1421         rc = fat_node_get(&fn, devmap_handle, index);
     1347        rc = fat_node_get(&fn, service_id, index);
    14221348        if (rc != EOK)
    14231349                return rc;
     
    14361362}
    14371363
    1438 static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
     1364static int fat_sync(service_id_t service_id, fs_index_t index)
    14391365{
    14401366        fs_node_t *fn;
    1441         int rc = fat_node_get(&fn, devmap_handle, index);
     1367        int rc = fat_node_get(&fn, service_id, index);
    14421368        if (rc != EOK)
    14431369                return rc;
    14441370        if (!fn)
    14451371                return ENOENT;
    1446        
     1372
    14471373        fat_node_t *nodep = FAT_NODE(fn);
    1448        
     1374
    14491375        nodep->dirty = true;
    14501376        rc = fat_node_sync(nodep);
    1451        
     1377
    14521378        fat_node_put(fn);
    14531379        return rc;
Note: See TracChangeset for help on using the changeset viewer.