Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 1313ee9 in mainline


Ignore:
Timestamp:
2009-12-13T15:17:08Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
963dd91
Parents:
fc6dd18
Message:

introduce device namespaces

  • add support for explicit open in libfs (needed by devfs, but also possibly for other filesystems which need to track some stateful information)
  • extend libfs to be more generic, make proper adjustments to libc, tmpfs and fat
  • various updates to make use of the device namespaces
  • code cleanup
Location:
uspace
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/ls/ls.c

    rfc6dd18 r1313ee9  
    100100        if (s.is_file)
    101101                printf("%-40s\t%llu\n", name, (long long) s.size);
     102        else if (s.is_directory)
     103                printf("%-40s\t<dir>\n", name);
    102104        else
    103105                printf("%-40s\n", name);
  • uspace/app/init/init.c

    rfc6dd18 r1313ee9  
    5858{
    5959        char *opts = "";
    60         const char *root_dev = "initrd";
     60        const char *root_dev = "bd/initrd";
    6161       
    6262        if (str_cmp(fstype, "tmpfs") == 0)
     
    9797        }
    9898       
    99         snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
     99        snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id);
    100100        int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING);
    101101       
     
    170170        }
    171171
    172         if (texit != TASK_EXIT_NORMAL || retval != 0) {
     172        if ((texit != TASK_EXIT_NORMAL) || (retval != 0)) {
    173173                printf(NAME ": Server %s failed to start (returned %d)\n",
    174174                        fname, retval);
     
    206206        int rc;
    207207
    208         printf("Trying to mount disk0 on /data... ");
     208        printf("Trying to mount bd/disk0 on /data... ");
    209209        fflush(stdout);
    210210
    211         rc = mount("fat", "/data", "disk0", "wtcache", 0);
     211        rc = mount("fat", "/data", "bd/disk0", "wtcache", 0);
    212212        if (rc == EOK)
    213213                printf("OK\n");
     
    256256#endif
    257257
    258         getvc("vc0", "/app/bdsh");
    259         getvc("vc1", "/app/bdsh");
    260         getvc("vc2", "/app/bdsh");
    261         getvc("vc3", "/app/bdsh");
    262         getvc("vc4", "/app/bdsh");
    263         getvc("vc5", "/app/bdsh");
    264         getvc("vc6", "/app/klog");
     258        getvc("term/vc0", "/app/bdsh");
     259        getvc("term/vc1", "/app/bdsh");
     260        getvc("term/vc2", "/app/bdsh");
     261        getvc("term/vc3", "/app/bdsh");
     262        getvc("term/vc4", "/app/bdsh");
     263        getvc("term/vc5", "/app/bdsh");
     264        getvc("term/vc6", "/app/klog");
    265265       
    266266        return 0;
  • uspace/app/tester/vfs/vfs1.c

    rfc6dd18 r1313ee9  
    8585                return "Unable to create null device";
    8686       
    87         snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
     87        snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id);
    8888        int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS);
    8989        switch (rc) {
  • uspace/lib/libc/generic/devmap.c

    rfc6dd18 r1313ee9  
    3535#include <async.h>
    3636#include <errno.h>
     37#include <malloc.h>
     38#include <bool.h>
    3739
    3840static int devmap_phone_driver = -1;
     
    105107        aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
    106108       
    107         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    108        
     109        ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
    109110        if (retval != EOK) {
    110111                async_wait_for(req, NULL);
     
    126127/** Register new device.
    127128 *
    128  * @param name   Device name.
    129  * @param handle Output: Handle to the created instance of device.
     129 * @param namespace Namespace name.
     130 * @param fqdn      Fully qualified device name.
     131 * @param handle    Output: Handle to the created instance of device.
    130132 *
    131133 */
    132 int devmap_device_register(const char *name, dev_handle_t *handle)
     134int devmap_device_register(const char *fqdn, dev_handle_t *handle)
    133135{
    134136        int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
     
    143145            &answer);
    144146       
    145         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    146        
     147        ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
    147148        if (retval != EOK) {
    148149                async_wait_for(req, NULL);
     
    167168}
    168169
    169 int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
     170int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags)
    170171{
    171172        int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
     
    180181            &answer);
    181182       
    182         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    183        
     183        ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
    184184        if (retval != EOK) {
    185185                async_wait_for(req, NULL);
     
    202202       
    203203        return retval;
     204}
     205
     206int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
     207{
     208        int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
     209       
     210        if (phone < 0)
     211                return phone;
     212       
     213        async_serialize_start();
     214       
     215        ipc_call_t answer;
     216        aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
     217            &answer);
     218       
     219        ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
     220        if (retval != EOK) {
     221                async_wait_for(req, NULL);
     222                async_serialize_end();
     223                return retval;
     224        }
     225       
     226        async_wait_for(req, &retval);
     227       
     228        async_serialize_end();
     229       
     230        if (retval != EOK) {
     231                if (handle != NULL)
     232                        *handle = (dev_handle_t) -1;
     233                return retval;
     234        }
     235       
     236        if (handle != NULL)
     237                *handle = (dev_handle_t) IPC_GET_ARG1(answer);
     238       
     239        return retval;
     240}
     241
     242devmap_handle_type_t devmap_handle_probe(dev_handle_t handle)
     243{
     244        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     245       
     246        if (phone < 0)
     247                return phone;
     248       
     249        ipcarg_t type;
     250        int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
     251        if (retval != EOK)
     252                return DEV_HANDLE_NONE;
     253       
     254        return (devmap_handle_type_t) type;
    204255}
    205256
     
    227278       
    228279        ipcarg_t null_id;
    229         int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
     280        int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
    230281        if (retval != EOK)
    231282                return -1;
     
    241292                return;
    242293       
    243         async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
    244 }
    245 
    246 ipcarg_t devmap_device_get_count(void)
    247 {
    248         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    249        
    250         if (phone < 0)
    251                 return 0;
    252        
     294        async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id);
     295}
     296
     297static size_t devmap_count_namespaces_internal(int phone)
     298{
    253299        ipcarg_t count;
    254         int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
     300        int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
    255301        if (retval != EOK)
    256302                return 0;
     
    259305}
    260306
    261 ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
    262 {
    263         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    264        
    265         if (phone < 0)
    266                 return 0;
    267        
    268         async_serialize_start();
    269        
    270         ipc_call_t answer;
    271         aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
    272        
    273         ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
    274        
    275         if (retval != EOK) {
    276                 async_wait_for(req, NULL);
    277                 async_serialize_end();
    278                 return 0;
    279         }
    280        
    281         async_wait_for(req, &retval);
    282        
    283         async_serialize_end();
    284        
     307static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle)
     308{
     309        ipcarg_t count;
     310        int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
    285311        if (retval != EOK)
    286312                return 0;
    287313       
    288         return IPC_GET_ARG1(answer);
    289 }
     314        return count;
     315}
     316
     317size_t devmap_count_namespaces(void)
     318{
     319        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     320       
     321        if (phone < 0)
     322                return 0;
     323       
     324        return devmap_count_namespaces_internal(phone);
     325}
     326
     327size_t devmap_count_devices(dev_handle_t ns_handle)
     328{
     329        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     330       
     331        if (phone < 0)
     332                return 0;
     333       
     334        return devmap_count_devices_internal(phone, ns_handle);
     335}
     336
     337size_t devmap_get_namespaces(dev_desc_t **data)
     338{
     339        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     340       
     341        if (phone < 0)
     342                return 0;
     343       
     344        /* Loop until namespaces read succesful */
     345        while (true) {
     346                size_t count = devmap_count_namespaces_internal(phone);
     347                if (count == 0)
     348                        return 0;
     349               
     350                dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
     351                if (devs == NULL)
     352                        return 0;
     353               
     354                async_serialize_start();
     355               
     356                ipc_call_t answer;
     357                aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
     358               
     359                int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     360                if (rc == EOVERFLOW) {
     361                        /*
     362                         * Number of namespaces has changed since
     363                         * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
     364                         */
     365                        async_serialize_end();
     366                        free(devs);
     367                        continue;
     368                }
     369               
     370                if (rc != EOK) {
     371                        async_wait_for(req, NULL);
     372                        async_serialize_end();
     373                        free(devs);
     374                        return 0;
     375                }
     376               
     377                ipcarg_t retval;
     378                async_wait_for(req, &retval);
     379                async_serialize_end();
     380               
     381                if (retval != EOK)
     382                        return 0;
     383               
     384                *data = devs;
     385                return count;
     386        }
     387}
     388
     389size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data)
     390{
     391        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     392       
     393        if (phone < 0)
     394                return 0;
     395       
     396        /* Loop until namespaces read succesful */
     397        while (true) {
     398                size_t count = devmap_count_devices_internal(phone, ns_handle);
     399                if (count == 0)
     400                        return 0;
     401               
     402                dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
     403                if (devs == NULL)
     404                        return 0;
     405               
     406                async_serialize_start();
     407               
     408                ipc_call_t answer;
     409                aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
     410               
     411                int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     412                if (rc == EOVERFLOW) {
     413                        /*
     414                         * Number of devices has changed since
     415                         * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
     416                         */
     417                        async_serialize_end();
     418                        free(devs);
     419                        continue;
     420                }
     421               
     422                if (rc != EOK) {
     423                        async_wait_for(req, NULL);
     424                        async_serialize_end();
     425                        free(devs);
     426                        return 0;
     427                }
     428               
     429                ipcarg_t retval;
     430                async_wait_for(req, &retval);
     431                async_serialize_end();
     432               
     433                if (retval != EOK)
     434                        return 0;
     435               
     436                *data = devs;
     437                return count;
     438        }
     439}
  • uspace/lib/libc/generic/vfs/vfs.c

    rfc6dd18 r1313ee9  
    117117}
    118118
    119 int mount(const char *fs_name, const char *mp, const char *dev,
     119int mount(const char *fs_name, const char *mp, const char *fqdn,
    120120    const char *opts, unsigned int flags)
    121121{
     
    126126        dev_handle_t dev_handle;
    127127       
    128         res = devmap_device_get_handle(dev, &dev_handle, flags);
     128        res = devmap_device_get_handle(fqdn, &dev_handle, flags);
    129129        if (res != EOK)
    130130                return res;
     
    703703        rc = fstat(fildes, &stat);
    704704
    705         if (!stat.devfs_stat.device)
     705        if (!stat.device)
    706706                return -1;
    707707       
    708         return devmap_device_connect(stat.devfs_stat.device, 0);
     708        return devmap_device_connect(stat.device, 0);
    709709}
    710710
  • uspace/lib/libc/include/devmap.h

    rfc6dd18 r1313ee9  
    3838#include <ipc/devmap.h>
    3939#include <async.h>
     40#include <bool.h>
    4041
    4142extern int devmap_get_phone(devmap_interface_t, unsigned int);
     
    4647
    4748extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
     49extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int);
     50extern devmap_handle_type_t devmap_handle_probe(dev_handle_t);
     51
    4852extern int devmap_device_connect(dev_handle_t, unsigned int);
    4953
     
    5155extern void devmap_null_destroy(int);
    5256
    53 extern ipcarg_t devmap_device_get_count(void);
    54 extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
     57extern size_t devmap_count_namespaces(void);
     58extern size_t devmap_count_devices(dev_handle_t);
     59
     60extern size_t devmap_get_namespaces(dev_desc_t **);
     61extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **);
    5562
    5663#endif
  • uspace/lib/libc/include/ipc/devmap.h

    rfc6dd18 r1313ee9  
    4343
    4444typedef enum {
     45        DEV_HANDLE_NONE,
     46        DEV_HANDLE_NAMESPACE,
     47        DEV_HANDLE_DEVICE
     48} devmap_handle_type_t;
     49
     50typedef enum {
    4551        DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
    4652        DEVMAP_DRIVER_UNREGISTER,
    4753        DEVMAP_DEVICE_REGISTER,
    4854        DEVMAP_DEVICE_UNREGISTER,
    49         DEVMAP_DEVICE_GET_NAME,
    5055        DEVMAP_DEVICE_GET_HANDLE,
    51         DEVMAP_DEVICE_NULL_CREATE,
    52         DEVMAP_DEVICE_NULL_DESTROY,
    53         DEVMAP_DEVICE_GET_COUNT,
    54         DEVMAP_DEVICE_GET_DEVICES
     56        DEVMAP_NAMESPACE_GET_HANDLE,
     57        DEVMAP_HANDLE_PROBE,
     58        DEVMAP_NULL_CREATE,
     59        DEVMAP_NULL_DESTROY,
     60        DEVMAP_GET_NAMESPACE_COUNT,
     61        DEVMAP_GET_DEVICE_COUNT,
     62        DEVMAP_GET_NAMESPACES,
     63        DEVMAP_GET_DEVICES
    5564} devmap_request_t;
    5665
  • uspace/lib/libc/include/sys/stat.h

    rfc6dd18 r1313ee9  
    4242
    4343struct stat {
    44         fs_handle_t     fs_handle;
    45         dev_handle_t    dev_handle;
    46         fs_index_t      index;
    47         unsigned        lnkcnt;
    48         bool            is_file;
    49         off_t           size;
    50         union {
    51                 struct {
    52                         dev_handle_t    device;
    53                 } devfs_stat;
    54         };
     44        fs_handle_t fs_handle;
     45        dev_handle_t dev_handle;
     46        fs_index_t index;
     47        unsigned int lnkcnt;
     48        bool is_file;
     49        bool is_directory;
     50        off_t size;
     51        dev_handle_t device;
    5552};
    5653
  • uspace/lib/libfs/libfs.c

    rfc6dd18 r1313ee9  
    11/*
    2  * Copyright (c) 2009 Jakub Jermar 
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libfs 
     29/** @addtogroup libfs
    3030 * @{
    31  */ 
     31 */
    3232/**
    3333 * @file
    34  * Glue code which is commonod to all FS implementations.
    35  */
    36 
    37 #include "libfs.h" 
     34 * Glue code which is common to all FS implementations.
     35 */
     36
     37#include "libfs.h"
    3838#include "../../srv/vfs/vfs.h"
    3939#include <errno.h>
     
    6767 * code.
    6868 *
    69  * @param vfs_phone     Open phone for communication with VFS.
    70  * @param reg           File system registration structure. It will be
    71  *                      initialized by this function.
    72  * @param info          VFS info structure supplied by the file system
    73  *                      implementation.
    74  * @param conn          Connection fibril for handling all calls originating in
    75  *                      VFS.
    76  *
    77  * @return              EOK on success or a non-zero error code on errror.
     69 * @param vfs_phone Open phone for communication with VFS.
     70 * @param reg       File system registration structure. It will be
     71 *                  initialized by this function.
     72 * @param info      VFS info structure supplied by the file system
     73 *                  implementation.
     74 * @param conn      Connection fibril for handling all calls originating in
     75 *                  VFS.
     76 *
     77 * @return EOK on success or a non-zero error code on errror.
     78 *
    7879 */
    7980int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     
    8788        ipc_call_t answer;
    8889        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    89 
     90       
    9091        /*
    9192         * Send our VFS info structure to VFS.
     
    9697                return rc;
    9798        }
    98 
     99       
    99100        /*
    100101         * Ask VFS for callback connection.
    101102         */
    102103        ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
    103 
     104       
    104105        /*
    105106         * Allocate piece of address space for PLB.
     
    110111                return ENOMEM;
    111112        }
    112 
     113       
    113114        /*
    114115         * Request sharing the Path Lookup Buffer with VFS.
     
    136137         */
    137138        async_set_client_connection(conn);
    138 
     139       
    139140        return IPC_GET_RETVAL(answer);
    140141}
     
    154155        int res;
    155156        ipcarg_t rc;
    156 
     157       
    157158        ipc_call_t call;
    158159        ipc_callid_t callid;
    159 
    160         /* accept the phone */
     160       
     161        /* Accept the phone */
    161162        callid = async_get_call(&call);
    162163        int mountee_phone = (int)IPC_GET_ARG1(call);
    163164        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    164             mountee_phone < 0) {
     165            (mountee_phone < 0)) {
    165166                ipc_answer_0(callid, EINVAL);
    166167                ipc_answer_0(rid, EINVAL);
    167168                return;
    168169        }
    169         ipc_answer_0(callid, EOK);      /* acknowledge the mountee_phone */
     170       
     171        /* Acknowledge the mountee_phone */
     172        ipc_answer_0(callid, EOK);
    170173       
    171174        res = async_data_write_receive(&callid, NULL);
     
    176179                return;
    177180        }
    178 
     181       
    179182        fs_node_t *fn;
    180183        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
    181         if (res != EOK || !fn) {
     184        if ((res != EOK) || (!fn)) {
    182185                ipc_hangup(mountee_phone);
    183186                ipc_answer_0(callid, combine_rc(res, ENOENT));
     
    185188                return;
    186189        }
    187 
     190       
    188191        if (fn->mp_data.mp_active) {
    189192                ipc_hangup(mountee_phone);
     
    193196                return;
    194197        }
    195 
     198       
    196199        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
    197200        if (rc != EOK) {
     
    215218                fn->mp_data.phone = mountee_phone;
    216219        }
     220       
    217221        /*
    218222         * Do not release the FS node so that it stays in memory.
     
    238242    ipc_call_t *request)
    239243{
    240         unsigned first = IPC_GET_ARG1(*request);
    241         unsigned last = IPC_GET_ARG2(*request);
    242         unsigned next = first;
     244        unsigned int first = IPC_GET_ARG1(*request);
     245        unsigned int last = IPC_GET_ARG2(*request);
     246        unsigned int next = first;
    243247        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    244248        int lflag = IPC_GET_ARG4(*request);
    245         fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
     249        fs_index_t index = IPC_GET_ARG5(*request);
    246250        char component[NAME_MAX + 1];
    247251        int len;
    248252        int rc;
    249 
     253       
    250254        if (last < next)
    251255                last += PLB_SIZE;
    252 
     256       
    253257        fs_node_t *par = NULL;
    254258        fs_node_t *cur = NULL;
    255259        fs_node_t *tmp = NULL;
    256 
     260       
    257261        rc = ops->root_get(&cur, dev_handle);
    258262        on_error(rc, goto out_with_answer);
    259 
     263       
    260264        if (cur->mp_data.mp_active) {
    261265                ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
     
    265269                return;
    266270        }
    267 
     271       
     272        /* Eat slash */
    268273        if (ops->plb_get_char(next) == '/')
    269                 next++;         /* eat slash */
     274                next++;
    270275       
    271276        while (next <= last) {
    272277                bool has_children;
    273 
     278               
    274279                rc = ops->has_children(&has_children, cur);
    275280                on_error(rc, goto out_with_answer);
    276281                if (!has_children)
    277282                        break;
    278 
    279                 /* collect the component */
     283               
     284                /* Collect the component */
    280285                len = 0;
    281                 while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
     286                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    282287                        if (len + 1 == NAME_MAX) {
    283                                 /* component length overflow */
     288                                /* Component length overflow */
    284289                                ipc_answer_0(rid, ENAMETOOLONG);
    285290                                goto out;
    286291                        }
    287292                        component[len++] = ops->plb_get_char(next);
    288                         next++; /* process next character */
     293                        /* Process next character */
     294                        next++;
    289295                }
    290 
     296               
    291297                assert(len);
    292298                component[len] = '\0';
    293                 next++;         /* eat slash */
    294 
    295                 /* match the component */
     299                /* Eat slash */
     300                next++;
     301               
     302                /* Match the component */
    296303                rc = ops->match(&tmp, cur, component);
    297304                on_error(rc, goto out_with_answer);
    298 
    299                 if (tmp && tmp->mp_data.mp_active) {
     305               
     306                if ((tmp) && (tmp->mp_data.mp_active)) {
    300307                        if (next > last)
    301308                                next = last = first;
    302309                        else
    303310                                next--;
    304                                
     311                       
    305312                        ipc_forward_slow(rid, tmp->mp_data.phone,
    306313                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
     
    312319                        return;
    313320                }
    314 
    315                 /* handle miss: match amongst siblings */
     321               
     322                /* Handle miss: match amongst siblings */
    316323                if (!tmp) {
    317324                        if (next <= last) {
    318                                 /* there are unprocessed components */
     325                                /* There are unprocessed components */
    319326                                ipc_answer_0(rid, ENOENT);
    320327                                goto out;
    321328                        }
    322                         /* miss in the last component */
    323                         if (lflag & (L_CREATE | L_LINK)) {
    324                                 /* request to create a new link */
     329                       
     330                        /* Miss in the last component */
     331                        if (lflag & (L_CREATE | L_LINK)) {
     332                                /* Request to create a new link */
    325333                                if (!ops->is_directory(cur)) {
    326334                                        ipc_answer_0(rid, ENOTDIR);
    327335                                        goto out;
    328336                                }
     337                               
    329338                                fs_node_t *fn;
    330339                                if (lflag & L_CREATE)
     
    335344                                            index);
    336345                                on_error(rc, goto out_with_answer);
     346                               
    337347                                if (fn) {
    338348                                        rc = ops->link(cur, fn, component);
     
    349359                                                (void) ops->node_put(fn);
    350360                                        }
    351                                 } else {
     361                                } else
    352362                                        ipc_answer_0(rid, ENOSPC);
    353                                 }
     363                               
    354364                                goto out;
    355                         }
     365                        }
     366                       
    356367                        ipc_answer_0(rid, ENOENT);
    357368                        goto out;
    358369                }
    359 
     370               
    360371                if (par) {
    361372                        rc = ops->node_put(par);
    362373                        on_error(rc, goto out_with_answer);
    363374                }
    364 
    365                 /* descend one level */
     375               
     376                /* Descend one level */
    366377                par = cur;
    367378                cur = tmp;
    368379                tmp = NULL;
    369380        }
    370 
    371         /* handle miss: excessive components */
     381       
     382        /* Handle miss: excessive components */
    372383        if (next <= last) {
    373384                bool has_children;
    374 
    375385                rc = ops->has_children(&has_children, cur);
    376386                on_error(rc, goto out_with_answer);
     387               
    377388                if (has_children)
    378389                        goto skip_miss;
    379 
     390               
    380391                if (lflag & (L_CREATE | L_LINK)) {
    381392                        if (!ops->is_directory(cur)) {
     
    383394                                goto out;
    384395                        }
    385 
    386                         /* collect next component */
     396                       
     397                        /* Collect next component */
    387398                        len = 0;
    388399                        while (next <= last) {
    389400                                if (ops->plb_get_char(next) == '/') {
    390                                         /* more than one component */
     401                                        /* More than one component */
    391402                                        ipc_answer_0(rid, ENOENT);
    392403                                        goto out;
    393404                                }
     405                               
    394406                                if (len + 1 == NAME_MAX) {
    395                                         /* component length overflow */
     407                                        /* Component length overflow */
    396408                                        ipc_answer_0(rid, ENAMETOOLONG);
    397409                                        goto out;
    398410                                }
     411                               
    399412                                component[len++] = ops->plb_get_char(next);
    400                                 next++; /* process next character */
     413                                /* Process next character */
     414                                next++;
    401415                        }
     416                       
    402417                        assert(len);
    403418                        component[len] = '\0';
    404                                
     419                       
    405420                        fs_node_t *fn;
    406421                        if (lflag & L_CREATE)
     
    409424                                rc = ops->node_get(&fn, dev_handle, index);
    410425                        on_error(rc, goto out_with_answer);
     426                       
    411427                        if (fn) {
    412428                                rc = ops->link(cur, fn, component);
     
    423439                                        (void) ops->node_put(fn);
    424440                                }
    425                         } else {
     441                        } else
    426442                                ipc_answer_0(rid, ENOSPC);
    427                         }
     443                       
    428444                        goto out;
    429445                }
     446               
    430447                ipc_answer_0(rid, ENOENT);
    431448                goto out;
    432449        }
     450       
    433451skip_miss:
    434 
    435         /* handle hit */
     452       
     453        /* Handle hit */
    436454        if (lflag & L_UNLINK) {
    437                 unsigned old_lnkcnt = ops->lnkcnt_get(cur);
     455                unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
    438456                rc = ops->unlink(par, cur, component);
    439                 ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
     457                ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,
    440458                    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
    441459                goto out;
    442460        }
     461       
    443462        if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
    444463            (lflag & L_LINK)) {
     
    446465                goto out;
    447466        }
     467       
    448468        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
    449469                ipc_answer_0(rid, EISDIR);
    450470                goto out;
    451471        }
     472       
    452473        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
    453474                ipc_answer_0(rid, ENOTDIR);
    454475                goto out;
    455476        }
    456 
     477       
    457478out_with_answer:
     479       
    458480        if (rc == EOK) {
    459                 ipc_answer_5(rid, EOK, fs_handle, dev_handle,
     481                if (lflag & L_OPEN)
     482                        rc = ops->node_open(cur);
     483               
     484                ipc_answer_5(rid, rc, fs_handle, dev_handle,
    460485                    ops->index_get(cur), ops->size_get(cur),
    461486                    ops->lnkcnt_get(cur));
    462         } else {
     487        } else
    463488                ipc_answer_0(rid, rc);
    464         }
    465 
     489       
    466490out:
     491       
    467492        if (par)
    468493                (void) ops->node_put(par);
     494       
    469495        if (cur)
    470496                (void) ops->node_put(cur);
     497       
    471498        if (tmp)
    472499                (void) ops->node_put(tmp);
     
    478505        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    479506        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     507       
    480508        fs_node_t *fn;
    481         int rc;
    482 
    483         rc = ops->node_get(&fn, dev_handle, index);
     509        int rc = ops->node_get(&fn, dev_handle, index);
    484510        on_error(rc, answer_and_return(rid, rc));
    485 
     511       
    486512        ipc_callid_t callid;
    487513        size_t size;
    488         if (!async_data_read_receive(&callid, &size) ||
    489             size != sizeof(struct stat)) {
     514        if ((!async_data_read_receive(&callid, &size)) ||
     515            (size != sizeof(struct stat))) {
     516                ops->node_put(fn);
    490517                ipc_answer_0(callid, EINVAL);
    491518                ipc_answer_0(rid, EINVAL);
    492519                return;
    493520        }
    494 
     521       
    495522        struct stat stat;
    496523        memset(&stat, 0, sizeof(struct stat));
     
    499526        stat.dev_handle = dev_handle;
    500527        stat.index = index;
    501         stat.lnkcnt = ops->lnkcnt_get(fn); 
     528        stat.lnkcnt = ops->lnkcnt_get(fn);
    502529        stat.is_file = ops->is_file(fn);
     530        stat.is_directory = ops->is_directory(fn);
    503531        stat.size = ops->size_get(fn);
    504 
     532        stat.device = ops->device_get(fn);
     533       
     534        ops->node_put(fn);
     535       
    505536        async_data_read_finalize(callid, &stat, sizeof(struct stat));
    506537        ipc_answer_0(rid, EOK);
     
    509540/** Open VFS triplet.
    510541 *
    511  * @param ops       libfs operations structure with function pointers to
    512  *                  file system implementation
    513  * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
    514  * @param request   VFS_OUT_OPEN_NODE request data itself.
     542 * @param ops     libfs operations structure with function pointers to
     543 *                file system implementation
     544 * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
     545 * @param request VFS_OUT_OPEN_NODE request data itself.
    515546 *
    516547 */
     
    531562        }
    532563       
    533         ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
     564        rc = ops->node_open(fn);
     565        ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn),
    534566            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    535567       
  • uspace/lib/libfs/libfs.h

    rfc6dd18 r1313ee9  
    6464        int (* match)(fs_node_t **, fs_node_t *, const char *);
    6565        int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
     66        int (* node_open)(fs_node_t *);
    6667        int (* node_put)(fs_node_t *);
    6768        int (* create)(fs_node_t **, dev_handle_t, int);
     
    7677        fs_index_t (* index_get)(fs_node_t *);
    7778        size_t (* size_get)(fs_node_t *);
    78         unsigned (* lnkcnt_get)(fs_node_t *);
     79        unsigned int (* lnkcnt_get)(fs_node_t *);
    7980        char (* plb_get_char)(unsigned pos);
    8081        bool (* is_directory)(fs_node_t *);
    8182        bool (* is_file)(fs_node_t *);
     83        dev_handle_t (* device_get)(fs_node_t *);
    8284} libfs_ops_t;
    8385
  • uspace/srv/bd/ata_bd/ata_bd.c

    rfc6dd18 r1313ee9  
    6666#include "ata_bd.h"
    6767
    68 #define NAME "ata_bd"
     68#define NAME       "ata_bd"
     69#define NAMESPACE  "bd"
    6970
    7071/** Physical block size. Should be always 512. */
     
    135136                if (disk[i].present == false)
    136137                        continue;
    137 
    138                 snprintf(name, 16, "disk%d", i);
     138               
     139                snprintf(name, 16, "%s/disk%d", NAMESPACE, i);
    139140                rc = devmap_device_register(name, &disk[i].dev_handle);
    140141                if (rc != EOK) {
    141142                        devmap_hangup_phone(DEVMAP_DRIVER);
    142                         printf(NAME ": Unable to register device %s.\n",
    143                                 name);
     143                        printf(NAME ": Unable to register device %s.\n", name);
    144144                        return rc;
    145145                }
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    rfc6dd18 r1313ee9  
    5050#include <task.h>
    5151
    52 #define NAME "gxe_bd"
     52#define NAME       "gxe_bd"
     53#define NAMESPACE  "bd"
    5354
    5455enum {
     
    141142
    142143        for (i = 0; i < MAX_DISKS; i++) {
    143                 snprintf(name, 16, "disk%d", i);
     144                snprintf(name, 16, "%s/disk%d", NAMESPACE, i);
    144145                rc = devmap_device_register(name, &dev_handle[i]);
    145146                if (rc != EOK) {
    146147                        devmap_hangup_phone(DEVMAP_DRIVER);
    147                         printf(NAME ": Unable to register device %s.\n",
    148                                 name);
     148                        printf(NAME ": Unable to register device %s.\n", name);
    149149                        return rc;
    150150                }
  • uspace/srv/bd/rd/rd.c

    rfc6dd18 r1313ee9  
    228228       
    229229        dev_handle_t dev_handle;
    230         if (devmap_device_register("initrd", &dev_handle) != EOK) {
     230        if (devmap_device_register("bd/initrd", &dev_handle) != EOK) {
    231231                devmap_hangup_phone(DEVMAP_DRIVER);
    232232                printf(NAME ": Unable to register device\n");
  • uspace/srv/console/console.c

    rfc6dd18 r1313ee9  
    5757#include "screenbuffer.h"
    5858
    59 #define NAME  "console"
    60 
    61 #define MAX_DEVICE_NAME  32
     59#define NAME       "console"
     60#define NAMESPACE  "term"
    6261
    6362/** Phone to the keyboard driver. */
     
    6968        ipcarg_t cols;  /**< Framebuffer columns */
    7069        ipcarg_t rows;  /**< Framebuffer rows */
    71         int color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
     70        int color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
    7271} fb_info;
    7372
     
    740739                        consoles[i].refcount = 0;
    741740                       
    742                         char vc[MAX_DEVICE_NAME];
    743                         snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
     741                        char vc[DEVMAP_NAME_MAXLEN + 1];
     742                        snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%u", NAMESPACE, i);
    744743                       
    745744                        if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
  • uspace/srv/devmap/devmap.c

    rfc6dd18 r1313ee9  
    6868} devmap_driver_t;
    6969
     70/** Info about registered namespaces
     71 *
     72 */
     73typedef struct {
     74        /** Pointer to the previous and next device in the list of all namespaces */
     75        link_t namespaces;
     76        /** Unique namespace identifier */
     77        dev_handle_t handle;
     78        /** Namespace name */
     79        char *name;
     80        /** Reference count */
     81        size_t refcnt;
     82} devmap_namespace_t;
     83
    7084/** Info about registered device
    7185 *
     
    7791            owned by one driver */
    7892        link_t driver_devices;
    79         /** Unique device identifier  */
     93        /** Unique device identifier */
    8094        dev_handle_t handle;
     95        /** Device namespace */
     96        devmap_namespace_t *namespace;
    8197        /** Device name */
    8298        char *name;
     
    86102
    87103LIST_INITIALIZE(devices_list);
     104LIST_INITIALIZE(namespaces_list);
    88105LIST_INITIALIZE(drivers_list);
    89106
     
    117134}
    118135
     136/** Convert fully qualified device name to namespace and device name.
     137 *
     138 * A fully qualified device name can be either a plain device name
     139 * (then the namespace is considered to be an empty string) or consist
     140 * of two components separated by a slash. No more than one slash
     141 * is allowed.
     142 *
     143 */
     144static bool devmap_fqdn_split(const char *fqdn, char **ns_name, char **name)
     145{
     146        size_t cnt = 0;
     147        size_t slash_offset = 0;
     148        size_t slash_after = 0;
     149       
     150        size_t offset = 0;
     151        size_t offset_prev = 0;
     152        wchar_t c;
     153       
     154        while ((c = str_decode(fqdn, &offset, STR_NO_LIMIT)) != 0) {
     155                if (c == '/') {
     156                        cnt++;
     157                        slash_offset = offset_prev;
     158                        slash_after = offset;
     159                }
     160                offset_prev = offset;
     161        }
     162       
     163        /* More than one slash */
     164        if (cnt > 1)
     165                return false;
     166       
     167        /* No slash -> namespace is empty */
     168        if (cnt == 0) {
     169                *ns_name = str_dup("");
     170                if (*ns_name == NULL)
     171                        return false;
     172               
     173                *name = str_dup(fqdn);
     174                if ((*name == NULL) || (str_cmp(*name, "") == 0)) {
     175                        free(*ns_name);
     176                        return false;
     177                }
     178               
     179                return true;
     180        }
     181       
     182        /* Exactly one slash */
     183        *ns_name = str_ndup(fqdn, slash_offset);
     184        if (*ns_name == NULL)
     185                return false;
     186       
     187        *name = str_dup(fqdn + slash_after);
     188        if ((*name == NULL) || (str_cmp(*name, "") == 0)) {
     189                free(*ns_name);
     190                return false;
     191        }
     192       
     193        return true;
     194}
     195
     196/** Find namespace with given name.
     197 *
     198 * The devices_list_mutex should be already held when
     199 * calling this function.
     200 *
     201 */
     202static devmap_namespace_t *devmap_namespace_find_name(const char *name)
     203{
     204        link_t *item = namespaces_list.next;
     205       
     206        while (item != &namespaces_list) {
     207                devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
     208                if (str_cmp(namespace->name, name) == 0)
     209                        return namespace;
     210                item = item->next;
     211        }
     212       
     213        return NULL;
     214}
     215
     216/** Find namespace with given handle.
     217 *
     218 * The devices_list_mutex should be already held when
     219 * calling this function.
     220 *
     221 * @todo: use hash table
     222 *
     223 */
     224static devmap_namespace_t *devmap_namespace_find_handle(dev_handle_t handle)
     225{
     226        link_t *item = namespaces_list.next;
     227       
     228        while (item != &namespaces_list) {
     229                devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
     230                if (namespace->handle == handle)
     231                        return namespace;
     232               
     233                item = item->next;
     234        }
     235       
     236        return NULL;
     237}
     238
    119239/** Find device with given name.
    120240 *
    121  */
    122 static devmap_device_t *devmap_device_find_name(const char *name)
     241 * The devices_list_mutex should be already held when
     242 * calling this function.
     243 *
     244 */
     245static devmap_device_t *devmap_device_find_name(const char *ns_name,
     246    const char *name)
    123247{
    124248        link_t *item = devices_list.next;
    125         devmap_device_t *device = NULL;
    126249       
    127250        while (item != &devices_list) {
    128                 device = list_get_instance(item, devmap_device_t, devices);
    129                 if (str_cmp(device->name, name) == 0)
    130                         break;
     251                devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
     252                if ((str_cmp(device->namespace->name, ns_name) == 0) && (str_cmp(device->name, name) == 0))
     253                        return device;
    131254                item = item->next;
    132255        }
    133256       
    134         if (item == &devices_list)
     257        return NULL;
     258}
     259
     260/** Find device with given handle.
     261 *
     262 * The devices_list_mutex should be already held when
     263 * calling this function.
     264 *
     265 * @todo: use hash table
     266 *
     267 */
     268static devmap_device_t *devmap_device_find_handle(dev_handle_t handle)
     269{
     270        link_t *item = devices_list.next;
     271       
     272        while (item != &devices_list) {
     273                devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
     274                if (device->handle == handle)
     275                        return device;
     276               
     277                item = item->next;
     278        }
     279       
     280        return NULL;
     281}
     282
     283/** Create a namespace (if not already present)
     284 *
     285 * The devices_list_mutex should be already held when
     286 * calling this function.
     287 *
     288 */
     289static devmap_namespace_t *devmap_namespace_create(const char *ns_name)
     290{
     291        devmap_namespace_t *namespace = devmap_namespace_find_name(ns_name);
     292        if (namespace != NULL)
     293                return namespace;
     294       
     295        namespace = (devmap_namespace_t *) malloc(sizeof(devmap_namespace_t));
     296        if (namespace == NULL)
    135297                return NULL;
    136298       
    137         device = list_get_instance(item, devmap_device_t, devices);
    138         return device;
    139 }
    140 
    141 /** Find device with given handle.
    142  *
    143  * @todo: use hash table
    144  *
    145  */
    146 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle)
    147 {
    148         fibril_mutex_lock(&devices_list_mutex);
    149        
    150         link_t *item = (&devices_list)->next;
    151         devmap_device_t *device = NULL;
    152        
    153         while (item != &devices_list) {
    154                 device = list_get_instance(item, devmap_device_t, devices);
    155                 if (device->handle == handle)
    156                         break;
    157                 item = item->next;
    158         }
    159        
    160         if (item == &devices_list) {
    161                 fibril_mutex_unlock(&devices_list_mutex);
     299        namespace->name = str_dup(ns_name);
     300        if (namespace->name == NULL) {
     301                free(namespace);
    162302                return NULL;
    163303        }
    164304       
    165         device = list_get_instance(item, devmap_device_t, devices);
    166        
    167         fibril_mutex_unlock(&devices_list_mutex);
    168        
    169         return device;
    170 }
    171 
    172 /**
    173  * Unregister device and free it. It's assumed that driver's device list is
    174  * already locked.
    175  */
    176 static int devmap_device_unregister_core(devmap_device_t *device)
    177 {
     305        namespace->handle = devmap_create_handle();
     306        namespace->refcnt = 0;
     307       
     308        /*
     309         * Insert new namespace into list of registered namespaces
     310         */
     311        list_append(&(namespace->namespaces), &namespaces_list);
     312       
     313        return namespace;
     314}
     315
     316/** Destroy a namespace (if it is no longer needed)
     317 *
     318 * The devices_list_mutex should be already held when
     319 * calling this function.
     320 *
     321 */
     322static void devmap_namespace_destroy(devmap_namespace_t *namespace)
     323{
     324        if (namespace->refcnt == 0) {
     325                list_remove(&(namespace->namespaces));
     326               
     327                free(namespace->name);
     328                free(namespace);
     329        }
     330}
     331
     332/** Increase namespace reference count by including device
     333 *
     334 * The devices_list_mutex should be already held when
     335 * calling this function.
     336 *
     337 */
     338static void devmap_namespace_addref(devmap_namespace_t *namespace,
     339    devmap_device_t *device)
     340{
     341        device->namespace = namespace;
     342        namespace->refcnt++;
     343}
     344
     345/** Decrease namespace reference count
     346 *
     347 * The devices_list_mutex should be already held when
     348 * calling this function.
     349 *
     350 */
     351static void devmap_namespace_delref(devmap_namespace_t *namespace)
     352{
     353        namespace->refcnt--;
     354        devmap_namespace_destroy(namespace);
     355}
     356
     357/** Unregister device and free it
     358 *
     359 * The devices_list_mutex should be already held when
     360 * calling this function.
     361 *
     362 */
     363static void devmap_device_unregister_core(devmap_device_t *device)
     364{
     365        devmap_namespace_delref(device->namespace);
    178366        list_remove(&(device->devices));
    179367        list_remove(&(device->driver_devices));
    180368       
     369        free(device->namespace);
    181370        free(device->name);
    182371        free(device);
    183        
    184         return EOK;
    185372}
    186373
     
    189376 * drivers.
    190377 */
    191 static void devmap_driver_register(devmap_driver_t **odriver)
    192 {
    193         *odriver = NULL;
    194        
     378static devmap_driver_t *devmap_driver_register(void)
     379{
    195380        ipc_call_t icall;
    196381        ipc_callid_t iid = async_get_call(&icall);
     
    198383        if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
    199384                ipc_answer_0(iid, EREFUSED);
    200                 return;
     385                return NULL;
    201386        }
    202387       
     
    205390        if (driver == NULL) {
    206391                ipc_answer_0(iid, ENOMEM);
    207                 return;
     392                return NULL;
    208393        }
    209394       
     
    211396         * Get driver name
    212397         */
    213         ipc_callid_t callid;
    214         size_t name_size;
    215         if (!async_data_write_receive(&callid, &name_size)) {
     398        int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN);
     399        if (rc != EOK) {
    216400                free(driver);
    217                 ipc_answer_0(callid, EREFUSED);
    218                 ipc_answer_0(iid, EREFUSED);
    219                 return;
    220         }
    221        
    222         if (name_size > DEVMAP_NAME_MAXLEN) {
    223                 free(driver);
    224                 ipc_answer_0(callid, EINVAL);
    225                 ipc_answer_0(iid, EREFUSED);
    226                 return;
    227         }
    228        
    229         /*
    230          * Allocate buffer for device name.
    231          */
    232         driver->name = (char *) malloc(name_size + 1);
    233         if (driver->name == NULL) {
    234                 free(driver);
    235                 ipc_answer_0(callid, ENOMEM);
    236                 ipc_answer_0(iid, EREFUSED);
    237                 return;
    238         }
    239        
    240         /*
    241          * Send confirmation to sender and get data into buffer.
    242          */
    243         if (async_data_write_finalize(callid, driver->name, name_size) != EOK) {
    244                 free(driver->name);
    245                 free(driver);
    246                 ipc_answer_0(iid, EREFUSED);
    247                 return;
    248         }
    249        
    250         driver->name[name_size] = 0;
     401                ipc_answer_0(iid, rc);
     402                return NULL;
     403        }
    251404       
    252405        /* Initialize mutex for list of devices owned by this driver */
     
    262415         */
    263416        ipc_call_t call;
    264         callid = async_get_call(&call);
     417        ipc_callid_t callid = async_get_call(&call);
    265418       
    266419        if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
     
    270423                free(driver);
    271424                ipc_answer_0(iid, ENOTSUP);
    272                 return;
     425                return NULL;
    273426        }
    274427       
     
    293446        ipc_answer_0(iid, EOK);
    294447       
    295         *odriver = driver;
     448        return driver;
    296449}
    297450
     
    355508        }
    356509       
    357         /* Get device name */
    358         ipc_callid_t callid;
    359         size_t size;
    360         if (!async_data_write_receive(&callid, &size)) {
     510        /* Get fqdn */
     511        char *fqdn;
     512        int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
     513        if (rc != EOK) {
    361514                free(device);
    362                 ipc_answer_0(iid, EREFUSED);
    363                 return;
    364         }
    365        
    366         if (size > DEVMAP_NAME_MAXLEN) {
     515                ipc_answer_0(iid, rc);
     516                return;
     517        }
     518       
     519        char *ns_name;
     520        if (!devmap_fqdn_split(fqdn, &ns_name, &device->name)) {
     521                free(fqdn);
    367522                free(device);
    368                 ipc_answer_0(callid, EINVAL);
    369                 ipc_answer_0(iid, EREFUSED);
    370                 return;
    371         }
    372        
    373         /* +1 for terminating \0 */
    374         device->name = (char *) malloc(size + 1);
    375        
    376         if (device->name == NULL) {
     523                ipc_answer_0(iid, EINVAL);
     524                return;
     525        }
     526       
     527        free(fqdn);
     528       
     529        fibril_mutex_lock(&devices_list_mutex);
     530       
     531        devmap_namespace_t *namespace = devmap_namespace_create(ns_name);
     532        free(ns_name);
     533        if (!namespace) {
     534                fibril_mutex_unlock(&devices_list_mutex);
    377535                free(device);
    378                 ipc_answer_0(callid, ENOMEM);
    379                 ipc_answer_0(iid, EREFUSED);
    380                 return;
    381         }
    382        
    383         async_data_write_finalize(callid, device->name, size);
    384         device->name[size] = 0;
     536                ipc_answer_0(iid, ENOMEM);
     537                return;
     538        }
    385539       
    386540        list_initialize(&(device->devices));
    387541        list_initialize(&(device->driver_devices));
    388542       
    389         fibril_mutex_lock(&devices_list_mutex);
    390        
    391         /* Check that device with such name is not already registered */
    392         if (NULL != devmap_device_find_name(device->name)) {
    393                 printf(NAME ": Device '%s' already registered\n", device->name);
     543        /* Check that device is not already registered */
     544        if (devmap_device_find_name(namespace->name, device->name) != NULL) {
     545                printf(NAME ": Device '%s/%s' already registered\n", device->namespace, device->name);
     546                devmap_namespace_destroy(namespace);
    394547                fibril_mutex_unlock(&devices_list_mutex);
     548                free(device->namespace);
    395549                free(device->name);
    396550                free(device);
     
    402556        device->handle = devmap_create_handle();
    403557       
     558        devmap_namespace_addref(namespace, device);
    404559        device->driver = driver;
    405560       
     
    437592static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
    438593{
     594        fibril_mutex_lock(&devices_list_mutex);
     595       
    439596        /*
    440597         * Get handle from request
     
    450607        ipc_forward_fast(callid, dev->driver->phone, dev->handle,
    451608            IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
     609       
     610        fibril_mutex_unlock(&devices_list_mutex);
    452611}
    453612
     
    458617 *
    459618 */
    460 static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
    461 {
    462         /*
    463          * Wait for incoming message with device name (but do not
    464          * read the name itself until the buffer is allocated).
    465          */
    466         ipc_callid_t callid;
    467         size_t size;
    468         if (!async_data_write_receive(&callid, &size)) {
    469                 ipc_answer_0(callid, EREFUSED);
    470                 ipc_answer_0(iid, EREFUSED);
    471                 return;
    472         }
    473        
    474         if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) {
    475                 ipc_answer_0(callid, EINVAL);
    476                 ipc_answer_0(iid, EREFUSED);
    477                 return;
    478         }
    479        
    480         /*
    481          * Allocate buffer for device name.
    482          */
    483         char *name = (char *) malloc(size + 1);
    484         if (name == NULL) {
    485                 ipc_answer_0(callid, ENOMEM);
    486                 ipc_answer_0(iid, EREFUSED);
    487                 return;
    488         }
    489        
    490         /*
    491          * Send confirmation to sender and get data into buffer.
    492          */
    493         ipcarg_t retval = async_data_write_finalize(callid, name, size);
    494         if (retval != EOK) {
    495                 ipc_answer_0(iid, EREFUSED);
    496                 free(name);
    497                 return;
    498         }
    499         name[size] = '\0';
     619static void devmap_device_get_handle(ipc_callid_t iid, ipc_call_t *icall)
     620{
     621        char *fqdn;
     622       
     623        /* Get fqdn */
     624        int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
     625        if (rc != EOK) {
     626                ipc_answer_0(iid, rc);
     627                return;
     628        }
     629       
     630        char *ns_name;
     631        char *name;
     632        if (!devmap_fqdn_split(fqdn, &ns_name, &name)) {
     633                free(fqdn);
     634                ipc_answer_0(iid, EINVAL);
     635                return;
     636        }
     637       
     638        free(fqdn);
    500639       
    501640        fibril_mutex_lock(&devices_list_mutex);
    502641        const devmap_device_t *dev;
     642       
    503643recheck:
    504 
     644       
    505645        /*
    506646         * Find device name in the list of known devices.
    507647         */
    508         dev = devmap_device_find_name(name);
     648        dev = devmap_device_find_name(ns_name, name);
    509649       
    510650        /*
     
    520660               
    521661                ipc_answer_0(iid, ENOENT);
     662                free(ns_name);
    522663                free(name);
    523664                fibril_mutex_unlock(&devices_list_mutex);
     
    527668       
    528669        ipc_answer_1(iid, EOK, dev->handle);
     670        free(ns_name);
    529671        free(name);
    530672}
    531673
    532 /** Find name of device identified by id and send it to caller.
    533  *
    534  */
    535 static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
    536 {
    537         const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
     674/** Find handle for namespace identified by name.
     675 *
     676 * In answer will be send EOK and device handle in arg1 or a error
     677 * code from errno.h.
     678 *
     679 */
     680static void devmap_namespace_get_handle(ipc_callid_t iid, ipc_call_t *icall)
     681{
     682        char *name;
     683       
     684        /* Get device name */
     685        int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN);
     686        if (rc != EOK) {
     687                ipc_answer_0(iid, rc);
     688                return;
     689        }
     690       
     691        fibril_mutex_lock(&devices_list_mutex);
     692        const devmap_namespace_t *namespace;
     693       
     694recheck:
    538695       
    539696        /*
    540          * Device not found.
     697         * Find namespace name in the list of known namespaces.
    541698         */
    542         if (device == NULL) {
     699        namespace = devmap_namespace_find_name(name);
     700       
     701        /*
     702         * Namespace was not found.
     703         */
     704        if (namespace == NULL) {
     705                if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
     706                        /* Blocking lookup */
     707                        fibril_condvar_wait(&devices_list_cv,
     708                            &devices_list_mutex);
     709                        goto recheck;
     710                }
     711               
    543712                ipc_answer_0(iid, ENOENT);
    544                 return;
    545         }
    546        
    547         ipc_answer_0(iid, EOK);
    548        
    549         /* FIXME:
    550          * We have no channel from DEVMAP to client, therefore
    551          * sending must be initiated by client.
    552          *
    553          * size_t name_size = str_size(device->name);
    554          *
    555          * int rc = async_data_write_send(phone, device->name, name_size);
    556          * if (rc != EOK) {
    557          *     async_wait_for(req, NULL);
    558          *     return rc;
    559          * }
    560          */
    561        
    562         /* TODO: send name in response */
    563 }
    564 
    565 static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall)
     713                free(name);
     714                fibril_mutex_unlock(&devices_list_mutex);
     715                return;
     716        }
     717        fibril_mutex_unlock(&devices_list_mutex);
     718       
     719        ipc_answer_1(iid, EOK, namespace->handle);
     720        free(name);
     721}
     722
     723static void devmap_handle_probe(ipc_callid_t iid, ipc_call_t *icall)
    566724{
    567725        fibril_mutex_lock(&devices_list_mutex);
    568         ipc_answer_1(iid, EOK, list_count(&devices_list));
     726       
     727        devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
     728        if (namespace == NULL) {
     729                devmap_device_t *dev = devmap_device_find_handle(IPC_GET_ARG1(*icall));
     730                if (dev == NULL)
     731                        ipc_answer_1(iid, EOK, DEV_HANDLE_NONE);
     732                else
     733                        ipc_answer_1(iid, EOK, DEV_HANDLE_DEVICE);
     734        } else
     735                ipc_answer_1(iid, EOK, DEV_HANDLE_NAMESPACE);
     736       
    569737        fibril_mutex_unlock(&devices_list_mutex);
    570738}
    571739
    572 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall)
     740static void devmap_get_namespace_count(ipc_callid_t iid, ipc_call_t *icall)
    573741{
    574742        fibril_mutex_lock(&devices_list_mutex);
    575        
     743        ipc_answer_1(iid, EOK, list_count(&namespaces_list));
     744        fibril_mutex_unlock(&devices_list_mutex);
     745}
     746
     747static void devmap_get_device_count(ipc_callid_t iid, ipc_call_t *icall)
     748{
     749        fibril_mutex_lock(&devices_list_mutex);
     750       
     751        devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
     752        if (namespace == NULL)
     753                ipc_answer_0(iid, EEXISTS);
     754        else
     755                ipc_answer_1(iid, EOK, namespace->refcnt);
     756       
     757        fibril_mutex_unlock(&devices_list_mutex);
     758}
     759
     760static void devmap_get_namespaces(ipc_callid_t iid, ipc_call_t *icall)
     761{
    576762        ipc_callid_t callid;
    577763        size_t size;
     
    584770        if ((size % sizeof(dev_desc_t)) != 0) {
    585771                ipc_answer_0(callid, EINVAL);
     772                ipc_answer_0(iid, EINVAL);
     773                return;
     774        }
     775       
     776        fibril_mutex_lock(&devices_list_mutex);
     777       
     778        size_t count = size / sizeof(dev_desc_t);
     779        if (count != list_count(&namespaces_list)) {
     780                ipc_answer_0(callid, EOVERFLOW);
     781                ipc_answer_0(iid, EOVERFLOW);
     782                return;
     783        }
     784       
     785        dev_desc_t *desc = (dev_desc_t *) malloc(size);
     786        if (desc == NULL) {
     787                ipc_answer_0(callid, ENOMEM);
     788                ipc_answer_0(iid, ENOMEM);
     789                return;
     790        }
     791       
     792        link_t *item = namespaces_list.next;
     793        size_t pos = 0;
     794        while (item != &namespaces_list) {
     795                devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
     796               
     797                desc[pos].handle = namespace->handle;
     798                str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, namespace->name);
     799                pos++;
     800               
     801                item = item->next;
     802        }
     803       
     804        ipcarg_t retval = async_data_read_finalize(callid, desc, size);
     805       
     806        free(desc);
     807        fibril_mutex_unlock(&devices_list_mutex);
     808       
     809        ipc_answer_0(iid, retval);
     810}
     811
     812static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall)
     813{
     814        /* FIXME: Use faster algorithm which can make better use
     815           of namespaces */
     816       
     817        ipc_callid_t callid;
     818        size_t size;
     819        if (!async_data_read_receive(&callid, &size)) {
     820                ipc_answer_0(callid, EREFUSED);
    586821                ipc_answer_0(iid, EREFUSED);
    587822                return;
    588823        }
    589824       
     825        if ((size % sizeof(dev_desc_t)) != 0) {
     826                ipc_answer_0(callid, EINVAL);
     827                ipc_answer_0(iid, EINVAL);
     828                return;
     829        }
     830       
     831        fibril_mutex_lock(&devices_list_mutex);
     832       
     833        devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
     834        if (namespace == NULL) {
     835                fibril_mutex_unlock(&devices_list_mutex);
     836                ipc_answer_0(callid, ENOENT);
     837                ipc_answer_0(iid, ENOENT);
     838                return;
     839        }
     840       
    590841        size_t count = size / sizeof(dev_desc_t);
     842        if (count != namespace->refcnt) {
     843                ipc_answer_0(callid, EOVERFLOW);
     844                ipc_answer_0(iid, EOVERFLOW);
     845                return;
     846        }
     847       
    591848        dev_desc_t *desc = (dev_desc_t *) malloc(size);
    592849        if (desc == NULL) {
     
    596853        }
    597854       
     855        link_t *item = devices_list.next;
    598856        size_t pos = 0;
    599         link_t *item = devices_list.next;
    600        
    601         while ((item != &devices_list) && (pos < count)) {
     857        while (item != &devices_list) {
    602858                devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
    603859               
    604                 desc[pos].handle = device->handle;
    605                 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name);
    606                 pos++;
     860                if (device->namespace == namespace) {
     861                        desc[pos].handle = device->handle;
     862                        str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name);
     863                        pos++;
     864                }
     865               
    607866                item = item->next;
    608867        }
    609868       
    610         ipcarg_t retval = async_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));
    611         if (retval != EOK) {
    612                 ipc_answer_0(iid, EREFUSED);
    613                 free(desc);
    614                 return;
    615         }
     869        ipcarg_t retval = async_data_read_finalize(callid, desc, size);
    616870       
    617871        free(desc);
    618        
    619872        fibril_mutex_unlock(&devices_list_mutex);
    620873       
    621         ipc_answer_1(iid, EOK, pos);
     874        ipc_answer_0(iid, retval);
    622875}
    623876
     
    642895        }
    643896       
    644         /* Create NULL device entry */
     897        char null[DEVMAP_NAME_MAXLEN];
     898        snprintf(null, DEVMAP_NAME_MAXLEN, "%u", i);
     899       
     900        char *dev_name = str_dup(null);
     901        if (dev_name == NULL) {
     902                fibril_mutex_unlock(&null_devices_mutex);
     903                ipc_answer_0(iid, ENOMEM);
     904                return;
     905        }
     906       
    645907        devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
    646908        if (device == NULL) {
     
    650912        }
    651913       
    652         char null[DEVMAP_NAME_MAXLEN];
    653         snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);
    654        
    655         device->name = str_dup(null);
    656         if (device->name == NULL) {
     914        fibril_mutex_lock(&devices_list_mutex);
     915       
     916        devmap_namespace_t *namespace = devmap_namespace_create("null");
     917        if (!namespace) {
     918                fibril_mutex_lock(&devices_list_mutex);
    657919                fibril_mutex_unlock(&null_devices_mutex);
    658                 free(device);
    659920                ipc_answer_0(iid, ENOMEM);
    660921                return;
     
    663924        list_initialize(&(device->devices));
    664925        list_initialize(&(device->driver_devices));
    665        
    666         fibril_mutex_lock(&devices_list_mutex);
    667926       
    668927        /* Get unique device handle */
    669928        device->handle = devmap_create_handle();
    670929        device->driver = NULL;
     930       
     931        devmap_namespace_addref(namespace, device);
     932        device->name = dev_name;
    671933       
    672934        /* Insert device into list of all devices
     
    692954        }
    693955       
     956        fibril_mutex_lock(&devices_list_mutex);
    694957        devmap_device_unregister_core(null_devices[i]);
     958        fibril_mutex_unlock(&devices_list_mutex);
     959       
    695960        null_devices[i] = NULL;
    696961       
     
    725990        ipc_answer_0(iid, EOK);
    726991       
    727         devmap_driver_t *driver = NULL;
    728         devmap_driver_register(&driver);
    729        
    730         if (NULL == driver)
     992        devmap_driver_t *driver = devmap_driver_register();
     993        if (driver == NULL)
    731994                return;
    732995       
     
    7551018                        break;
    7561019                case DEVMAP_DEVICE_GET_HANDLE:
    757                         devmap_get_handle(callid, &call);
    758                         break;
    759                 case DEVMAP_DEVICE_GET_NAME:
    760                         devmap_get_name(callid, &call);
     1020                        devmap_device_get_handle(callid, &call);
     1021                        break;
     1022                case DEVMAP_NAMESPACE_GET_HANDLE:
     1023                        devmap_namespace_get_handle(callid, &call);
    7611024                        break;
    7621025                default:
     
    7931056                        continue;
    7941057                case DEVMAP_DEVICE_GET_HANDLE:
    795                         devmap_get_handle(callid, &call);
    796                         break;
    797                 case DEVMAP_DEVICE_GET_NAME:
    798                         devmap_get_name(callid, &call);
    799                         break;
    800                 case DEVMAP_DEVICE_NULL_CREATE:
     1058                        devmap_device_get_handle(callid, &call);
     1059                        break;
     1060                case DEVMAP_NAMESPACE_GET_HANDLE:
     1061                        devmap_namespace_get_handle(callid, &call);
     1062                        break;
     1063                case DEVMAP_HANDLE_PROBE:
     1064                        devmap_handle_probe(callid, &call);
     1065                        break;
     1066                case DEVMAP_NULL_CREATE:
    8011067                        devmap_null_create(callid, &call);
    8021068                        break;
    803                 case DEVMAP_DEVICE_NULL_DESTROY:
     1069                case DEVMAP_NULL_DESTROY:
    8041070                        devmap_null_destroy(callid, &call);
    8051071                        break;
    806                 case DEVMAP_DEVICE_GET_COUNT:
    807                         devmap_get_count(callid, &call);
    808                         break;
    809                 case DEVMAP_DEVICE_GET_DEVICES:
     1072                case DEVMAP_GET_NAMESPACE_COUNT:
     1073                        devmap_get_namespace_count(callid, &call);
     1074                        break;
     1075                case DEVMAP_GET_DEVICE_COUNT:
     1076                        devmap_get_device_count(callid, &call);
     1077                        break;
     1078                case DEVMAP_GET_NAMESPACES:
     1079                        devmap_get_namespaces(callid, &call);
     1080                        break;
     1081                case DEVMAP_GET_DEVICES:
    8101082                        devmap_get_devices(callid, &call);
    8111083                        break;
  • uspace/srv/fs/devfs/devfs_ops.c

    rfc6dd18 r1313ee9  
    4444#include <fibril_synch.h>
    4545#include <adt/hash_table.h>
     46#include <ipc/devmap.h>
    4647#include <sys/stat.h>
     48#include <libfs.h>
     49#include <assert.h>
    4750#include "devfs.h"
    4851#include "devfs_ops.h"
    4952
    50 #define PLB_GET_CHAR(pos)  (devfs_reg.plb_ro[pos % PLB_SIZE])
     53typedef struct {
     54        devmap_handle_type_t type;
     55        dev_handle_t handle;
     56} devfs_node_t;
    5157
    5258/** Opened devices structure */
     
    9197};
    9298
     99static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type,
     100    dev_handle_t handle)
     101{
     102        devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t));
     103        if (node == NULL) {
     104                *rfn = NULL;
     105                return ENOMEM;
     106        }
     107       
     108        *rfn = (fs_node_t *) malloc(sizeof(fs_node_t));
     109        if (*rfn == NULL) {
     110                free(node);
     111                *rfn = NULL;
     112                return ENOMEM;
     113        }
     114       
     115        fs_node_initialize(*rfn);
     116        node->type = type;
     117        node->handle = handle;
     118       
     119        (*rfn)->data = node;
     120        return EOK;
     121}
     122
     123static int devfs_root_get(fs_node_t **rfn, dev_handle_t dev_handle)
     124{
     125        return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0);
     126}
     127
     128static int devfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
     129{
     130        devfs_node_t *node = (devfs_node_t *) pfn->data;
     131       
     132        if (node->handle == 0) {
     133                /* Root directory */
     134               
     135                dev_desc_t *devs;
     136                size_t count = devmap_get_namespaces(&devs);
     137               
     138                if (count > 0) {
     139                        size_t pos;
     140                        for (pos = 0; pos < count; pos++) {
     141                                /* Ignore root namespace */
     142                                if (str_cmp(devs[pos].name, "") == 0)
     143                                        continue;
     144                               
     145                                if (str_cmp(devs[pos].name, component) == 0) {
     146                                        free(devs);
     147                                        return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
     148                                }
     149                        }
     150                       
     151                        free(devs);
     152                }
     153               
     154                /* Search root namespace */
     155                dev_handle_t namespace;
     156                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     157                        count = devmap_get_devices(namespace, &devs);
     158                       
     159                        if (count > 0) {
     160                                size_t pos;
     161                                for (pos = 0; pos < count; pos++) {
     162                                        if (str_cmp(devs[pos].name, component) == 0) {
     163                                                free(devs);
     164                                                return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     165                                        }
     166                                }
     167                               
     168                                free(devs);
     169                        }
     170                }
     171               
     172                *rfn = NULL;
     173                return EOK;
     174        }
     175       
     176        if (node->type == DEV_HANDLE_NAMESPACE) {
     177                /* Namespace directory */
     178               
     179                dev_desc_t *devs;
     180                size_t count = devmap_get_devices(node->handle, &devs);
     181                if (count > 0) {
     182                        size_t pos;
     183                        for (pos = 0; pos < count; pos++) {
     184                                if (str_cmp(devs[pos].name, component) == 0) {
     185                                        free(devs);
     186                                        return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
     187                                }
     188                        }
     189                       
     190                        free(devs);
     191                }
     192               
     193                *rfn = NULL;
     194                return EOK;
     195        }
     196       
     197        *rfn = NULL;
     198        return EOK;
     199}
     200
     201static int devfs_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index)
     202{
     203        return devfs_node_get_internal(rfn, devmap_handle_probe(index), index);
     204}
     205
     206static int devfs_node_open(fs_node_t *fn)
     207{
     208        devfs_node_t *node = (devfs_node_t *) fn->data;
     209       
     210        if (node->handle == 0) {
     211                /* Root directory */
     212                return EOK;
     213        }
     214       
     215        devmap_handle_type_t type = devmap_handle_probe(node->handle);
     216       
     217        if (type == DEV_HANDLE_NAMESPACE) {
     218                /* Namespace directory */
     219                return EOK;
     220        }
     221       
     222        if (type == DEV_HANDLE_DEVICE) {
     223                /* Device node */
     224               
     225                unsigned long key[] = {
     226                        [DEVICES_KEY_HANDLE] = (unsigned long) node->handle
     227                };
     228               
     229                fibril_mutex_lock(&devices_mutex);
     230                link_t *lnk = hash_table_find(&devices, key);
     231                if (lnk == NULL) {
     232                        device_t *dev = (device_t *) malloc(sizeof(device_t));
     233                        if (dev == NULL) {
     234                                fibril_mutex_unlock(&devices_mutex);
     235                                return ENOMEM;
     236                        }
     237                       
     238                        int phone = devmap_device_connect(node->handle, 0);
     239                        if (phone < 0) {
     240                                fibril_mutex_unlock(&devices_mutex);
     241                                free(dev);
     242                                return ENOENT;
     243                        }
     244                       
     245                        dev->handle = node->handle;
     246                        dev->phone = phone;
     247                        dev->refcount = 1;
     248                       
     249                        hash_table_insert(&devices, key, &dev->link);
     250                } else {
     251                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
     252                        dev->refcount++;
     253                }
     254               
     255                fibril_mutex_unlock(&devices_mutex);
     256               
     257                return EOK;
     258        }
     259       
     260        return ENOENT;
     261}
     262
     263static int devfs_node_put(fs_node_t *fn)
     264{
     265        free(fn->data);
     266        free(fn);
     267        return EOK;
     268}
     269
     270static int devfs_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int lflag)
     271{
     272        assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
     273       
     274        *rfn = NULL;
     275        return ENOTSUP;
     276}
     277
     278static int devfs_destroy_node(fs_node_t *fn)
     279{
     280        return ENOTSUP;
     281}
     282
     283static int devfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
     284{
     285        return ENOTSUP;
     286}
     287
     288static int devfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
     289{
     290        return ENOTSUP;
     291}
     292
     293static int devfs_has_children(bool *has_children, fs_node_t *fn)
     294{
     295        devfs_node_t *node = (devfs_node_t *) fn->data;
     296       
     297        if (node->handle == 0) {
     298                size_t count = devmap_count_namespaces();
     299                if (count > 0) {
     300                        *has_children = true;
     301                        return EOK;
     302                }
     303               
     304                /* Root namespace */
     305                dev_handle_t namespace;
     306                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     307                        count = devmap_count_devices(namespace);
     308                        if (count > 0) {
     309                                *has_children = true;
     310                                return EOK;
     311                        }
     312                }
     313               
     314                *has_children = false;
     315                return EOK;
     316        }
     317       
     318        if (node->type == DEV_HANDLE_NAMESPACE) {
     319                size_t count = devmap_count_devices(node->handle);
     320                if (count > 0) {
     321                        *has_children = true;
     322                        return EOK;
     323                }
     324               
     325                *has_children = false;
     326                return EOK;
     327        }
     328       
     329        *has_children = false;
     330        return EOK;
     331}
     332
     333static fs_index_t devfs_index_get(fs_node_t *fn)
     334{
     335        devfs_node_t *node = (devfs_node_t *) fn->data;
     336        return node->handle;
     337}
     338
     339static size_t devfs_size_get(fs_node_t *fn)
     340{
     341        return 0;
     342}
     343
     344static unsigned int devfs_lnkcnt_get(fs_node_t *fn)
     345{
     346        devfs_node_t *node = (devfs_node_t *) fn->data;
     347       
     348        if (node->handle == 0)
     349                return 0;
     350       
     351        return 1;
     352}
     353
     354static char devfs_plb_get_char(unsigned pos)
     355{
     356        return devfs_reg.plb_ro[pos % PLB_SIZE];
     357}
     358
     359static bool devfs_is_directory(fs_node_t *fn)
     360{
     361        devfs_node_t *node = (devfs_node_t *) fn->data;
     362       
     363        return ((node->type == DEV_HANDLE_NONE) || (node->type == DEV_HANDLE_NAMESPACE));
     364}
     365
     366static bool devfs_is_file(fs_node_t *fn)
     367{
     368        devfs_node_t *node = (devfs_node_t *) fn->data;
     369       
     370        return (node->type == DEV_HANDLE_DEVICE);
     371}
     372
     373static dev_handle_t devfs_device_get(fs_node_t *fn)
     374{
     375        devfs_node_t *node = (devfs_node_t *) fn->data;
     376       
     377        if (node->type == DEV_HANDLE_DEVICE)
     378                return node->handle;
     379       
     380        return 0;
     381}
     382
     383/** libfs operations */
     384libfs_ops_t devfs_libfs_ops = {
     385        .root_get = devfs_root_get,
     386        .match = devfs_match,
     387        .node_get = devfs_node_get,
     388        .node_open = devfs_node_open,
     389        .node_put = devfs_node_put,
     390        .create = devfs_create_node,
     391        .destroy = devfs_destroy_node,
     392        .link = devfs_link_node,
     393        .unlink = devfs_unlink_node,
     394        .has_children = devfs_has_children,
     395        .index_get = devfs_index_get,
     396        .size_get = devfs_size_get,
     397        .lnkcnt_get = devfs_lnkcnt_get,
     398        .plb_get_char = devfs_plb_get_char,
     399        .is_directory = devfs_is_directory,
     400        .is_file = devfs_is_file,
     401        .device_get = devfs_device_get
     402};
     403
    93404bool devfs_init(void)
    94405{
     
    105416void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    106417{
     418        char *opts;
     419       
    107420        /* Accept the mount options */
    108         ipc_callid_t callid;
    109         size_t size;
    110         if (!async_data_write_receive(&callid, &size)) {
    111                 ipc_answer_0(callid, EINVAL);
    112                 ipc_answer_0(rid, EINVAL);
    113                 return;
    114         }
    115        
    116         char *opts = malloc(size + 1);
    117         if (!opts) {
    118                 ipc_answer_0(callid, ENOMEM);
    119                 ipc_answer_0(rid, ENOMEM);
    120                 return;
    121         }
    122        
    123         ipcarg_t retval = async_data_write_finalize(callid, opts, size);
     421        ipcarg_t retval = async_data_string_receive(&opts, 0);
    124422        if (retval != EOK) {
    125423                ipc_answer_0(rid, retval);
    126                 free(opts);
    127424                return;
    128425        }
    129426       
    130427        free(opts);
    131        
    132428        ipc_answer_3(rid, EOK, 0, 0, 0);
    133429}
     
    135431void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    136432{
    137         ipc_answer_0(rid, ENOTSUP);
     433        libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    138434}
    139435
    140436void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    141437{
    142         ipcarg_t first = IPC_GET_ARG1(*request);
    143         ipcarg_t last = IPC_GET_ARG2(*request);
    144         dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    145         ipcarg_t lflag = IPC_GET_ARG4(*request);
    146         fs_index_t index = IPC_GET_ARG5(*request);
    147        
    148         /* Hierarchy is flat, no altroot is supported */
    149         if (index != 0) {
    150                 ipc_answer_0(rid, ENOENT);
    151                 return;
    152         }
    153        
    154         if ((lflag & L_LINK) || (lflag & L_UNLINK)) {
    155                 ipc_answer_0(rid, ENOTSUP);
    156                 return;
    157         }
    158        
    159         /* Eat slash */
    160         if (PLB_GET_CHAR(first) == '/') {
    161                 first++;
    162                 first %= PLB_SIZE;
    163         }
    164        
    165         if (first >= last) {
    166                 /* Root entry */
    167                 if (!(lflag & L_FILE))
    168                         ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0);
    169                 else
    170                         ipc_answer_0(rid, ENOENT);
    171         } else {
    172                 if (!(lflag & L_DIRECTORY)) {
    173                         size_t len;
    174                         if (last >= first)
    175                                 len = last - first + 1;
    176                         else
    177                                 len = first + PLB_SIZE - last + 1;
     438        libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     439}
     440
     441void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
     442{
     443        libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     444}
     445
     446void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
     447{
     448        libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     449}
     450
     451void devfs_read(ipc_callid_t rid, ipc_call_t *request)
     452{
     453        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     454        off_t pos = (off_t) IPC_GET_ARG3(*request);
     455       
     456        if (index == 0) {
     457                ipc_callid_t callid;
     458                size_t size;
     459                if (!async_data_read_receive(&callid, &size)) {
     460                        ipc_answer_0(callid, EINVAL);
     461                        ipc_answer_0(rid, EINVAL);
     462                        return;
     463                }
     464               
     465                dev_desc_t *desc;
     466                size_t count = devmap_get_namespaces(&desc);
     467               
     468                /* Get rid of root namespace */
     469                size_t i;
     470                for (i = 0; i < count; i++) {
     471                        if (str_cmp(desc[i].name, "") == 0) {
     472                                if (pos >= i)
     473                                        pos++;
     474                               
     475                                break;
     476                        }
     477                }
     478               
     479                if (pos < count) {
     480                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     481                        free(desc);
     482                        ipc_answer_1(rid, EOK, 1);
     483                        return;
     484                }
     485               
     486                free(desc);
     487                pos -= count;
     488               
     489                /* Search root namespace */
     490                dev_handle_t namespace;
     491                if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {
     492                        count = devmap_get_devices(namespace, &desc);
    178493                       
    179                         char *name = (char *) malloc(len + 1);
    180                         if (name == NULL) {
    181                                 ipc_answer_0(rid, ENOMEM);
     494                        if (pos < count) {
     495                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     496                                free(desc);
     497                                ipc_answer_1(rid, EOK, 1);
    182498                                return;
    183499                        }
    184500                       
    185                         size_t i;
    186                         for (i = 0; i < len; i++)
    187                                 name[i] = PLB_GET_CHAR(first + i);
    188                        
    189                         name[len] = 0;
    190                        
    191                         dev_handle_t handle;
    192                         if (devmap_device_get_handle(name, &handle, 0) != EOK) {
    193                                 free(name);
    194                                 ipc_answer_0(rid, ENOENT);
    195                                 return;
    196                         }
    197                        
    198                         if (lflag & L_OPEN) {
    199                                 unsigned long key[] = {
    200                                         [DEVICES_KEY_HANDLE] = (unsigned long) handle
    201                                 };
    202                                
    203                                 fibril_mutex_lock(&devices_mutex);
    204                                 link_t *lnk = hash_table_find(&devices, key);
    205                                 if (lnk == NULL) {
    206                                         int phone = devmap_device_connect(handle, 0);
    207                                         if (phone < 0) {
    208                                                 fibril_mutex_unlock(&devices_mutex);
    209                                                 free(name);
    210                                                 ipc_answer_0(rid, ENOENT);
    211                                                 return;
    212                                         }
    213                                        
    214                                         device_t *dev = (device_t *) malloc(sizeof(device_t));
    215                                         if (dev == NULL) {
    216                                                 fibril_mutex_unlock(&devices_mutex);
    217                                                 free(name);
    218                                                 ipc_answer_0(rid, ENOMEM);
    219                                                 return;
    220                                         }
    221                                        
    222                                         dev->handle = handle;
    223                                         dev->phone = phone;
    224                                         dev->refcount = 1;
    225                                        
    226                                         hash_table_insert(&devices, key, &dev->link);
    227                                 } else {
    228                                         device_t *dev = hash_table_get_instance(lnk, device_t, link);
    229                                         dev->refcount++;
    230                                 }
    231                                 fibril_mutex_unlock(&devices_mutex);
    232                         }
    233                        
    234                         free(name);
    235                        
    236                         ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1);
    237                 } else
    238                         ipc_answer_0(rid, ENOENT);
    239         }
    240 }
    241 
    242 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    243 {
    244         dev_handle_t handle = IPC_GET_ARG2(*request);
    245        
    246         unsigned long key[] = {
    247                 [DEVICES_KEY_HANDLE] = (unsigned long) handle
    248         };
    249        
    250         fibril_mutex_lock(&devices_mutex);
    251         link_t *lnk = hash_table_find(&devices, key);
    252         if (lnk == NULL) {
    253                 int phone = devmap_device_connect(handle, 0);
    254                 if (phone < 0) {
    255                         fibril_mutex_unlock(&devices_mutex);
    256                         ipc_answer_0(rid, ENOENT);
    257                         return;
    258                 }
    259                
    260                 device_t *dev = (device_t *) malloc(sizeof(device_t));
    261                 if (dev == NULL) {
    262                         fibril_mutex_unlock(&devices_mutex);
    263                         ipc_answer_0(rid, ENOMEM);
    264                         return;
    265                 }
    266                
    267                 dev->handle = handle;
    268                 dev->phone = phone;
    269                 dev->refcount = 1;
    270                
    271                 hash_table_insert(&devices, key, &dev->link);
    272         } else {
    273                 device_t *dev = hash_table_get_instance(lnk, device_t, link);
    274                 dev->refcount++;
    275         }
    276         fibril_mutex_unlock(&devices_mutex);
    277        
    278         ipc_answer_3(rid, EOK, 0, 1, L_FILE);
    279 }
    280 
    281 void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
    282 {
    283         dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    284         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    285        
    286         ipc_callid_t callid;
    287         size_t size;
    288         if (!async_data_read_receive(&callid, &size) ||
    289             size != sizeof(struct stat)) {
    290                 ipc_answer_0(callid, EINVAL);
    291                 ipc_answer_0(rid, EINVAL);
    292                 return;
    293         }
    294 
    295         struct stat stat;
    296         memset(&stat, 0, sizeof(struct stat));
    297 
    298         stat.fs_handle = devfs_reg.fs_handle;
    299         stat.dev_handle = dev_handle;
    300         stat.index = index;
    301         stat.lnkcnt = 1;
    302         stat.is_file = (index != 0);
    303         stat.size = 0;
    304        
    305         if (index != 0) {
    306                 unsigned long key[] = {
    307                         [DEVICES_KEY_HANDLE] = (unsigned long) index
    308                 };
    309                
    310                 fibril_mutex_lock(&devices_mutex);
    311                 link_t *lnk = hash_table_find(&devices, key);
    312                 if (lnk != NULL)
    313                         stat.devfs_stat.device = (dev_handle_t)index;
    314                 fibril_mutex_unlock(&devices_mutex);
    315         }
    316 
    317         async_data_read_finalize(callid, &stat, sizeof(struct stat));
    318         ipc_answer_0(rid, EOK);
    319 }
    320 
    321 void devfs_read(ipc_callid_t rid, ipc_call_t *request)
    322 {
    323         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    324         off_t pos = (off_t) IPC_GET_ARG3(*request);
    325        
    326         if (index != 0) {
     501                        free(desc);
     502                }
     503               
     504                ipc_answer_0(callid, ENOENT);
     505                ipc_answer_1(rid, ENOENT, 0);
     506                return;
     507        }
     508       
     509        devmap_handle_type_t type = devmap_handle_probe(index);
     510       
     511        if (type == DEV_HANDLE_NAMESPACE) {
     512                /* Namespace directory */
     513                ipc_callid_t callid;
     514                size_t size;
     515                if (!async_data_read_receive(&callid, &size)) {
     516                        ipc_answer_0(callid, EINVAL);
     517                        ipc_answer_0(rid, EINVAL);
     518                        return;
     519                }
     520               
     521                dev_desc_t *desc;
     522                size_t count = devmap_get_devices(index, &desc);
     523               
     524                if (pos < count) {
     525                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
     526                        free(desc);
     527                        ipc_answer_1(rid, EOK, 1);
     528                        return;
     529                }
     530               
     531                free(desc);
     532                ipc_answer_0(callid, ENOENT);
     533                ipc_answer_1(rid, ENOENT, 0);
     534                return;
     535        }
     536       
     537        if (type == DEV_HANDLE_DEVICE) {
     538                /* Device node */
     539               
    327540                unsigned long key[] = {
    328541                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    364577                /* Driver reply is the final result of the whole operation */
    365578                ipc_answer_1(rid, rc, bytes);
    366         } else {
    367                 ipc_callid_t callid;
    368                 size_t size;
    369                 if (!async_data_read_receive(&callid, &size)) {
    370                         ipc_answer_0(callid, EINVAL);
    371                         ipc_answer_0(rid, EINVAL);
    372                         return;
    373                 }
    374                
    375                 size_t count = devmap_device_get_count();
    376                 dev_desc_t *desc = malloc(count * sizeof(dev_desc_t));
    377                 if (desc == NULL) {
    378                         ipc_answer_0(callid, ENOMEM);
    379                         ipc_answer_1(rid, ENOMEM, 0);
    380                         return;
    381                 }
    382                
    383                 size_t max = devmap_device_get_devices(count, desc);
    384                
    385                 if (pos < max) {
    386                         async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    387                 } else {
    388                         ipc_answer_0(callid, ENOENT);
    389                         ipc_answer_1(rid, ENOENT, 0);
    390                         return;
    391                 }
    392                
    393                 free(desc);
    394                
    395                 ipc_answer_1(rid, EOK, 1);
    396         }
     579                return;
     580        }
     581       
     582        ipc_answer_0(rid, ENOENT);
    397583}
    398584
     
    402588        off_t pos = (off_t) IPC_GET_ARG3(*request);
    403589       
    404         if (index != 0) {
     590        if (index == 0) {
     591                ipc_answer_0(rid, ENOTSUP);
     592                return;
     593        }
     594       
     595        devmap_handle_type_t type = devmap_handle_probe(index);
     596       
     597        if (type == DEV_HANDLE_NAMESPACE) {
     598                /* Namespace directory */
     599                ipc_answer_0(rid, ENOTSUP);
     600                return;
     601        }
     602       
     603        if (type == DEV_HANDLE_DEVICE) {
     604                /* Device node */
    405605                unsigned long key[] = {
    406606                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    443643                /* Driver reply is the final result of the whole operation */
    444644                ipc_answer_1(rid, rc, bytes);
    445         } else {
    446                 /* Read-only filesystem */
    447                 ipc_answer_0(rid, ENOTSUP);
    448         }
     645                return;
     646        }
     647       
     648        ipc_answer_0(rid, ENOENT);
    449649}
    450650
     
    458658        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    459659       
    460         if (index != 0) {
     660        if (index == 0) {
     661                ipc_answer_0(rid, EOK);
     662                return;
     663        }
     664       
     665        devmap_handle_type_t type = devmap_handle_probe(index);
     666       
     667        if (type == DEV_HANDLE_NAMESPACE) {
     668                /* Namespace directory */
     669                ipc_answer_0(rid, EOK);
     670                return;
     671        }
     672       
     673        if (type == DEV_HANDLE_DEVICE) {
    461674                unsigned long key[] = {
    462675                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    482695               
    483696                ipc_answer_0(rid, EOK);
    484         } else
    485                 ipc_answer_0(rid, ENOTSUP);
     697                return;
     698        }
     699       
     700        ipc_answer_0(rid, ENOENT);
    486701}
    487702
     
    490705        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    491706       
    492         if (index != 0) {
     707        if (index == 0) {
     708                ipc_answer_0(rid, EOK);
     709                return;
     710        }
     711       
     712        devmap_handle_type_t type = devmap_handle_probe(index);
     713       
     714        if (type == DEV_HANDLE_NAMESPACE) {
     715                /* Namespace directory */
     716                ipc_answer_0(rid, EOK);
     717                return;
     718        }
     719       
     720        if (type == DEV_HANDLE_DEVICE) {
    493721                unsigned long key[] = {
    494722                        [DEVICES_KEY_HANDLE] = (unsigned long) index
     
    518746                /* Driver reply is the final result of the whole operation */
    519747                ipc_answer_0(rid, rc);
    520         } else
    521                 ipc_answer_0(rid, ENOTSUP);
     748                return;
     749        }
     750       
     751        ipc_answer_0(rid, ENOENT);
    522752}
    523753
  • uspace/srv/fs/fat/fat_ops.c

    rfc6dd18 r1313ee9  
    7171static int fat_match(fs_node_t **, fs_node_t *, const char *);
    7272static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t);
     73static int fat_node_open(fs_node_t *);
    7374static int fat_node_put(fs_node_t *);
    7475static int fat_create_node(fs_node_t **, dev_handle_t, int);
     
    8384static bool fat_is_directory(fs_node_t *);
    8485static bool fat_is_file(fs_node_t *node);
     86static dev_handle_t fat_device_get(fs_node_t *node);
    8587
    8688/*
     
    407409}
    408410
     411int fat_node_open(fs_node_t *fn)
     412{
     413        /*
     414         * Opening a file is stateless, nothing
     415         * to be done here.
     416         */
     417        return EOK;
     418}
     419
    409420int fat_node_put(fs_node_t *fn)
    410421{
     
    867878}
    868879
     880dev_handle_t fat_device_get(fs_node_t *node)
     881{
     882        return 0;
     883}
     884
    869885/** libfs operations */
    870886libfs_ops_t fat_libfs_ops = {
     
    872888        .match = fat_match,
    873889        .node_get = fat_node_get,
     890        .node_open = fat_node_open,
    874891        .node_put = fat_node_put,
    875892        .create = fat_create_node,
     
    881898        .size_get = fat_size_get,
    882899        .lnkcnt_get = fat_lnkcnt_get,
    883         .plb_get_char = fat_plb_get_char,
     900        .plb_get_char = fat_plb_get_char,
    884901        .is_directory = fat_is_directory,
    885         .is_file = fat_is_file
     902        .is_file = fat_is_file,
     903        .device_get = fat_device_get
    886904};
    887905
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    rfc6dd18 r1313ee9  
    6969static int tmpfs_match(fs_node_t **, fs_node_t *, const char *);
    7070static int tmpfs_node_get(fs_node_t **, dev_handle_t, fs_index_t);
     71static int tmpfs_node_open(fs_node_t *);
    7172static int tmpfs_node_put(fs_node_t *);
    7273static int tmpfs_create_node(fs_node_t **, dev_handle_t, int);
     
    117118}
    118119
     120static dev_handle_t tmpfs_device_get(fs_node_t *fn)
     121{
     122        return 0;
     123}
     124
    119125/** libfs operations */
    120126libfs_ops_t tmpfs_libfs_ops = {
     
    122128        .match = tmpfs_match,
    123129        .node_get = tmpfs_node_get,
     130        .node_open = tmpfs_node_open,
    124131        .node_put = tmpfs_node_put,
    125132        .create = tmpfs_create_node,
     
    133140        .plb_get_char = tmpfs_plb_get_char,
    134141        .is_directory = tmpfs_is_directory,
    135         .is_file = tmpfs_is_file
     142        .is_file = tmpfs_is_file,
     143        .device_get = tmpfs_device_get
    136144};
    137145
     
    241249        }
    242250        return EOK;     
     251}
     252
     253int tmpfs_node_open(fs_node_t *fn)
     254{
     255        /* nothing to do */
     256        return EOK;
    243257}
    244258
Note: See TracChangeset for help on using the changeset viewer.