Changeset a4b4b47 in mainline


Ignore:
Timestamp:
2008-06-03T15:11:15Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6a7f6b8
Parents:
536ec42
Message:

initialize tmpfs from RAM disk

Location:
uspace/srv/fs/tmpfs
Files:
2 edited

Legend:

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

    r536ec42 ra4b4b47  
    5050#include <libfs.h>
    5151#include "../../vfs/vfs.h"
     52
     53#define NAME "tmpfs"
    5254
    5355
     
    133135        int vfs_phone;
    134136
    135         printf("TMPFS: HelenOS TMPFS file system server.\n");
     137        printf(NAME ": HelenOS TMPFS file system server\n");
    136138
    137139        vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
     
    145147            tmpfs_connection);
    146148        if (rc != EOK) {
    147                 printf("Failed to register the TMPFS file system (%d)\n", rc);
     149                printf(NAME ": Failed to register file system (%d)\n", rc);
    148150                return rc;
    149151        }
    150152       
    151         dprintf("TMPFS filesystem registered, fs_handle=%d.\n",
    152             tmpfs_reg.fs_handle);
    153 
     153        printf(NAME ": Accepting connections\n");
    154154        async_manager();
    155155        /* not reached */
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r536ec42 ra4b4b47  
    5151#include <as.h>
    5252#include <libfs.h>
     53#include <ipc/services.h>
     54#include <ipc/devmap.h>
     55#include <sys/mman.h>
     56#include <byteorder.h>
    5357
    5458#define min(a, b)               ((a) < (b) ? (a) : (b))
     
    5862
    5963#define NAMES_BUCKETS           4
     64
     65#define BLOCK_SIZE                      1024    // FIXME
     66#define RD_BASE                         1024    // FIXME
     67#define RD_READ_BLOCK   (RD_BASE + 1)
    6068
    6169/*
     
    141149hash_table_t dentries;
    142150
     151struct rdentry {
     152        uint8_t type;
     153        uint32_t len;
     154} __attribute__((packed));
     155
    143156/* Implementation of hash table interface for the dentries hash table. */
    144157static hash_index_t dentries_hash(unsigned long *key)
     
    236249        root->lnkcnt = 1;
    237250        return true;
     251}
     252
     253static bool tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, size_t *pos, void *dst, size_t size)
     254{
     255        size_t offset = 0;
     256        size_t left = size;
     257       
     258        while (left > 0) {
     259                size_t rd;
     260               
     261                if (*bufpos + left < *buflen)
     262                        rd = left;
     263                else
     264                        rd = *buflen - *bufpos;
     265               
     266                if (rd > 0) {
     267                        memcpy(dst + offset, buffer + *bufpos, rd);
     268                        offset += rd;
     269                        *bufpos += rd;
     270                        *pos += rd;
     271                        left -= rd;
     272                }
     273               
     274                if (*bufpos == *buflen) {
     275                        int retval;
     276                        int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK, *pos / BLOCK_SIZE, BLOCK_SIZE, (sysarg_t *) &retval);
     277                        if ((rc != EOK) || (retval != EOK))
     278                                return false;
     279                       
     280                        *bufpos = 0;
     281                        *buflen = BLOCK_SIZE;
     282                }
     283        }
     284       
     285        return true;
     286}
     287
     288static bool tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, size_t *pos, tmpfs_dentry_t *parent)
     289{
     290        struct rdentry entry;
     291       
     292        do {
     293                char *fname;
     294                tmpfs_dentry_t *node;
     295                uint32_t size;
     296               
     297                if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, sizeof(entry)))
     298                        return false;
     299               
     300                entry.len = uint32_t_le2host(entry.len);
     301               
     302                switch (entry.type) {
     303                case 0:
     304                        break;
     305                case 1:
     306                        fname = malloc(entry.len + 1);
     307                        if (fname == NULL)
     308                                return false;
     309                       
     310                        node = (tmpfs_dentry_t *) tmpfs_create_node(L_FILE);
     311                        if (node == NULL) {
     312                                free(fname);
     313                                return false;
     314                        }
     315                       
     316                        if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
     317                                tmpfs_destroy_node((void *) node);
     318                                free(fname);
     319                                return false;
     320                        }
     321                        fname[entry.len] = 0;
     322                       
     323                        if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
     324                                tmpfs_destroy_node((void *) node);
     325                                free(fname);
     326                                return false;
     327                        }
     328                        free(fname);
     329                       
     330                        if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &size, sizeof(size)))
     331                                return false;
     332                       
     333                        size = uint32_t_le2host(size);
     334                       
     335                        node->data = malloc(size);
     336                        if (node->data == NULL)
     337                                return false;
     338                       
     339                        node->size = size;
     340                        if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, node->data, size))
     341                                return false;
     342                       
     343                        break;
     344                case 2:
     345                        fname = malloc(entry.len + 1);
     346                        if (fname == NULL)
     347                                return false;
     348                       
     349                        node = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
     350                        if (node == NULL) {
     351                                free(fname);
     352                                return false;
     353                        }
     354                       
     355                        if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
     356                                tmpfs_destroy_node((void *) node);
     357                                free(fname);
     358                                return false;
     359                        }
     360                        fname[entry.len] = 0;
     361                       
     362                        if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
     363                                tmpfs_destroy_node((void *) node);
     364                                free(fname);
     365                                return false;
     366                        }
     367                        free(fname);
     368                       
     369                        if (!tmpfs_restore_recursion(phone, block, bufpos, buflen, pos, node))
     370                                return false;
     371                       
     372                        break;
     373                default:
     374                        return false;
     375                }
     376        } while (entry.type != 0);
     377       
     378        return true;
     379}
     380
     381static bool tmpfs_restore(dev_handle_t dev)
     382{
     383        void *block = mmap(NULL, BLOCK_SIZE,
     384            PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
     385       
     386        if (block == NULL)
     387                return false;
     388       
     389        int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, dev);
     390
     391        if (phone < 0) {
     392                munmap(block, BLOCK_SIZE);
     393                return false;
     394        }
     395       
     396        if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != EOK)
     397                goto error;
     398       
     399        size_t bufpos = 0;
     400        size_t buflen = 0;
     401        size_t pos = 0;
     402       
     403        char tag[6];
     404        if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5))
     405                goto error;
     406       
     407        tag[5] = 0;
     408        if (strcmp(tag, "TMPFS") != 0)
     409                goto error;
     410       
     411        if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, root))
     412                goto error;
     413               
     414        ipc_hangup(phone);
     415        munmap(block, BLOCK_SIZE);
     416        return true;
     417       
     418error:
     419        ipc_hangup(phone);
     420        munmap(block, BLOCK_SIZE);
     421        return false;
    238422}
    239423
     
    396580void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
    397581{
    398         dev_handle_t mr_dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    399         fs_index_t mr_index = (fs_index_t)IPC_GET_ARG2(*request);
    400         fs_handle_t mp_fs_handle = (fs_handle_t)IPC_GET_ARG3(*request);
    401         dev_handle_t mp_dev_handle = (dev_handle_t)IPC_GET_ARG4(*request);
    402         fs_index_t mp_index = (fs_index_t)IPC_GET_ARG5(*request);
     582        dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     583        fs_index_t mr_index = (fs_index_t) IPC_GET_ARG2(*request);
     584        fs_handle_t mp_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
     585        dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
     586        fs_index_t mp_index = (fs_index_t) IPC_GET_ARG5(*request);
     587       
    403588        if ((mr_index == root->index) &&
    404             (mp_fs_handle == tmpfs_reg.fs_handle) &&
    405             (mp_index == mr_index))
    406                 ipc_answer_0(rid, EOK);
    407         else
     589                (mp_fs_handle == tmpfs_reg.fs_handle) &&
     590                (mp_index == mr_index)) {
     591               
     592                if (mr_dev_handle >= 0) {
     593                        if (tmpfs_restore(mr_dev_handle))
     594                                ipc_answer_0(rid, EOK);
     595                        else
     596                                ipc_answer_0(rid, ELIMIT);
     597                } else
     598                        ipc_answer_0(rid, EOK);
     599        } else
    408600                ipc_answer_0(rid, ENOTSUP);
    409601}
Note: See TracChangeset for help on using the changeset viewer.