Changeset a4eb8a60 in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.c


Ignore:
Timestamp:
2007-12-22T22:58:57Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5c786d1
Parents:
c9957b6
Message:

VFS work.
Foundation for TMPFS-side VFS_READ and fixes in VFS-side VFS_READ.

File:
1 edited

Legend:

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

    rc9957b6 ra4eb8a60  
    4646#include <string.h>
    4747#include <stdio.h>
     48#include <sys/types.h>
     49#include <libadt/hash_table.h>
     50#include <as.h>
     51
     52#define min(a, b)               ((a) < (b) ? (a) : (b))
     53#define max(a, b)               ((a) > (b) ? (a) : (b))
    4854
    4955#define PLB_GET_CHAR(i)         (tmpfs_reg.plb_ro[(i) % PLB_SIZE])
     56
     57#define DENTRIES_BUCKETS        256
     58
     59/*
     60 * Hash table of all directory entries.
     61 */
     62hash_table_t dentries;
     63
     64static hash_index_t dentries_hash(unsigned long *key)
     65{
     66        return *key % DENTRIES_BUCKETS;
     67}
     68
     69static int dentries_compare(unsigned long *key, hash_count_t keys,
     70    link_t *item)
     71{
     72        tmpfs_dentry_t *dentry = hash_table_get_instance(item, tmpfs_dentry_t,
     73            dh_link);
     74        return dentry->index == *key;
     75}
     76
     77static void dentries_remove_callback(link_t *item)
     78{
     79}
     80
     81/** TMPFS dentries hash table operations. */
     82hash_table_operations_t dentries_ops = {
     83        .hash = dentries_hash,
     84        .compare = dentries_compare,
     85        .remove_callback = dentries_remove_callback
     86};
    5087
    5188unsigned tmpfs_next_index = 1;
     
    6198        dentry->size = 0;
    6299        dentry->data = NULL;
     100        link_initialize(&dentry->dh_link);
    63101}
    64102
     
    71109static bool tmpfs_init(void)
    72110{
     111        if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
     112                return false;
     113
    73114        root = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
    74         if (!root) {
    75                 return false;
    76         }
     115        if (!root)
     116                return false;
    77117        tmpfs_dentry_initialize(root);
    78118        root->index = tmpfs_next_index++;
    79119        root->name = "";
    80120        root->type = TMPFS_DIRECTORY;
     121        hash_table_insert(&dentries, &root->index, &root->dh_link);
    81122
    82123        /*
     
    97138        d->type = TMPFS_DIRECTORY;
    98139        d->name = "dir1";
     140        hash_table_insert(&dentries, &d->index, &d->dh_link);
    99141
    100142        d = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
     
    111153        d->type = TMPFS_DIRECTORY;
    112154        d->name = "dir2";
     155        hash_table_insert(&dentries, &d->index, &d->dh_link);
    113156       
    114157        d = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
     
    128171        d->data = "This is the contents of /dir1/file1.\n";
    129172        d->size = strlen(d->data);
     173        hash_table_insert(&dentries, &d->index, &d->dh_link);
    130174
    131175        d = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
     
    146190        d->data = "This is the contents of /dir2/file2.\n";
    147191        d->size = strlen(d->data);
     192        hash_table_insert(&dentries, &d->index, &d->dh_link);
    148193
    149194        return true;
     
    233278}
    234279
     280void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
     281{
     282        int dev_handle = IPC_GET_ARG1(*request);
     283        unsigned long index = IPC_GET_ARG2(*request);
     284        off_t pos = IPC_GET_ARG3(*request);
     285        size_t size = IPC_GET_ARG4(*request);
     286
     287        /*
     288         * Lookup the respective dentry.
     289         */
     290        link_t *hlp;
     291        hlp = hash_table_find(&dentries, &index);
     292        if (!hlp) {
     293                ipc_answer_0(rid, ENOENT);
     294                return;
     295        }
     296        tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
     297            dh_link);
     298
     299        /*
     300         * Receive the communication area.
     301         */
     302        ipc_callid_t callid;
     303        ipc_call_t call;
     304        callid = async_get_call(&call);
     305        if (IPC_GET_METHOD(call) != IPC_M_AS_AREA_SEND) {
     306                ipc_answer_0(callid, EINVAL);   
     307                ipc_answer_0(rid, EINVAL);
     308                return;
     309        }
     310
     311        int flags = IPC_GET_ARG3(call);
     312        if (!(flags & AS_AREA_WRITE)) {
     313                ipc_answer_0(callid, EINVAL);
     314                ipc_answer_0(rid, EINVAL);
     315                return;
     316        }
     317        size_t sz = IPC_GET_ARG2(call);
     318        uint8_t *buf = as_get_mappable_page(sz);
     319        if (!buf) {
     320                ipc_answer_0(callid, ENOMEM);
     321                ipc_answer_0(rid, ENOMEM);
     322                return;
     323        }
     324        ipc_answer_1(callid, EOK, buf);         /* commit to share the area */
     325
     326        size_t bytes = max(0, min(dentry->size - pos, size));
     327        memcpy(buf, dentry->data + pos, bytes);
     328
     329        (void) as_area_destroy(buf);
     330
     331        ipc_answer_1(rid, EOK, bytes);
     332}
     333
    235334/**
    236335 * @}
Note: See TracChangeset for help on using the changeset viewer.