Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r75160a6 rffa2c8ef  
    2929/** @addtogroup fs
    3030 * @{
    31  */ 
     31 */
    3232
    3333/**
     
    3939#include "tmpfs.h"
    4040#include "../../vfs/vfs.h"
    41 #include <ipc/ipc.h>
     41#include <macros.h>
     42#include <stdint.h>
    4243#include <async.h>
    4344#include <errno.h>
    4445#include <atomic.h>
    4546#include <stdlib.h>
    46 #include <string.h>
     47#include <str.h>
    4748#include <stdio.h>
    4849#include <assert.h>
     
    6768
    6869/* Forward declarations of static functions. */
    69 static fs_node_t *tmpfs_match(fs_node_t *, const char *);
    70 static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t);
    71 static void tmpfs_node_put(fs_node_t *);
    72 static fs_node_t *tmpfs_create_node(dev_handle_t, int);
     70static int tmpfs_match(fs_node_t **, fs_node_t *, const char *);
     71static int tmpfs_node_get(fs_node_t **, devmap_handle_t, fs_index_t);
     72static int tmpfs_node_open(fs_node_t *);
     73static int tmpfs_node_put(fs_node_t *);
     74static int tmpfs_create_node(fs_node_t **, devmap_handle_t, int);
     75static int tmpfs_destroy_node(fs_node_t *);
    7376static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *);
    7477static int tmpfs_unlink_node(fs_node_t *, fs_node_t *, const char *);
    75 static int tmpfs_destroy_node(fs_node_t *);
    7678
    7779/* Implementation of helper functions. */
     80static int tmpfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
     81{
     82        return tmpfs_node_get(rfn, devmap_handle, TMPFS_SOME_ROOT);
     83}
     84
     85static int tmpfs_has_children(bool *has_children, fs_node_t *fn)
     86{
     87        *has_children = !list_empty(&TMPFS_NODE(fn)->cs_head);
     88        return EOK;
     89}
     90
    7891static fs_index_t tmpfs_index_get(fs_node_t *fn)
    7992{
     
    8194}
    8295
    83 static size_t tmpfs_size_get(fs_node_t *fn)
     96static aoff64_t tmpfs_size_get(fs_node_t *fn)
    8497{
    8598        return TMPFS_NODE(fn)->size;
     
    91104}
    92105
    93 static bool tmpfs_has_children(fs_node_t *fn)
    94 {
    95         return !list_empty(&TMPFS_NODE(fn)->cs_head);
    96 }
    97 
    98 static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)
    99 {
    100         return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
    101 }
    102 
    103106static char tmpfs_plb_get_char(unsigned pos)
    104107{
     
    114117{
    115118        return TMPFS_NODE(fn)->type == TMPFS_FILE;
     119}
     120
     121static devmap_handle_t tmpfs_device_get(fs_node_t *fn)
     122{
     123        return 0;
    116124}
    117125
    118126/** libfs operations */
    119127libfs_ops_t tmpfs_libfs_ops = {
     128        .root_get = tmpfs_root_get,
    120129        .match = tmpfs_match,
    121130        .node_get = tmpfs_node_get,
     131        .node_open = tmpfs_node_open,
    122132        .node_put = tmpfs_node_put,
    123133        .create = tmpfs_create_node,
     
    125135        .link = tmpfs_link_node,
    126136        .unlink = tmpfs_unlink_node,
     137        .has_children = tmpfs_has_children,
    127138        .index_get = tmpfs_index_get,
    128139        .size_get = tmpfs_size_get,
    129140        .lnkcnt_get = tmpfs_lnkcnt_get,
    130         .has_children = tmpfs_has_children,
    131         .root_get = tmpfs_root_get,
    132141        .plb_get_char = tmpfs_plb_get_char,
    133142        .is_directory = tmpfs_is_directory,
    134         .is_file = tmpfs_is_file
     143        .is_file = tmpfs_is_file,
     144        .device_get = tmpfs_device_get
    135145};
    136146
     
    138148hash_table_t nodes;
    139149
    140 #define NODES_KEY_INDEX 0
    141 #define NODES_KEY_DEV   1
     150#define NODES_KEY_DEV   0       
     151#define NODES_KEY_INDEX 1
    142152
    143153/* Implementation of hash table interface for the nodes hash table. */
     
    151161        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    152162            nh_link);
    153         return (nodep->index == key[NODES_KEY_INDEX] &&
    154             nodep->dev_handle == key[NODES_KEY_DEV]);
     163       
     164        switch (keys) {
     165        case 1:
     166                return (nodep->devmap_handle == key[NODES_KEY_DEV]);
     167        case 2:
     168                return ((nodep->devmap_handle == key[NODES_KEY_DEV]) &&
     169                    (nodep->index == key[NODES_KEY_INDEX]));
     170        default:
     171                assert((keys == 1) || (keys == 2));
     172        }
     173
     174        return 0;
    155175}
    156176
    157177static void nodes_remove_callback(link_t *item)
    158178{
     179        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
     180            nh_link);
     181
     182        while (!list_empty(&nodep->cs_head)) {
     183                tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
     184                    tmpfs_dentry_t, link);
     185
     186                assert(nodep->type == TMPFS_DIRECTORY);
     187                list_remove(&dentryp->link);
     188                free(dentryp);
     189        }
     190
     191        if (nodep->data) {
     192                assert(nodep->type == TMPFS_FILE);
     193                free(nodep->data);
     194        }
     195        free(nodep->bp);
     196        free(nodep);
    159197}
    160198
     
    170208        nodep->bp = NULL;
    171209        nodep->index = 0;
    172         nodep->dev_handle = 0;
     210        nodep->devmap_handle = 0;
    173211        nodep->type = TMPFS_NONE;
    174212        nodep->lnkcnt = 0;
     
    194232}
    195233
    196 static bool tmpfs_instance_init(dev_handle_t dev_handle)
     234static bool tmpfs_instance_init(devmap_handle_t devmap_handle)
    197235{
    198236        fs_node_t *rfn;
    199        
    200         rfn = tmpfs_create_node(dev_handle, L_DIRECTORY);
    201         if (!rfn)
     237        int rc;
     238       
     239        rc = tmpfs_create_node(&rfn, devmap_handle, L_DIRECTORY);
     240        if (rc != EOK || !rfn)
    202241                return false;
    203242        TMPFS_NODE(rfn)->lnkcnt = 0;    /* FS root is not linked */
     
    205244}
    206245
    207 fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component)
     246static void tmpfs_instance_done(devmap_handle_t devmap_handle)
     247{
     248        unsigned long key[] = {
     249                [NODES_KEY_DEV] = devmap_handle
     250        };
     251        /*
     252         * Here we are making use of one special feature of our hash table
     253         * implementation, which allows to remove more items based on a partial
     254         * key match. In the following, we are going to remove all nodes
     255         * matching our device handle. The nodes_remove_callback() function will
     256         * take care of resource deallocation.
     257         */
     258        hash_table_remove(&nodes, key, 1);
     259}
     260
     261int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    208262{
    209263        tmpfs_node_t *parentp = TMPFS_NODE(pfn);
     
    212266        for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
    213267            lnk = lnk->next) {
    214                 tmpfs_dentry_t *dentryp = list_get_instance(lnk, tmpfs_dentry_t,
    215                     link);
    216                 if (!str_cmp(dentryp->name, component))
    217                         return FS_NODE(dentryp->node);
    218         }
    219 
    220         return NULL;
    221 }
    222 
    223 fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
     268                tmpfs_dentry_t *dentryp;
     269                dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
     270                if (!str_cmp(dentryp->name, component)) {
     271                        *rfn = FS_NODE(dentryp->node);
     272                        return EOK;
     273                }
     274        }
     275
     276        *rfn = NULL;
     277        return EOK;
     278}
     279
     280int tmpfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
    224281{
    225282        unsigned long key[] = {
    226                 [NODES_KEY_INDEX] = index,
    227                 [NODES_KEY_DEV] = dev_handle
     283                [NODES_KEY_DEV] = devmap_handle,
     284                [NODES_KEY_INDEX] = index
    228285        };
    229286        link_t *lnk = hash_table_find(&nodes, key);
    230         if (!lnk)
    231                 return NULL;
    232         return FS_NODE(hash_table_get_instance(lnk, tmpfs_node_t, nh_link));
    233 }
    234 
    235 void tmpfs_node_put(fs_node_t *fn)
     287        if (lnk) {
     288                tmpfs_node_t *nodep;
     289                nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link);
     290                *rfn = FS_NODE(nodep);
     291        } else {
     292                *rfn = NULL;
     293        }
     294        return EOK;     
     295}
     296
     297int tmpfs_node_open(fs_node_t *fn)
    236298{
    237299        /* nothing to do */
    238 }
    239 
    240 fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
    241 {
     300        return EOK;
     301}
     302
     303int tmpfs_node_put(fs_node_t *fn)
     304{
     305        /* nothing to do */
     306        return EOK;
     307}
     308
     309int tmpfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)
     310{
     311        fs_node_t *rootfn;
     312        int rc;
     313
    242314        assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
    243315
    244316        tmpfs_node_t *nodep = malloc(sizeof(tmpfs_node_t));
    245317        if (!nodep)
    246                 return NULL;
     318                return ENOMEM;
    247319        tmpfs_node_initialize(nodep);
    248320        nodep->bp = malloc(sizeof(fs_node_t));
    249321        if (!nodep->bp) {
    250322                free(nodep);
    251                 return NULL;
     323                return ENOMEM;
    252324        }
    253325        fs_node_initialize(nodep->bp);
    254326        nodep->bp->data = nodep;        /* link the FS and TMPFS nodes */
    255         if (!tmpfs_root_get(dev_handle))
     327
     328        rc = tmpfs_root_get(&rootfn, devmap_handle);
     329        assert(rc == EOK);
     330        if (!rootfn)
    256331                nodep->index = TMPFS_SOME_ROOT;
    257332        else
    258333                nodep->index = tmpfs_next_index++;
    259         nodep->dev_handle = dev_handle;
     334        nodep->devmap_handle = devmap_handle;
    260335        if (lflag & L_DIRECTORY)
    261336                nodep->type = TMPFS_DIRECTORY;
     
    265340        /* Insert the new node into the nodes hash table. */
    266341        unsigned long key[] = {
    267                 [NODES_KEY_INDEX] = nodep->index,
    268                 [NODES_KEY_DEV] = nodep->dev_handle
     342                [NODES_KEY_DEV] = nodep->devmap_handle,
     343                [NODES_KEY_INDEX] = nodep->index
    269344        };
    270345        hash_table_insert(&nodes, key, &nodep->nh_link);
    271         return FS_NODE(nodep);
     346        *rfn = FS_NODE(nodep);
     347        return EOK;
     348}
     349
     350int tmpfs_destroy_node(fs_node_t *fn)
     351{
     352        tmpfs_node_t *nodep = TMPFS_NODE(fn);
     353       
     354        assert(!nodep->lnkcnt);
     355        assert(list_empty(&nodep->cs_head));
     356
     357        unsigned long key[] = {
     358                [NODES_KEY_DEV] = nodep->devmap_handle,
     359                [NODES_KEY_INDEX] = nodep->index
     360        };
     361        hash_table_remove(&nodes, key, 2);
     362
     363        /*
     364         * The nodes_remove_callback() function takes care of the actual
     365         * resource deallocation.
     366         */
     367        return EOK;
    272368}
    273369
     
    343439}
    344440
    345 int tmpfs_destroy_node(fs_node_t *fn)
    346 {
    347         tmpfs_node_t *nodep = TMPFS_NODE(fn);
    348        
    349         assert(!nodep->lnkcnt);
    350         assert(list_empty(&nodep->cs_head));
    351 
    352         unsigned long key[] = {
    353                 [NODES_KEY_INDEX] = nodep->index,
    354                 [NODES_KEY_DEV] = nodep->dev_handle
    355         };
    356         hash_table_remove(&nodes, key, 2);
    357 
    358         if (nodep->type == TMPFS_FILE)
    359                 free(nodep->data);
    360         free(nodep->bp);
    361         free(nodep);
    362         return EOK;
    363 }
    364 
    365441void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    366442{
    367         dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    368 
    369         /* accept the mount options */
    370         ipc_callid_t callid;
    371         size_t size;
    372         if (!ipc_data_write_receive(&callid, &size)) {
    373                 ipc_answer_0(callid, EINVAL);
    374                 ipc_answer_0(rid, EINVAL);
    375                 return;
    376         }
    377         char *opts = malloc(size + 1);
    378         if (!opts) {
    379                 ipc_answer_0(callid, ENOMEM);
    380                 ipc_answer_0(rid, ENOMEM);
    381                 return;
    382         }
    383         ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
    384         if (retval != EOK) {
    385                 ipc_answer_0(rid, retval);
     443        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     444        fs_node_t *rootfn;
     445        int rc;
     446       
     447        /* Accept the mount options. */
     448        char *opts;
     449        rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     450        if (rc != EOK) {
     451                async_answer_0(rid, rc);
     452                return;
     453        }
     454
     455        /* Check if this device is not already mounted. */
     456        rc = tmpfs_root_get(&rootfn, devmap_handle);
     457        if ((rc == EOK) && (rootfn)) {
     458                (void) tmpfs_node_put(rootfn);
    386459                free(opts);
    387                 return;
    388         }
    389         opts[size] = '\0';
     460                async_answer_0(rid, EEXIST);
     461                return;
     462        }
    390463
    391464        /* Initialize TMPFS instance. */
    392         if (!tmpfs_instance_init(dev_handle)) {
    393                 ipc_answer_0(rid, ENOMEM);
    394                 return;
    395         }
    396 
    397         tmpfs_node_t *rootp = TMPFS_NODE(tmpfs_root_get(dev_handle));
     465        if (!tmpfs_instance_init(devmap_handle)) {
     466                free(opts);
     467                async_answer_0(rid, ENOMEM);
     468                return;
     469        }
     470
     471        rc = tmpfs_root_get(&rootfn, devmap_handle);
     472        assert(rc == EOK);
     473        tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
    398474        if (str_cmp(opts, "restore") == 0) {
    399                 if (tmpfs_restore(dev_handle))
    400                         ipc_answer_3(rid, EOK, rootp->index, rootp->size,
     475                if (tmpfs_restore(devmap_handle))
     476                        async_answer_3(rid, EOK, rootp->index, rootp->size,
    401477                            rootp->lnkcnt);
    402478                else
    403                         ipc_answer_0(rid, ELIMIT);
     479                        async_answer_0(rid, ELIMIT);
    404480        } else {
    405                 ipc_answer_3(rid, EOK, rootp->index, rootp->size,
     481                async_answer_3(rid, EOK, rootp->index, rootp->size,
    406482                    rootp->lnkcnt);
    407483        }
     484        free(opts);
    408485}
    409486
     
    413490}
    414491
     492void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     493{
     494        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     495
     496        tmpfs_instance_done(devmap_handle);
     497        async_answer_0(rid, EOK);
     498}
     499
     500void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     501{
     502        libfs_unmount(&tmpfs_libfs_ops, rid, request);
     503}
     504
    415505void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    416506{
     
    420510void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    421511{
    422         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    423         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    424         off_t pos = (off_t)IPC_GET_ARG3(*request);
    425 
     512        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     513        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     514        aoff64_t pos =
     515            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     516       
    426517        /*
    427518         * Lookup the respective TMPFS node.
     
    429520        link_t *hlp;
    430521        unsigned long key[] = {
    431                 [NODES_KEY_INDEX] = index,
    432                 [NODES_KEY_DEV] = dev_handle,
     522                [NODES_KEY_DEV] = devmap_handle,
     523                [NODES_KEY_INDEX] = index
    433524        };
    434525        hlp = hash_table_find(&nodes, key);
    435526        if (!hlp) {
    436                 ipc_answer_0(rid, ENOENT);
     527                async_answer_0(rid, ENOENT);
    437528                return;
    438529        }
    439530        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    440531            nh_link);
    441 
     532       
    442533        /*
    443534         * Receive the read request.
     
    445536        ipc_callid_t callid;
    446537        size_t size;
    447         if (!ipc_data_read_receive(&callid, &size)) {
    448                 ipc_answer_0(callid, EINVAL);   
    449                 ipc_answer_0(rid, EINVAL);
     538        if (!async_data_read_receive(&callid, &size)) {
     539                async_answer_0(callid, EINVAL);
     540                async_answer_0(rid, EINVAL);
    450541                return;
    451542        }
     
    453544        size_t bytes;
    454545        if (nodep->type == TMPFS_FILE) {
    455                 bytes = max(0, min(nodep->size - pos, size));
    456                 (void) ipc_data_read_finalize(callid, nodep->data + pos,
     546                bytes = min(nodep->size - pos, size);
     547                (void) async_data_read_finalize(callid, nodep->data + pos,
    457548                    bytes);
    458549        } else {
    459550                tmpfs_dentry_t *dentryp;
    460551                link_t *lnk;
    461                 int i;
     552                aoff64_t i;
    462553               
    463554                assert(nodep->type == TMPFS_DIRECTORY);
     
    469560                 */
    470561                for (i = 0, lnk = nodep->cs_head.next;
    471                     i < pos && lnk != &nodep->cs_head;
     562                    (i < pos) && (lnk != &nodep->cs_head);
    472563                    i++, lnk = lnk->next)
    473564                        ;
    474565
    475566                if (lnk == &nodep->cs_head) {
    476                         ipc_answer_0(callid, ENOENT);
    477                         ipc_answer_1(rid, ENOENT, 0);
     567                        async_answer_0(callid, ENOENT);
     568                        async_answer_1(rid, ENOENT, 0);
    478569                        return;
    479570                }
     
    481572                dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
    482573
    483                 (void) ipc_data_read_finalize(callid, dentryp->name,
     574                (void) async_data_read_finalize(callid, dentryp->name,
    484575                    str_size(dentryp->name) + 1);
    485576                bytes = 1;
     
    489580         * Answer the VFS_READ call.
    490581         */
    491         ipc_answer_1(rid, EOK, bytes);
     582        async_answer_1(rid, EOK, bytes);
    492583}
    493584
    494585void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    495586{
    496         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    497         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    498         off_t pos = (off_t)IPC_GET_ARG3(*request);
    499 
     587        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     588        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     589        aoff64_t pos =
     590            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     591       
    500592        /*
    501593         * Lookup the respective TMPFS node.
     
    503595        link_t *hlp;
    504596        unsigned long key[] = {
    505                 [NODES_KEY_INDEX] = index,
    506                 [NODES_KEY_DEV] = dev_handle
     597                [NODES_KEY_DEV] = devmap_handle,
     598                [NODES_KEY_INDEX] = index
    507599        };
    508600        hlp = hash_table_find(&nodes, key);
    509601        if (!hlp) {
    510                 ipc_answer_0(rid, ENOENT);
     602                async_answer_0(rid, ENOENT);
    511603                return;
    512604        }
     
    519611        ipc_callid_t callid;
    520612        size_t size;
    521         if (!ipc_data_write_receive(&callid, &size)) {
    522                 ipc_answer_0(callid, EINVAL);   
    523                 ipc_answer_0(rid, EINVAL);
     613        if (!async_data_write_receive(&callid, &size)) {
     614                async_answer_0(callid, EINVAL);
     615                async_answer_0(rid, EINVAL);
    524616                return;
    525617        }
     
    530622        if (pos + size <= nodep->size) {
    531623                /* The file size is not changing. */
    532                 (void) ipc_data_write_finalize(callid, nodep->data + pos, size);
    533                 ipc_answer_2(rid, EOK, size, nodep->size);
     624                (void) async_data_write_finalize(callid, nodep->data + pos, size);
     625                async_answer_2(rid, EOK, size, nodep->size);
    534626                return;
    535627        }
     
    544636        void *newdata = realloc(nodep->data, nodep->size + delta);
    545637        if (!newdata) {
    546                 ipc_answer_0(callid, ENOMEM);
    547                 ipc_answer_2(rid, EOK, 0, nodep->size);
     638                async_answer_0(callid, ENOMEM);
     639                async_answer_2(rid, EOK, 0, nodep->size);
    548640                return;
    549641        }
     
    552644        nodep->size += delta;
    553645        nodep->data = newdata;
    554         (void) ipc_data_write_finalize(callid, nodep->data + pos, size);
    555         ipc_answer_2(rid, EOK, size, nodep->size);
     646        (void) async_data_write_finalize(callid, nodep->data + pos, size);
     647        async_answer_2(rid, EOK, size, nodep->size);
    556648}
    557649
    558650void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    559651{
    560         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
     652        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     653        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     654        aoff64_t size =
     655            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     656       
     657        /*
     658         * Lookup the respective TMPFS node.
     659         */
     660        unsigned long key[] = {
     661                [NODES_KEY_DEV] = devmap_handle,
     662                [NODES_KEY_INDEX] = index
     663        };
     664        link_t *hlp = hash_table_find(&nodes, key);
     665        if (!hlp) {
     666                async_answer_0(rid, ENOENT);
     667                return;
     668        }
     669        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
     670            nh_link);
     671       
     672        if (size == nodep->size) {
     673                async_answer_0(rid, EOK);
     674                return;
     675        }
     676       
     677        if (size > SIZE_MAX) {
     678                async_answer_0(rid, ENOMEM);
     679                return;
     680        }
     681       
     682        void *newdata = realloc(nodep->data, size);
     683        if (!newdata) {
     684                async_answer_0(rid, ENOMEM);
     685                return;
     686        }
     687       
     688        if (size > nodep->size) {
     689                size_t delta = size - nodep->size;
     690                memset(newdata + nodep->size, 0, delta);
     691        }
     692       
     693        nodep->size = size;
     694        nodep->data = newdata;
     695        async_answer_0(rid, EOK);
     696}
     697
     698void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
     699{
     700        async_answer_0(rid, EOK);
     701}
     702
     703void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
     704{
     705        devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    561706        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    562         size_t size = (off_t)IPC_GET_ARG3(*request);
    563 
    564         /*
    565          * Lookup the respective TMPFS node.
    566          */
     707        int rc;
     708
    567709        link_t *hlp;
    568710        unsigned long key[] = {
    569                 [NODES_KEY_INDEX] = index,
    570                 [NODES_KEY_DEV] = dev_handle
     711                [NODES_KEY_DEV] = devmap_handle,
     712                [NODES_KEY_INDEX] = index
    571713        };
    572714        hlp = hash_table_find(&nodes, key);
    573715        if (!hlp) {
    574                 ipc_answer_0(rid, ENOENT);
    575                 return;
    576         }
    577         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    578             nh_link);
    579 
    580         if (size == nodep->size) {
    581                 ipc_answer_0(rid, EOK);
    582                 return;
    583         }
    584 
    585         void *newdata = realloc(nodep->data, size);
    586         if (!newdata) {
    587                 ipc_answer_0(rid, ENOMEM);
    588                 return;
    589         }
    590         if (size > nodep->size) {
    591                 size_t delta = size - nodep->size;
    592                 memset(newdata + nodep->size, 0, delta);
    593         }
    594         nodep->size = size;
    595         nodep->data = newdata;
    596         ipc_answer_0(rid, EOK);
    597 }
    598 
    599 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    600 {
    601         ipc_answer_0(rid, EOK);
    602 }
    603 
    604 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    605 {
    606         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    607         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    608         int rc;
    609 
    610         link_t *hlp;
    611         unsigned long key[] = {
    612                 [NODES_KEY_INDEX] = index,
    613                 [NODES_KEY_DEV] = dev_handle
    614         };
    615         hlp = hash_table_find(&nodes, key);
    616         if (!hlp) {
    617                 ipc_answer_0(rid, ENOENT);
     716                async_answer_0(rid, ENOENT);
    618717                return;
    619718        }
     
    621720            nh_link);
    622721        rc = tmpfs_destroy_node(FS_NODE(nodep));
    623         ipc_answer_0(rid, rc);
     722        async_answer_0(rid, rc);
    624723}
    625724
     
    636735void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
    637736{
    638         /* Dummy implementation */
    639         ipc_answer_0(rid, EOK);
     737        /*
     738         * TMPFS keeps its data structures always consistent,
     739         * thus the sync operation is a no-op.
     740         */
     741        async_answer_0(rid, EOK);
    640742}
    641743
Note: See TracChangeset for help on using the changeset viewer.