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

Changeset 2bc13887 in mainline


Ignore:
Timestamp:
2011-08-17T15:07:20Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
2c4aa39
Parents:
455f190
Message:

Add vfs_pass_handle().

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/vfs/vfs.h

    r455f190 r2bc13887  
    4141#include <stdio.h>
    4242
     43enum vfs_change_state_type {
     44        VFS_PASS_HANDLE
     45};
     46
    4347/** Libc version of the VFS triplet.
    4448 *
  • uspace/srv/vfs/vfs.c

    r455f190 r2bc13887  
    3737
    3838#include <ipc/services.h>
     39#include <abi/ipc/event.h>
     40#include <event.h>
    3941#include <ns.h>
    4042#include <async.h>
     
    130132}
    131133
     134enum {
     135        VFS_TASK_STATE_CHANGE
     136};
     137
     138static void notification_received(ipc_callid_t callid, ipc_call_t *call)
     139{
     140        switch (IPC_GET_IMETHOD(*call)) {
     141        case VFS_TASK_STATE_CHANGE:
     142                if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
     143                        vfs_pass_handle(IPC_GET_ARG4(*call),
     144                            IPC_GET_ARG5(*call), (int) IPC_GET_ARG2(*call));
     145                break;
     146        default:
     147                break;
     148        }
     149}
     150
    132151int main(int argc, char **argv)
    133152{
     
    170189
    171190        /*
     191         * Set notification handler and subscribe to notifications.
     192         */
     193        async_set_interrupt_received(notification_received);
     194        event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
     195
     196        /*
    172197         * Register at the naming service.
    173198         */
  • uspace/srv/vfs/vfs.h

    r455f190 r2bc13887  
    188188extern void *vfs_client_data_create(void);
    189189extern void vfs_client_data_destroy(void *);
     190
     191extern void vfs_pass_handle(sysarg_t, sysarg_t, int);
    190192
    191193extern vfs_file_t *vfs_file_get(int);
  • uspace/srv/vfs/vfs_file.c

    r455f190 r2bc13887  
    5353} vfs_client_data_t;
    5454
     55static int _vfs_fd_free(vfs_client_data_t *, int);
     56
    5557/** 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);
     58static bool vfs_files_init(vfs_client_data_t *vfs_data)
     59{
     60        fibril_mutex_lock(&vfs_data->lock);
     61        if (!vfs_data->files) {
     62                vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
     63                if (!vfs_data->files) {
     64                        fibril_mutex_unlock(&vfs_data->lock);
    6365                        return false;
    6466                }
    65                 memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
    66         }
    67         fibril_mutex_unlock(&VFS_DATA->lock);
     67                memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
     68        }
     69        fibril_mutex_unlock(&vfs_data->lock);
    6870        return true;
    6971}
    7072
    7173/** Cleanup the table of open files. */
    72 static void vfs_files_done(void)
     74static void vfs_files_done(vfs_client_data_t *vfs_data)
    7375{
    7476        int i;
    7577
    76         if (!FILES)
     78        if (!vfs_data->files)
    7779                return;
    7880
    7981        for (i = 0; i < MAX_OPEN_FILES; i++) {
    80                 if (FILES[i]) {
    81                         (void) vfs_fd_free(i);
    82                 }
    83         }
    84        
    85         free(FILES);
     82                if (vfs_data->files[i])
     83                        (void) _vfs_fd_free(vfs_data, i);
     84        }
     85       
     86        free(vfs_data->files);
    8687}
    8788
     
    103104        vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
    104105
    105         vfs_files_done();
     106        vfs_files_done(vfs_data);
    106107        free(vfs_data);
    107108}
     
    131132 *                      incremented.
    132133 */
    133 static void vfs_file_addref(vfs_file_t *file)
    134 {
    135         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     134static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file)
     135{
     136        assert(fibril_mutex_is_locked(&vfs_data->lock));
    136137
    137138        file->refcnt++;
     
    143144 *                      decremented.
    144145 */
    145 static int vfs_file_delref(vfs_file_t *file)
     146static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file)
    146147{
    147148        int rc = EOK;
    148149
    149         assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     150        assert(fibril_mutex_is_locked(&vfs_data->lock));
    150151
    151152        if (file->refcnt-- == 1) {
     
    162163}
    163164
    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())
     165static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
     166{
     167        if (!vfs_files_init(vfs_data))
    176168                return ENOMEM;
    177169       
     
    182174                i = 0;
    183175       
    184         fibril_mutex_lock(&VFS_DATA->lock);
     176        fibril_mutex_lock(&vfs_data->lock);
    185177        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);
     178                if (!vfs_data->files[i]) {
     179                        vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
     180                        if (!vfs_data->files[i]) {
     181                                fibril_mutex_unlock(&vfs_data->lock);
    190182                                return ENOMEM;
    191183                        }
    192184                       
    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);
     185                        memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
     186                        fibril_mutex_initialize(&vfs_data->files[i]->lock);
     187                        vfs_file_addref(vfs_data, vfs_data->files[i]);
     188                        fibril_mutex_unlock(&vfs_data->lock);
    197189                        return (int) i;
    198190                }
     
    210202                }
    211203        }
    212         fibril_mutex_unlock(&VFS_DATA->lock);
     204        fibril_mutex_unlock(&vfs_data->lock);
    213205       
    214206        return EMFILE;
     207}
     208
     209/** Allocate a file descriptor.
     210 *
     211 * @param desc If true, look for an available file descriptor
     212 *             in a descending order.
     213 *
     214 * @return First available file descriptor or a negative error
     215 *         code.
     216 */
     217int vfs_fd_alloc(bool desc)
     218{
     219        return _vfs_fd_alloc(VFS_DATA, desc);
     220}
     221
     222static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)
     223{
     224        int rc;
     225
     226        if (!vfs_files_init(vfs_data))
     227                return ENOMEM;
     228
     229        fibril_mutex_lock(&vfs_data->lock);     
     230        if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {
     231                fibril_mutex_unlock(&vfs_data->lock);
     232                return EBADF;
     233        }
     234       
     235        rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);
     236        vfs_data->files[fd] = NULL;
     237        fibril_mutex_unlock(&vfs_data->lock);
     238       
     239        return rc;
    215240}
    216241
     
    224249int vfs_fd_free(int fd)
    225250{
    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;
     251        return _vfs_fd_free(VFS_DATA, fd);
    242252}
    243253
     
    253263int vfs_fd_assign(vfs_file_t *file, int fd)
    254264{
    255         if (!vfs_files_init())
     265        if (!vfs_files_init(VFS_DATA))
    256266                return ENOMEM;
    257267
     
    263273       
    264274        FILES[fd] = file;
    265         vfs_file_addref(FILES[fd]);
     275        vfs_file_addref(VFS_DATA, FILES[fd]);
    266276        fibril_mutex_unlock(&VFS_DATA->lock);
    267277       
     
    269279}
    270280
    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())
     281static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
     282{
     283        if (!vfs_files_init(vfs_data))
    280284                return NULL;
    281285       
    282         fibril_mutex_lock(&VFS_DATA->lock);
     286        fibril_mutex_lock(&vfs_data->lock);
    283287        if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
    284                 vfs_file_t *file = FILES[fd];
     288                vfs_file_t *file = vfs_data->files[fd];
    285289                if (file != NULL) {
    286                         vfs_file_addref(file);
    287                         fibril_mutex_unlock(&VFS_DATA->lock);
     290                        vfs_file_addref(vfs_data, file);
     291                        fibril_mutex_unlock(&vfs_data->lock);
    288292                        return file;
    289293                }
    290294        }
    291         fibril_mutex_unlock(&VFS_DATA->lock);
     295        fibril_mutex_unlock(&vfs_data->lock);
    292296       
    293297        return NULL;
    294298}
    295299
     300/** Find VFS file structure for a given file descriptor.
     301 *
     302 * @param fd            File descriptor.
     303 *
     304 * @return              VFS file structure corresponding to fd.
     305 */
     306vfs_file_t *vfs_file_get(int fd)
     307{
     308        return _vfs_file_get(VFS_DATA, fd);
     309}
     310
     311static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
     312{
     313        fibril_mutex_lock(&vfs_data->lock);
     314        vfs_file_delref(vfs_data, file);
     315        fibril_mutex_unlock(&vfs_data->lock);
     316}
     317
    296318/** Stop using a file structure.
    297319 *
     
    300322void vfs_file_put(vfs_file_t *file)
    301323{
    302         fibril_mutex_lock(&VFS_DATA->lock);
    303         vfs_file_delref(file);
    304         fibril_mutex_unlock(&VFS_DATA->lock);
     324        _vfs_file_put(VFS_DATA, file);
     325}
     326
     327void vfs_pass_handle(sysarg_t donor_hash, sysarg_t acceptor_hash, int donor_fd)
     328{
     329        vfs_client_data_t *donor_data = NULL;
     330        vfs_client_data_t *acceptor_data = NULL;
     331        vfs_file_t *donor_file = NULL;
     332        vfs_file_t *acceptor_file = NULL;
     333        int acceptor_fd;
     334
     335        donor_data = async_get_client_data_by_hash(donor_hash);
     336        if (!donor_data)
     337                return;
     338        acceptor_data = async_get_client_data_by_hash(acceptor_hash);
     339        if (!acceptor_data)
     340                goto out;
     341
     342        donor_file = _vfs_file_get(donor_data, donor_fd);
     343        if (!donor_file)
     344                goto out;
     345
     346        acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
     347        if (acceptor_fd < 0)
     348                goto out;
     349
     350        /*
     351         * Add a new reference to the underlying VFS node.
     352         */
     353        vfs_node_addref(donor_file->node);
     354
     355        acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
     356        assert(acceptor_file);
     357
     358        /*
     359         * Inherit attributes from the donor.
     360         */
     361        acceptor_file->node = donor_file->node;
     362        acceptor_file->append = donor_file->append;
     363        acceptor_file->pos = donor_file->pos;
     364
     365out:
     366        if (donor_data)
     367                async_put_client_data_by_hash(donor_hash);
     368        if (acceptor_data)
     369                async_put_client_data_by_hash(acceptor_hash);
     370        if (donor_file)
     371                _vfs_file_put(donor_data, donor_file);
     372        if (acceptor_file)
     373                _vfs_file_put(acceptor_data, acceptor_file);
    305374}
    306375
Note: See TracChangeset for help on using the changeset viewer.