Changeset 921b84f in mainline for uspace/srv


Ignore:
Timestamp:
2011-08-19T17:36:25Z (14 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5fb32c5
Parents:
ea186c6 (diff), f00af83 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge libposix changes.

Location:
uspace/srv
Files:
13 edited

Legend:

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

    rea186c6 r921b84f  
    548548
    549549        fibril_mutex_lock(&driver->driver_mutex);
    550        
    551         async_exch_t *exch = async_exchange_begin(driver->sess);
    552         async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    553             DRIVER_DEVMAN, 0, 0);
    554         async_exchange_end(exch);
    555 
    556         if (!sess) {
    557                 fibril_mutex_unlock(&driver->driver_mutex);
    558                 return;
    559         }
    560550
    561551        /*
     
    583573                fibril_mutex_unlock(&driver->driver_mutex);
    584574
    585                 add_device(sess, driver, dev, tree);
     575                add_device(driver, dev, tree);
    586576
    587577                /*
     
    603593                link = driver->devices.head.next;
    604594        }
    605 
    606         async_hangup(sess);
    607595
    608596        /*
     
    718706 * @param node          The device's node in the device tree.
    719707 */
    720 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
    721     dev_tree_t *tree)
     708void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
    722709{
    723710        /*
     
    736723        }
    737724       
    738         async_exch_t *exch = async_exchange_begin(sess);
     725        async_exch_t *exch = async_exchange_begin(drv->sess);
    739726       
    740727        ipc_call_t answer;
     
    806793        fibril_mutex_unlock(&drv->driver_mutex);
    807794
    808         if (is_running) {
    809                 /* Notify the driver about the new device. */
    810                 async_exch_t *exch = async_exchange_begin(drv->sess);
    811                 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    812                     DRIVER_DEVMAN, 0, 0);
    813                 async_exchange_end(exch);
    814                
    815                 if (sess) {
    816                         add_device(sess, drv, dev, tree);
    817                         async_hangup(sess);
    818                 }
    819         }
     795        /* Notify the driver about the new device. */
     796        if (is_running)
     797                add_device(drv, dev, tree);
    820798       
    821799        return true;
     
    919897        return dev;
    920898}
     899
     900/** Get list of device functions. */
     901int dev_get_functions(dev_tree_t *tree, dev_node_t *dev,
     902    devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size)
     903{
     904        size_t act_cnt;
     905        size_t buf_cnt;
     906
     907        assert(fibril_rwlock_is_locked(&tree->rwlock));
     908
     909        buf_cnt = buf_size / sizeof(devman_handle_t);
     910
     911        act_cnt = list_count(&dev->functions);
     912        *act_size = act_cnt * sizeof(devman_handle_t);
     913
     914        if (buf_size % sizeof(devman_handle_t) != 0)
     915                return EINVAL;
     916
     917        size_t pos = 0;
     918        list_foreach(dev->functions, item) {
     919                fun_node_t *fun =
     920                    list_get_instance(item, fun_node_t, dev_functions);
     921
     922                if (pos < buf_cnt)
     923                        hdl_buf[pos] = fun->handle;
     924                pos++;
     925        }
     926
     927        return EOK;
     928}
     929
    921930
    922931/* Function nodes */
     
    11451154        char *rel_path = path;
    11461155        char *next_path_elem = NULL;
    1147         bool cont = true;
     1156        bool cont = (rel_path[1] != '\0');
    11481157       
    11491158        while (cont && fun != NULL) {
  • uspace/srv/devman/devman.h

    rea186c6 r921b84f  
    235235extern void add_driver(driver_list_t *, driver_t *);
    236236extern void attach_driver(dev_node_t *, driver_t *);
    237 extern void add_device(async_sess_t *, driver_t *, dev_node_t *, dev_tree_t *);
     237extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
    238238extern bool start_driver(driver_t *);
    239239
     
    253253extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle);
    254254extern dev_node_t *find_dev_function(dev_node_t *, const char *);
     255extern int dev_get_functions(dev_tree_t *tree, dev_node_t *, devman_handle_t *,
     256    size_t, size_t *);
    255257
    256258extern fun_node_t *create_fun_node(void);
  • uspace/srv/devman/main.c

    rea186c6 r921b84f  
    497497}
    498498
    499 /** Find device path by its handle. */
    500 static void devman_get_device_path_by_handle(ipc_callid_t iid,
    501     ipc_call_t *icall)
     499/** Get device name. */
     500static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall)
    502501{
    503502        devman_handle_t handle = IPC_GET_ARG1(*icall);
     
    523522        }
    524523
     524        size_t sent_length = str_size(fun->name);
     525        if (sent_length > data_len) {
     526                sent_length = data_len;
     527        }
     528
     529        async_data_read_finalize(data_callid, fun->name, sent_length);
     530        async_answer_0(iid, EOK);
     531
     532        free(buffer);
     533}
     534
     535
     536/** Get device path. */
     537static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall)
     538{
     539        devman_handle_t handle = IPC_GET_ARG1(*icall);
     540
     541        fun_node_t *fun = find_fun_node(&device_tree, handle);
     542        if (fun == NULL) {
     543                async_answer_0(iid, ENOMEM);
     544                return;
     545        }
     546
     547        ipc_callid_t data_callid;
     548        size_t data_len;
     549        if (!async_data_read_receive(&data_callid, &data_len)) {
     550                async_answer_0(iid, EINVAL);
     551                return;
     552        }
     553
     554        void *buffer = malloc(data_len);
     555        if (buffer == NULL) {
     556                async_answer_0(data_callid, ENOMEM);
     557                async_answer_0(iid, ENOMEM);
     558                return;
     559        }
     560
    525561        size_t sent_length = str_size(fun->pathname);
    526562        if (sent_length > data_len) {
     
    532568
    533569        free(buffer);
     570}
     571
     572static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall)
     573{
     574        ipc_callid_t callid;
     575        size_t size;
     576        size_t act_size;
     577        int rc;
     578       
     579        if (!async_data_read_receive(&callid, &size)) {
     580                async_answer_0(callid, EREFUSED);
     581                async_answer_0(iid, EREFUSED);
     582                return;
     583        }
     584       
     585        fibril_rwlock_read_lock(&device_tree.rwlock);
     586       
     587        dev_node_t *dev = find_dev_node_no_lock(&device_tree,
     588            IPC_GET_ARG1(*icall));
     589        if (dev == NULL) {
     590                fibril_rwlock_read_unlock(&device_tree.rwlock);
     591                async_answer_0(callid, ENOENT);
     592                async_answer_0(iid, ENOENT);
     593                return;
     594        }
     595       
     596        devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
     597        if (hdl_buf == NULL) {
     598                fibril_rwlock_read_unlock(&device_tree.rwlock);
     599                async_answer_0(callid, ENOMEM);
     600                async_answer_0(iid, ENOMEM);
     601                return;
     602        }
     603       
     604        rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
     605        if (rc != EOK) {
     606                fibril_rwlock_read_unlock(&device_tree.rwlock);
     607                async_answer_0(callid, rc);
     608                async_answer_0(iid, rc);
     609                return;
     610        }
     611       
     612        fibril_rwlock_read_unlock(&device_tree.rwlock);
     613       
     614        sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size);
     615        free(hdl_buf);
     616       
     617        async_answer_1(iid, retval, act_size);
     618}
     619
     620
     621/** Get handle for child device of a function. */
     622static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall)
     623{
     624        fun_node_t *fun;
     625       
     626        fibril_rwlock_read_lock(&device_tree.rwlock);
     627       
     628        fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
     629        if (fun == NULL) {
     630                fibril_rwlock_read_unlock(&device_tree.rwlock);
     631                async_answer_0(iid, ENOENT);
     632                return;
     633        }
     634       
     635        if (fun->child == NULL) {
     636                fibril_rwlock_read_unlock(&device_tree.rwlock);
     637                async_answer_0(iid, ENOENT);
     638                return;
     639        }
     640       
     641        async_answer_1(iid, EOK, fun->child->handle);
     642       
     643        fibril_rwlock_read_unlock(&device_tree.rwlock);
    534644}
    535645
     
    566676                        devman_function_get_handle(callid, &call);
    567677                        break;
    568                 case DEVMAN_DEVICE_GET_DEVICE_PATH:
    569                         devman_get_device_path_by_handle(callid, &call);
     678                case DEVMAN_DEV_GET_FUNCTIONS:
     679                        devman_dev_get_functions(callid, &call);
     680                        break;
     681                case DEVMAN_FUN_GET_CHILD:
     682                        devman_fun_get_child(callid, &call);
     683                        break;
     684                case DEVMAN_FUN_GET_NAME:
     685                        devman_fun_get_name(callid, &call);
     686                        break;
     687                case DEVMAN_FUN_GET_PATH:
     688                        devman_fun_get_path(callid, &call);
    570689                        break;
    571690                case DEVMAN_FUN_SID_TO_HANDLE:
  • uspace/srv/hid/input/port/adb_mouse.c

    rea186c6 r921b84f  
    4242#include <errno.h>
    4343#include <loc.h>
     44#include <stdio.h>
    4445
    4546static mouse_dev_t *mouse_dev;
  • uspace/srv/hw/irc/apic/apic.c

    rea186c6 r921b84f  
    4545#include <errno.h>
    4646#include <async.h>
     47#include <stdio.h>
    4748
    4849#define NAME  "apic"
  • uspace/srv/loader/main.c

    rea186c6 r921b84f  
    6161#include <elf/elf.h>
    6262#include <elf/elf_load.h>
     63#include <vfs/vfs.h>
    6364
    6465#ifdef CONFIG_RTLD
     
    8990
    9091/** Number of preset files */
    91 static int filc = 0;
    92 /** Preset files vector */
    93 static fdi_node_t **filv = NULL;
    94 /** Buffer holding all preset files */
    95 static fdi_node_t *fil_buf = NULL;
     92static unsigned int filc = 0;
    9693
    9794static elf_info_t prog_info;
     
    239236static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    240237{
    241         fdi_node_t *buf;
    242         size_t buf_size;
    243         int rc = async_data_write_accept((void **) &buf, false, 0, 0,
    244             sizeof(fdi_node_t), &buf_size);
    245        
    246         if (rc == EOK) {
    247                 int count = buf_size / sizeof(fdi_node_t);
    248                
    249                 /*
    250                  * Allocate new filv
    251                  */
    252                 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
    253                 if (_filv == NULL) {
    254                         free(buf);
    255                         async_answer_0(rid, ENOMEM);
    256                         return;
     238        size_t count = IPC_GET_ARG1(*request);
     239
     240        async_exch_t *vfs_exch = vfs_exchange_begin();
     241
     242        for (filc = 0; filc < count; filc++) {
     243                ipc_callid_t callid;
     244                int fd;
     245
     246                if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
     247                        async_answer_0(callid, EINVAL);
     248                        break;
    257249                }
    258                
    259                 /*
    260                  * Fill the new filv with argument pointers
    261                  */
    262                 int i;
    263                 for (i = 0; i < count; i++)
    264                         _filv[i] = &buf[i];
    265                
    266                 _filv[count] = NULL;
    267                
    268                 /*
    269                  * Copy temporary data to global variables
    270                  */
    271                 if (fil_buf != NULL)
    272                         free(fil_buf);
    273                
    274                 if (filv != NULL)
    275                         free(filv);
    276                
    277                 filc = count;
    278                 fil_buf = buf;
    279                 filv = _filv;
    280         }
    281        
     250                async_state_change_finalize(callid, vfs_exch);
     251                fd = fd_wait();
     252                assert(fd == (int) filc);
     253        }
     254
     255        vfs_exchange_end(vfs_exch);
     256
    282257        async_answer_0(rid, EOK);
    283258}
     
    308283       
    309284        pcb.filc = filc;
    310         pcb.filv = filv;
    311285       
    312286        if (prog_info.interp == NULL) {
  • uspace/srv/loc/loc.h

    rea186c6 r921b84f  
    3636#define LOC_H_
    3737
     38#include <ipc/loc.h>
    3839#include <async.h>
    3940#include <fibril_synch.h>
  • uspace/srv/vfs/vfs.c

    rea186c6 r921b84f  
    3636 */
    3737
     38#include <vfs/vfs.h>
    3839#include <ipc/services.h>
     40#include <abi/ipc/event.h>
     41#include <event.h>
    3942#include <ns.h>
    4043#include <async.h>
     
    4548#include <as.h>
    4649#include <atomic.h>
     50#include <macros.h>
    4751#include "vfs.h"
    4852
    4953#define NAME  "vfs"
     54
     55enum {
     56        VFS_TASK_STATE_CHANGE
     57};
    5058
    5159static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     
    8088                        vfs_open(callid, &call);
    8189                        break;
    82                 case VFS_IN_OPEN_NODE:
    83                         vfs_open_node(callid, &call);
    84                         break;
    8590                case VFS_IN_CLOSE:
    8691                        vfs_close(callid, &call);
     
    118123                case VFS_IN_DUP:
    119124                        vfs_dup(callid, &call);
     125                        break;
     126                case VFS_IN_WAIT_HANDLE:
     127                        vfs_wait_handle(callid, &call);
     128                        break;
    120129                default:
    121130                        async_answer_0(callid, ENOTSUP);
     
    128137         * connection fibril terminates.
    129138         */
     139}
     140
     141static void notification_received(ipc_callid_t callid, ipc_call_t *call)
     142{
     143        switch (IPC_GET_IMETHOD(*call)) {
     144        case VFS_TASK_STATE_CHANGE:
     145                if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
     146                        vfs_pass_handle(
     147                            (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
     148                            IPC_GET_ARG5(*call)), call->in_task_id,
     149                            (int) IPC_GET_ARG2(*call));
     150                break;
     151        default:
     152                break;
     153        }
    130154}
    131155
     
    170194
    171195        /*
     196         * Set notification handler and subscribe to notifications.
     197         */
     198        async_set_interrupt_received(notification_received);
     199        event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
     200
     201        /*
    172202         * Register at the naming service.
    173203         */
  • uspace/srv/vfs/vfs.h

    rea186c6 r921b84f  
    4141#include <bool.h>
    4242#include <ipc/vfs.h>
     43#include <task.h>
    4344
    4445#ifndef dprintf
     
    175176extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
    176177    vfs_pair_t *, ...);
    177 extern int vfs_open_node_internal(vfs_lookup_res_t *);
    178178
    179179extern bool vfs_nodes_init(void);
     
    189189extern void vfs_client_data_destroy(void *);
    190190
     191extern void vfs_pass_handle(task_id_t, task_id_t, int);
     192extern int vfs_wait_handle_internal(void);
     193
    191194extern vfs_file_t *vfs_file_get(int);
    192195extern void vfs_file_put(vfs_file_t *);
     
    197200extern void vfs_node_addref(vfs_node_t *);
    198201extern void vfs_node_delref(vfs_node_t *);
     202extern int vfs_open_node_remote(vfs_node_t *);
    199203
    200204extern void vfs_register(ipc_callid_t, ipc_call_t *);
     
    202206extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
    203207extern void vfs_open(ipc_callid_t, ipc_call_t *);
    204 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
    205208extern void vfs_sync(ipc_callid_t, ipc_call_t *);
    206209extern void vfs_dup(ipc_callid_t, ipc_call_t *);
     
    215218extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
    216219extern void vfs_rename(ipc_callid_t, ipc_call_t *);
     220extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *);
    217221
    218222#endif
  • uspace/srv/vfs/vfs_file.c

    rea186c6 r921b84f  
    4343#include <fibril.h>
    4444#include <fibril_synch.h>
     45#include <adt/list.h>
     46#include <task.h>
    4547#include "vfs.h"
    4648
     
    5052typedef struct {
    5153        fibril_mutex_t lock;
     54        fibril_condvar_t cv;
     55        list_t passed_handles;
    5256        vfs_file_t **files;
    5357} vfs_client_data_t;
    5458
     59typedef struct {
     60        link_t link;
     61        int handle;
     62} vfs_boxed_handle_t;
     63
     64static int _vfs_fd_free(vfs_client_data_t *, int);
     65
    5566/** Initialize the table of open files. */
    56 static bool vfs_files_init(void)
    57 {
    58         fibril_mutex_lock(&VFS_DATA->lock);
    59         if (!FILES) {
    60                 FILES = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
    61                 if (!FILES) {
    62                         fibril_mutex_unlock(&VFS_DATA->lock);
     67static bool vfs_files_init(vfs_client_data_t *vfs_data)
     68{
     69        fibril_mutex_lock(&vfs_data->lock);
     70        if (!vfs_data->files) {
     71                vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
     72                if (!vfs_data->files) {
     73                        fibril_mutex_unlock(&vfs_data->lock);
    6374                        return false;
    6475                }
    65                 memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
    66         }
    67         fibril_mutex_unlock(&VFS_DATA->lock);
     76                memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
     77        }
     78        fibril_mutex_unlock(&vfs_data->lock);
    6879        return true;
    6980}
    7081
    7182/** Cleanup the table of open files. */
    72 static void vfs_files_done(void)
     83static void vfs_files_done(vfs_client_data_t *vfs_data)
    7384{
    7485        int i;
    7586
    76         if (!FILES)
     87        if (!vfs_data->files)
    7788                return;
    7889
    7990        for (i = 0; i < MAX_OPEN_FILES; i++) {
    80                 if (FILES[i]) {
    81                         (void) vfs_fd_free(i);
    82                 }
    83         }
    84        
    85         free(FILES);
     91                if (vfs_data->files[i])
     92                        (void) _vfs_fd_free(vfs_data, i);
     93        }
     94       
     95        free(vfs_data->files);
     96
     97        while (!list_empty(&vfs_data->passed_handles)) {
     98                link_t *lnk;
     99                vfs_boxed_handle_t *bh;
     100               
     101                lnk = list_first(&vfs_data->passed_handles);
     102                list_remove(lnk);
     103
     104                bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
     105                free(bh);
     106        }
    86107}
    87108
     
    93114        if (vfs_data) {
    94115                fibril_mutex_initialize(&vfs_data->lock);
     116                fibril_condvar_initialize(&vfs_data->cv);
     117                list_initialize(&vfs_data->passed_handles);
    95118                vfs_data->files = NULL;
    96119        }
     
    103126        vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
    104127
    105         vfs_files_done();
     128        vfs_files_done(vfs_data);
    106129        free(vfs_data);
    107130}
     
    131154 *                      incremented.
    132155 */
    133 static void vfs_file_addref(vfs_file_t *file)
    134 {
    135         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     156static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file)
     157{
     158        assert(fibril_mutex_is_locked(&vfs_data->lock));
    136159
    137160        file->refcnt++;
     
    143166 *                      decremented.
    144167 */
    145 static int vfs_file_delref(vfs_file_t *file)
     168static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file)
    146169{
    147170        int rc = EOK;
    148171
    149         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     172        assert(fibril_mutex_is_locked(&vfs_data->lock));
    150173
    151174        if (file->refcnt-- == 1) {
     
    162185}
    163186
    164 
    165 /** Allocate a file descriptor.
    166  *
    167  * @param desc If true, look for an available file descriptor
    168  *             in a descending order.
    169  *
    170  * @return First available file descriptor or a negative error
    171  *         code.
    172  */
    173 int vfs_fd_alloc(bool desc)
    174 {
    175         if (!vfs_files_init())
     187static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
     188{
     189        if (!vfs_files_init(vfs_data))
    176190                return ENOMEM;
    177191       
     
    182196                i = 0;
    183197       
    184         fibril_mutex_lock(&VFS_DATA->lock);
     198        fibril_mutex_lock(&vfs_data->lock);
    185199        while (true) {
    186                 if (!FILES[i]) {
    187                         FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
    188                         if (!FILES[i]) {
    189                                 fibril_mutex_unlock(&VFS_DATA->lock);
     200                if (!vfs_data->files[i]) {
     201                        vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
     202                        if (!vfs_data->files[i]) {
     203                                fibril_mutex_unlock(&vfs_data->lock);
    190204                                return ENOMEM;
    191205                        }
    192206                       
    193                         memset(FILES[i], 0, sizeof(vfs_file_t));
    194                         fibril_mutex_initialize(&FILES[i]->lock);
    195                         vfs_file_addref(FILES[i]);
    196                         fibril_mutex_unlock(&VFS_DATA->lock);
     207                        memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
     208                        fibril_mutex_initialize(&vfs_data->files[i]->lock);
     209                        vfs_file_addref(vfs_data, vfs_data->files[i]);
     210                        fibril_mutex_unlock(&vfs_data->lock);
    197211                        return (int) i;
    198212                }
     
    210224                }
    211225        }
    212         fibril_mutex_unlock(&VFS_DATA->lock);
     226        fibril_mutex_unlock(&vfs_data->lock);
    213227       
    214228        return EMFILE;
     229}
     230
     231/** Allocate a file descriptor.
     232 *
     233 * @param desc If true, look for an available file descriptor
     234 *             in a descending order.
     235 *
     236 * @return First available file descriptor or a negative error
     237 *         code.
     238 */
     239int vfs_fd_alloc(bool desc)
     240{
     241        return _vfs_fd_alloc(VFS_DATA, desc);
     242}
     243
     244static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)
     245{
     246        int rc;
     247
     248        if (!vfs_files_init(vfs_data))
     249                return ENOMEM;
     250
     251        fibril_mutex_lock(&vfs_data->lock);     
     252        if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {
     253                fibril_mutex_unlock(&vfs_data->lock);
     254                return EBADF;
     255        }
     256       
     257        rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);
     258        vfs_data->files[fd] = NULL;
     259        fibril_mutex_unlock(&vfs_data->lock);
     260       
     261        return rc;
    215262}
    216263
     
    224271int vfs_fd_free(int fd)
    225272{
    226         int rc;
    227 
    228         if (!vfs_files_init())
    229                 return ENOMEM;
    230 
    231         fibril_mutex_lock(&VFS_DATA->lock);     
    232         if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) {
    233                 fibril_mutex_unlock(&VFS_DATA->lock);
    234                 return EBADF;
    235         }
    236        
    237         rc = vfs_file_delref(FILES[fd]);
    238         FILES[fd] = NULL;
    239         fibril_mutex_unlock(&VFS_DATA->lock);
    240        
    241         return rc;
     273        return _vfs_fd_free(VFS_DATA, fd);
    242274}
    243275
     
    253285int vfs_fd_assign(vfs_file_t *file, int fd)
    254286{
    255         if (!vfs_files_init())
     287        if (!vfs_files_init(VFS_DATA))
    256288                return ENOMEM;
    257289
     
    263295       
    264296        FILES[fd] = file;
    265         vfs_file_addref(FILES[fd]);
     297        vfs_file_addref(VFS_DATA, FILES[fd]);
    266298        fibril_mutex_unlock(&VFS_DATA->lock);
    267299       
     
    269301}
    270302
    271 /** Find VFS file structure for a given file descriptor.
    272  *
    273  * @param fd            File descriptor.
    274  *
    275  * @return              VFS file structure corresponding to fd.
    276  */
    277 vfs_file_t *vfs_file_get(int fd)
    278 {
    279         if (!vfs_files_init())
     303static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
     304{
     305        if (!vfs_files_init(vfs_data))
    280306                return NULL;
    281307       
    282         fibril_mutex_lock(&VFS_DATA->lock);
     308        fibril_mutex_lock(&vfs_data->lock);
    283309        if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
    284                 vfs_file_t *file = FILES[fd];
     310                vfs_file_t *file = vfs_data->files[fd];
    285311                if (file != NULL) {
    286                         vfs_file_addref(file);
    287                         fibril_mutex_unlock(&VFS_DATA->lock);
     312                        vfs_file_addref(vfs_data, file);
     313                        fibril_mutex_unlock(&vfs_data->lock);
    288314                        return file;
    289315                }
    290316        }
    291         fibril_mutex_unlock(&VFS_DATA->lock);
     317        fibril_mutex_unlock(&vfs_data->lock);
    292318       
    293319        return NULL;
    294320}
    295321
     322/** Find VFS file structure for a given file descriptor.
     323 *
     324 * @param fd            File descriptor.
     325 *
     326 * @return              VFS file structure corresponding to fd.
     327 */
     328vfs_file_t *vfs_file_get(int fd)
     329{
     330        return _vfs_file_get(VFS_DATA, fd);
     331}
     332
     333static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
     334{
     335        fibril_mutex_lock(&vfs_data->lock);
     336        vfs_file_delref(vfs_data, file);
     337        fibril_mutex_unlock(&vfs_data->lock);
     338}
     339
    296340/** Stop using a file structure.
    297341 *
     
    300344void vfs_file_put(vfs_file_t *file)
    301345{
    302         fibril_mutex_lock(&VFS_DATA->lock);
    303         vfs_file_delref(file);
    304         fibril_mutex_unlock(&VFS_DATA->lock);
     346        _vfs_file_put(VFS_DATA, file);
     347}
     348
     349void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
     350{
     351        vfs_client_data_t *donor_data = NULL;
     352        vfs_client_data_t *acceptor_data = NULL;
     353        vfs_file_t *donor_file = NULL;
     354        vfs_file_t *acceptor_file = NULL;
     355        vfs_boxed_handle_t *bh;
     356        int acceptor_fd;
     357
     358        acceptor_data = async_get_client_data_by_id(acceptor_id);
     359        if (!acceptor_data)
     360                return;
     361
     362        bh = malloc(sizeof(vfs_boxed_handle_t));
     363        assert(bh);
     364
     365        link_initialize(&bh->link);
     366        bh->handle = -1;
     367
     368        donor_data = async_get_client_data_by_id(donor_id);
     369        if (!donor_data)
     370                goto out;
     371
     372        donor_file = _vfs_file_get(donor_data, donor_fd);
     373        if (!donor_file)
     374                goto out;
     375
     376        acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
     377        if (acceptor_fd < 0)
     378                goto out;
     379
     380        bh->handle = acceptor_fd;
     381
     382        /*
     383         * Add a new reference to the underlying VFS node.
     384         */
     385        vfs_node_addref(donor_file->node);
     386        (void) vfs_open_node_remote(donor_file->node);
     387
     388        acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
     389        assert(acceptor_file);
     390
     391        /*
     392         * Inherit attributes from the donor.
     393         */
     394        acceptor_file->node = donor_file->node;
     395        acceptor_file->append = donor_file->append;
     396        acceptor_file->pos = donor_file->pos;
     397
     398out:
     399        fibril_mutex_lock(&acceptor_data->lock);
     400        list_append(&bh->link, &acceptor_data->passed_handles);
     401        fibril_condvar_broadcast(&acceptor_data->cv);
     402        fibril_mutex_unlock(&acceptor_data->lock);
     403
     404        if (donor_data)
     405                async_put_client_data_by_id(donor_id);
     406        if (acceptor_data)
     407                async_put_client_data_by_id(acceptor_id);
     408        if (donor_file)
     409                _vfs_file_put(donor_data, donor_file);
     410        if (acceptor_file)
     411                _vfs_file_put(acceptor_data, acceptor_file);
     412
     413}
     414
     415int vfs_wait_handle_internal(void)
     416{
     417        vfs_client_data_t *vfs_data = VFS_DATA;
     418        int fd;
     419       
     420        fibril_mutex_lock(&vfs_data->lock);
     421        while (list_empty(&vfs_data->passed_handles))
     422                fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock);
     423        link_t *lnk = list_first(&vfs_data->passed_handles);
     424        list_remove(lnk);
     425        fibril_mutex_unlock(&vfs_data->lock);
     426
     427        vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
     428        fd = bh->handle;
     429        free(bh);
     430
     431        return fd;
    305432}
    306433
  • uspace/srv/vfs/vfs_lookup.c

    rea186c6 r921b84f  
    201201}
    202202
    203 /** Perform a node open operation.
    204  *
    205  * @return EOK on success or an error code from errno.h.
    206  *
    207  */
    208 int vfs_open_node_internal(vfs_lookup_res_t *result)
    209 {
    210         async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
    211        
    212         ipc_call_t answer;
    213         aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
    214             (sysarg_t) result->triplet.service_id,
    215             (sysarg_t) result->triplet.index, &answer);
    216        
    217         sysarg_t rc;
    218         async_wait_for(req, &rc);
    219         vfs_exchange_release(exch);
    220        
    221         if (rc == EOK) {
    222                 result->size =
    223                     MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));
    224                 result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);
    225                 if (IPC_GET_ARG4(answer) & L_FILE)
    226                         result->type = VFS_NODE_FILE;
    227                 else if (IPC_GET_ARG4(answer) & L_DIRECTORY)
    228                         result->type = VFS_NODE_DIRECTORY;
    229                 else
    230                         result->type = VFS_NODE_UNKNOWN;
    231         }
    232        
    233         return rc;
    234 }
    235 
    236203/**
    237204 * @}
  • uspace/srv/vfs/vfs_node.c

    rea186c6 r921b84f  
    293293}
    294294
     295
     296/** Perform a remote node open operation.
     297 *
     298 * @return EOK on success or an error code from errno.h.
     299 *
     300 */
     301int vfs_open_node_remote(vfs_node_t *node)
     302{
     303        async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     304       
     305        ipc_call_t answer;
     306        aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
     307            (sysarg_t) node->service_id, (sysarg_t) node->index, &answer);
     308       
     309        vfs_exchange_release(exch);
     310
     311        sysarg_t rc;
     312        async_wait_for(req, &rc);
     313       
     314        return rc;
     315}
     316
    295317/**
    296318 * @}
  • uspace/srv/vfs/vfs_ops.c

    rea186c6 r921b84f  
    618618}
    619619
    620 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    621 {
    622         // FIXME: check for sanity of the supplied fs, dev and index
    623        
    624         /*
    625          * The interface is open_node(fs, dev, index, oflag).
    626          */
    627         vfs_lookup_res_t lr;
    628        
    629         lr.triplet.fs_handle = IPC_GET_ARG1(*request);
    630         lr.triplet.service_id = IPC_GET_ARG2(*request);
    631         lr.triplet.index = IPC_GET_ARG3(*request);
    632         int oflag = IPC_GET_ARG4(*request);
    633        
    634         fibril_rwlock_read_lock(&namespace_rwlock);
    635        
    636         int rc = vfs_open_node_internal(&lr);
    637         if (rc != EOK) {
    638                 fibril_rwlock_read_unlock(&namespace_rwlock);
    639                 async_answer_0(rid, rc);
    640                 return;
    641         }
    642        
    643         vfs_node_t *node = vfs_node_get(&lr);
    644         fibril_rwlock_read_unlock(&namespace_rwlock);
    645        
    646         /* Truncate the file if requested and if necessary. */
    647         if (oflag & O_TRUNC) {
    648                 fibril_rwlock_write_lock(&node->contents_rwlock);
    649                 if (node->size) {
    650                         rc = vfs_truncate_internal(node->fs_handle,
    651                             node->service_id, node->index, 0);
    652                         if (rc) {
    653                                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    654                                 vfs_node_put(node);
    655                                 async_answer_0(rid, rc);
    656                                 return;
    657                         }
    658                         node->size = 0;
    659                 }
    660                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    661         }
    662        
    663         /*
    664          * Get ourselves a file descriptor and the corresponding vfs_file_t
    665          * structure.
    666          */
    667         int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
    668         if (fd < 0) {
    669                 vfs_node_put(node);
    670                 async_answer_0(rid, fd);
    671                 return;
    672         }
    673         vfs_file_t *file = vfs_file_get(fd);
    674         file->node = node;
    675         if (oflag & O_APPEND)
    676                 file->append = true;
    677        
    678         /*
    679          * The following increase in reference count is for the fact that the
    680          * file is being opened and that a file structure is pointing to it.
    681          * It is necessary so that the file will not disappear when
    682          * vfs_node_put() is called. The reference will be dropped by the
    683          * respective VFS_IN_CLOSE.
    684          */
    685         vfs_node_addref(node);
    686         vfs_node_put(node);
    687         vfs_file_put(file);
    688        
    689         /* Success! Return the new file descriptor to the client. */
    690         async_answer_1(rid, EOK, fd);
    691 }
    692 
    693620void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
    694621{
     
    13491276}
    13501277
     1278void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
     1279{
     1280        int fd = vfs_wait_handle_internal();
     1281        async_answer_1(rid, EOK, fd);
     1282}
     1283
    13511284/**
    13521285 * @}
Note: See TracChangeset for help on using the changeset viewer.