Changeset 81d773f in mainline for uspace/srv/fs/exfat/exfat_ops.c


Ignore:
Timestamp:
2011-07-04T00:28:51Z (13 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
18ad2ab6
Parents:
2fb88ea
Message:

exFAT:

  1. exfat_bitmap_get and exfat_uctable_get for access to special exFAT objects
  2. Implement exfat_node_get_new
  3. Draft iimplementation of exfat_node_get_core
  4. Implement exfat_node_get
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/exfat/exfat_ops.c

    r2fb88ea r81d773f  
    3939#include "exfat.h"
    4040#include "exfat_fat.h"
     41#include "exfat_dentry.h"
    4142#include "../../vfs/vfs.h"
    4243#include <libfs.h>
     
    7172 * Forward declarations of FAT libfs operations.
    7273 */
     74/*
     75static int exfat_bitmap_get(fs_node_t **, devmap_handle_t);
     76static int exfat_uctable_get(fs_node_t **, devmap_handle_t);
     77*/
    7378static int exfat_root_get(fs_node_t **, devmap_handle_t);
    7479static int exfat_match(fs_node_t **, fs_node_t *, const char *);
     
    97102        node->bp = NULL;
    98103        node->idx = NULL;
    99         node->type = 0;
     104        node->type = EXFAT_UNKNOW;
    100105        link_initialize(&node->ffn_link);
    101106        node->size = 0;
     
    103108        node->refcnt = 0;
    104109        node->dirty = false;
     110        node->fragmented = true;
    105111        node->lastc_cached_valid = false;
    106112        node->lastc_cached_value = 0;
     
    174180}
    175181
     182static int exfat_node_get_new(exfat_node_t **nodepp)
     183{
     184        fs_node_t *fn;
     185        exfat_node_t *nodep;
     186        int rc;
     187
     188        fibril_mutex_lock(&ffn_mutex);
     189        if (!list_empty(&ffn_head)) {
     190                /* Try to use a cached free node structure. */
     191                exfat_idx_t *idxp_tmp;
     192                nodep = list_get_instance(ffn_head.next, exfat_node_t, ffn_link);
     193                if (!fibril_mutex_trylock(&nodep->lock))
     194                        goto skip_cache;
     195                idxp_tmp = nodep->idx;
     196                if (!fibril_mutex_trylock(&idxp_tmp->lock)) {
     197                        fibril_mutex_unlock(&nodep->lock);
     198                        goto skip_cache;
     199                }
     200                list_remove(&nodep->ffn_link);
     201                fibril_mutex_unlock(&ffn_mutex);
     202                if (nodep->dirty) {
     203                        rc = exfat_node_sync(nodep);
     204                        if (rc != EOK) {
     205                                idxp_tmp->nodep = NULL;
     206                                fibril_mutex_unlock(&nodep->lock);
     207                                fibril_mutex_unlock(&idxp_tmp->lock);
     208                                free(nodep->bp);
     209                                free(nodep);
     210                                return rc;
     211                        }
     212                }
     213                idxp_tmp->nodep = NULL;
     214                fibril_mutex_unlock(&nodep->lock);
     215                fibril_mutex_unlock(&idxp_tmp->lock);
     216                fn = FS_NODE(nodep);
     217        } else {
     218skip_cache:
     219                /* Try to allocate a new node structure. */
     220                fibril_mutex_unlock(&ffn_mutex);
     221                fn = (fs_node_t *)malloc(sizeof(fs_node_t));
     222                if (!fn)
     223                        return ENOMEM;
     224                nodep = (exfat_node_t *)malloc(sizeof(exfat_node_t));
     225                if (!nodep) {
     226                        free(fn);
     227                        return ENOMEM;
     228                }
     229        }
     230        exfat_node_initialize(nodep);
     231        fs_node_initialize(fn);
     232        fn->data = nodep;
     233        nodep->bp = fn;
     234
     235        *nodepp = nodep;
     236        return EOK;
     237}
     238
     239/** Internal version of exfat_node_get().
     240 *
     241 * @param idxp          Locked index structure.
     242 */
     243static int exfat_node_get_core(exfat_node_t **nodepp, exfat_idx_t *idxp)
     244{
     245        block_t *b=NULL;
     246        //exfat_bs_t *bs;
     247        //exfat_dentry_t *d;
     248        exfat_node_t *nodep = NULL;
     249        int rc;
     250
     251        if (idxp->nodep) {
     252                /*
     253                 * We are lucky.
     254                 * The node is already instantiated in memory.
     255                 */
     256                fibril_mutex_lock(&idxp->nodep->lock);
     257                if (!idxp->nodep->refcnt++) {
     258                        fibril_mutex_lock(&ffn_mutex);
     259                        list_remove(&idxp->nodep->ffn_link);
     260                        fibril_mutex_unlock(&ffn_mutex);
     261                }
     262                fibril_mutex_unlock(&idxp->nodep->lock);
     263                *nodepp = idxp->nodep;
     264                return EOK;
     265        }
     266
     267        /*
     268         * We must instantiate the node from the file system.
     269         */
     270
     271        assert(idxp->pfc);
     272
     273        rc = exfat_node_get_new(&nodep);
     274        if (rc != EOK)
     275                return rc;
     276
     277        //bs = block_bb_get(idxp->devmap_handle);
     278
     279        /* Access to exFAT directory and read two entries:
     280         * file entry and stream entry
     281         */
     282        /*
     283        exfat_directory_t di;
     284        exfat_dentry_t *de;
     285        exfat_directory_open(&di, ???);
     286        exfat_directory_seek(&di, idxp->pdi);
     287        exfat_directory_get(&di, &de);
     288
     289        switch (exfat_classify_dentry(de)) {
     290        case EXFAT_DENTRY_FILE:
     291                nodep->type = (de->file.attr & EXFAT_ATTR_SUBDIR)?
     292                    EXFAT_DIRECTORY : EXFAT_FILE;
     293                exfat_directory_next(&di);
     294                exfat_directory_get(&di, &de);
     295                nodep->firtsc = de->stream.firstc;
     296                nodep->size = de->stream.data_size;
     297                nodep->fragmented = (de->stream.flags & 0x02) == 0;
     298                break;
     299        case EXFAT_DENTRY_BITMAP:
     300                nodep->type = EXFAT_BITMAP;
     301                nodep->firstc = de->bitmap.firstc;
     302                nodep->size = de->bitmap.size;
     303                nodep->fragmented = false;
     304                break;
     305        case EXFAT_DENTRY_UCTABLE:
     306                nodep->type = EXFAT_UCTABLE;
     307                nodep->firstc = de->uctable.firstc;
     308                nodep->size = de->uctable.size;
     309                nodep->fragmented = false;
     310                break;
     311        default:
     312        case EXFAT_DENTRY_SKIP:
     313        case EXFAT_DENTRY_LAST:
     314        case EXFAT_DENTRY_FREE:
     315        case EXFAT_DENTRY_VOLLABEL:
     316        case EXFAT_DENTRY_GUID:
     317        case EXFAT_DENTRY_STREAM:
     318        case EXFAT_DENTRY_NAME:
     319                (void) block_put(b);
     320                (void) fat_node_put(FS_NODE(nodep));
     321                return ENOENT;
     322        }
     323        */
     324
     325        /* Read the block that contains the dentry of interest. */
     326        /*
     327        rc = _fat_block_get(&b, bs, idxp->devmap_handle, idxp->pfc, NULL,
     328            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
     329        if (rc != EOK) {
     330                (void) fat_node_put(FS_NODE(nodep));
     331                return rc;
     332        }
     333
     334        d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
     335        */
     336
     337        nodep->lnkcnt = 1;
     338        nodep->refcnt = 1;
     339
     340        rc = block_put(b);
     341        if (rc != EOK) {
     342                (void) exfat_node_put(FS_NODE(nodep));
     343                return rc;
     344        }
     345
     346        /* Link the idx structure with the node structure. */
     347        nodep->idx = idxp;
     348        idxp->nodep = nodep;
     349
     350        *nodepp = nodep;
     351        return EOK;
     352}
     353
     354
    176355
    177356/*
    178  * FAT libfs operations.
     357 * EXFAT libfs operations.
    179358 */
    180359
    181360int exfat_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
    182361{
    183         return exfat_node_get(rfn, devmap_handle, 0);
    184 }
     362        return exfat_node_get(rfn, devmap_handle, EXFAT_ROOT_IDX);
     363}
     364
     365/*
     366int exfat_bitmap_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     367{
     368        return exfat_node_get(rfn, devmap_handle, EXFAT_BITMAP_IDX);
     369}
     370
     371int exfat_uctable_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     372{
     373        return exfat_node_get(rfn, devmap_handle, EXFAT_UCTABLE_IDX);
     374}
     375*/
    185376
    186377int exfat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
     
    193384int exfat_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
    194385{
    195         *rfn = NULL;
    196         return EOK;
     386        exfat_node_t *nodep;
     387        exfat_idx_t *idxp;
     388        int rc;
     389
     390        idxp = exfat_idx_get_by_index(devmap_handle, index);
     391        if (!idxp) {
     392                *rfn = NULL;
     393                return EOK;
     394        }
     395        /* idxp->lock held */
     396        rc = exfat_node_get_core(&nodep, idxp);
     397        fibril_mutex_unlock(&idxp->lock);
     398        if (rc == EOK)
     399                *rfn = FS_NODE(nodep);
     400        return rc;
    197401}
    198402
     
    392596        exfat_node_initialize(rootp);
    393597
    394         /* exfat_idx_t *ridxp = exfat_idx_get_by_pos(devmap_handle, FAT_CLST_ROOTPAR, 0); */
    395         exfat_idx_t *ridxp = exfat_idx_get_by_pos(devmap_handle, 0, 0);
     598        exfat_idx_t *ridxp = exfat_idx_get_by_pos(devmap_handle, EXFAT_ROOT_PAR, 0);
    396599        if (!ridxp) {
    397600                free(rfn);
     
    416619
    417620        fibril_mutex_unlock(&ridxp->lock);
     621       
     622        /* TODO */
     623        /* We should intitalize bitmap and uctable nodes next to the root node */
     624        /* HERE!!! */
    418625
    419626        /* async_answer_0(rid, EOK); */
Note: See TracChangeset for help on using the changeset viewer.