Changeset 2b20947 in mainline for uspace/srv/vfs/vfs.c


Ignore:
Timestamp:
2007-09-15T14:47:57Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a0edf5f
Parents:
d0b72c4
Message:

VFS work.
Delve deeper into VFS_REGISTER.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs.c

    rd0b72c4 r2b20947  
    4141#include <errno.h>
    4242#include <stdlib.h>
     43#include <string.h>
     44#include <ctype.h>
    4345#include <bool.h>
     46#include <futex.h>
     47#include <libadt/list.h>
    4448#include "vfs.h"
    4549
     50atomic_t fs_head_futex = FUTEX_INITIALIZER;
     51link_t fs_head;
     52
    4653/** Verify the VFS info structure.
    4754 *
     
    5057 * @return              Non-zero if the info structure is sane, zero otherwise.
    5158 */
    52 static int vfs_info_sane(vfs_info_t *info)
    53 {
    54         return 1;       /* XXX */
     59static bool vfs_info_sane(vfs_info_t *info)
     60{
     61        int i;
     62
     63        /*
     64         * Check if the name is non-empty and is composed solely of ASCII
     65         * characters [a-z]+[a-z0-9_-]*.
     66         */
     67        if (!islower(info->name[0]))
     68                return false;
     69        for (i = 1; i < FS_NAME_MAXLEN; i++) {
     70                if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
     71                    (info->name[i] != '-') && (info->name[i] != '_')) {
     72                        if (info->name[i] == '\0')
     73                                break;
     74                        else
     75                                return false;
     76                }
     77        }
     78       
     79
     80        /*
     81         * Check if the FS implements mandatory VFS operations.
     82         */
     83        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_REGISTER)] != VFS_OP_DEFINED)
     84                return false;
     85        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] != VFS_OP_DEFINED)
     86                return false;
     87        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] != VFS_OP_DEFINED)
     88                return false;
     89        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] != VFS_OP_DEFINED)
     90                return false;
     91        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] != VFS_OP_DEFINED)
     92                return false;
     93        if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_READ)] != VFS_OP_DEFINED)
     94                return false;
     95       
     96        /*
     97         * Check if each operation is either not defined, defined or default.
     98         */
     99        for (i = VFS_FIRST; i < VFS_LAST; i++) {
     100                if ((IPC_METHOD_TO_VFS_OP(i) != VFS_OP_NULL) &&
     101                    (IPC_METHOD_TO_VFS_OP(i) != VFS_OP_DEFAULT) &&
     102                    (IPC_METHOD_TO_VFS_OP(i) != VFS_OP_DEFINED))
     103                        return false;   
     104        }
     105        return true;
    55106}
    56107
     
    81132       
    82133        /*
    83          * We know the size of the info structure. See if the client understands
    84          * this easy concept too.
     134         * We know the size of the VFS info structure. See if the client
     135         * understands this easy concept too.
    85136         */
    86137        if (size != sizeof(vfs_info_t)) {
     
    93144                return;
    94145        }
    95         vfs_info_t *info;
    96 
    97         /*
    98          * Allocate a buffer for the info structure.
    99          */
    100         info = (vfs_info_t *) malloc(sizeof(vfs_info_t));
    101         if (!info) {
     146        fs_info_t *fs_info;
     147
     148        /*
     149         * Allocate and initialize a buffer for the fs_info structure.
     150         */
     151        fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
     152        if (!fs_info) {
    102153                ipc_answer_fast(callid, ENOMEM, 0, 0);
    103154                ipc_answer_fast(rid, ENOMEM, 0, 0);
    104155                return;
    105156        }
    106                
    107         rc = ipc_data_send_answer(callid, &call, info, size);
     157        link_initialize(&fs_info->fs_link);
     158               
     159        rc = ipc_data_send_answer(callid, &call, &fs_info->vfs_info, size);
    108160        if (!rc) {
    109                 free(info);
     161                free(fs_info);
    110162                ipc_answer_fast(callid, rc, 0, 0);
    111163                ipc_answer_fast(rid, rc, 0, 0);
     
    113165        }
    114166               
    115         if (!vfs_info_sane(info)) {
    116                 free(info);
     167        if (!vfs_info_sane(&fs_info->vfs_info)) {
     168                free(fs_info);
    117169                ipc_answer_fast(callid, EINVAL, 0, 0);
    118170                ipc_answer_fast(rid, EINVAL, 0, 0);
     
    120172        }
    121173               
     174        futex_down(&fs_head_futex);
     175
     176        /*
     177         * Check for duplicit registrations.
     178         */
     179        link_t *cur;
     180        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     181                fs_info_t *fi = list_get_instance(cur, fs_info_t,
     182                    fs_link);
     183                /* TODO: replace strcmp with strncmp once we have it */
     184                if (strcmp(fs_info->vfs_info.name, fi->vfs_info.name) == 0) {
     185                        /*
     186                         * We already register a fs like this.
     187                         */
     188                        futex_up(&fs_head_futex);
     189                        free(fs_info);
     190                        ipc_answer_fast(callid, EEXISTS, 0, 0);
     191                        ipc_answer_fast(rid, EEXISTS, 0, 0);
     192                        return;
     193                }
     194        }
     195       
     196        /*
     197         * TODO:
     198         * 1. send the client the IPC_M_CONNECT_TO_ME call so that it makes a
     199         *    callback connection.
     200         * 2. add the fs_info into fs_head
     201         */
     202
     203        futex_up(&fs_head_futex);
    122204}
    123205
     
    178260        ipcarg_t phonead;
    179261
     262        list_initialize(&fs_head);
    180263        async_set_client_connection(vfs_connection);
    181264        ipc_connect_to_me(PHONE_NS, SERVICE_VFS, 0, &phonead);
Note: See TracChangeset for help on using the changeset viewer.