Changeset a4eb8a60 in mainline


Ignore:
Timestamp:
2007-12-22T22:58:57Z (17 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.

Location:
uspace/srv
Files:
4 edited

Legend:

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

    rc9957b6 ra4eb8a60  
    113113                        tmpfs_lookup(callid, &call);
    114114                        break;
     115                case VFS_READ:
     116                        tmpfs_read(callid, &call);
     117                        break;
    115118                default:
    116119                        ipc_answer_0(callid, ENOTSUP);
  • uspace/srv/fs/tmpfs/tmpfs.h

    rc9957b6 ra4eb8a60  
    3939#include <sys/types.h>
    4040#include <bool.h>
     41#include <libadt/hash_table.h>
    4142
    4243#define dprintf(...)    printf(__VA_ARGS__)
    4344
    4445typedef struct tmpfs_dentry {
    45         unsigned index;         /**< TMPFS node index. */
     46        unsigned long index;    /**< TMPFS node index. */
     47        link_t dh_link;         /**< Dentries hash table link. */
    4648        struct tmpfs_dentry *parent;
    4749        struct tmpfs_dentry *sibling;
     
    6062
    6163extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
     64extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
    6265
    6366#endif
  • 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 * @}
  • uspace/srv/vfs/vfs_read.c

    rc9957b6 ra4eb8a60  
    5050         * interleave and a file cannot be closed while it is being read).
    5151         *
    52          * Additional synchronization needs to be added once table table of
     52         * Additional synchronization needs to be added once the table of
    5353         * open files supports parallel access!
    5454         */
     
    6161
    6262        int fd = IPC_GET_ARG1(*request);
     63        size_t size = IPC_GET_ARG2(*request);
    6364
    6465        /*
     
    8990         */
    9091        aid_t msg;
    91         msg = async_send_3(fs_phone, VFS_READ, file->node->dev_handle,
    92             file->node->index, file->pos, NULL);
     92        ipc_call_t answer;
     93        msg = async_send_4(fs_phone, VFS_READ, file->node->dev_handle,
     94            file->node->index, file->pos, size, &answer);
    9395       
    9496        /*
     
    106108        ipcarg_t rc;
    107109        async_wait_for(msg, &rc);
     110        size_t bytes = IPC_GET_ARG1(answer);
    108111
    109112        /*
     
    111114         * return to the client.
    112115         */
    113         ipc_answer_0(rid, rc);
     116        ipc_answer_1(rid, rc, bytes);
    114117}
    115118
Note: See TracChangeset for help on using the changeset viewer.