Ignore:
File:
1 edited

Legend:

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

    r3e6a98c5 rfcab7ef  
    4545#include <adt/list.h>
    4646#include <task.h>
     47#include <vfs/vfs.h>
    4748#include "vfs.h"
    4849
     
    5960typedef struct {
    6061        link_t link;
    61         int handle;
     62        vfs_node_t *node;
     63        int permissions;
    6264} vfs_boxed_handle_t;
    6365
     
    177179                 * endpoint FS and drop our reference to the underlying VFS node.
    178180                 */
    179                 rc = vfs_file_close_remote(file);
    180                 vfs_node_delref(file->node);
     181               
     182                if (file->node != NULL) {
     183                        if (file->open_read || file->open_write) {
     184                                rc = vfs_file_close_remote(file);
     185                        }
     186                        vfs_node_delref(file->node);
     187                }
    181188                free(file);
    182189        }
     
    185192}
    186193
    187 static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
     194static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, vfs_file_t **file, bool desc)
    188195{
    189196        if (!vfs_files_init(vfs_data))
     
    205212                        }
    206213                       
     214                       
    207215                        memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
    208                         fibril_mutex_initialize(&vfs_data->files[i]->lock);
     216                       
     217                        fibril_mutex_initialize(&vfs_data->files[i]->_lock);
     218                        fibril_mutex_lock(&vfs_data->files[i]->_lock);
    209219                        vfs_file_addref(vfs_data, vfs_data->files[i]);
     220                       
     221                        *file = vfs_data->files[i];
     222                        vfs_file_addref(vfs_data, *file);
     223                       
    210224                        fibril_mutex_unlock(&vfs_data->lock);
    211225                        return (int) i;
     
    231245/** Allocate a file descriptor.
    232246 *
     247 * @param file Is set to point to the newly created file structure. Must be put afterwards.
    233248 * @param desc If true, look for an available file descriptor
    234249 *             in a descending order.
     
    237252 *         code.
    238253 */
    239 int vfs_fd_alloc(bool desc)
    240 {
    241         return _vfs_fd_alloc(VFS_DATA, desc);
     254int vfs_fd_alloc(vfs_file_t **file, bool desc)
     255{
     256        return _vfs_fd_alloc(VFS_DATA, file, desc);
    242257}
    243258
     
    289304
    290305        fibril_mutex_lock(&VFS_DATA->lock);     
    291         if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] != NULL)) {
     306        if ((fd < 0) || (fd >= MAX_OPEN_FILES)) {
    292307                fibril_mutex_unlock(&VFS_DATA->lock);
    293                 return EINVAL;
     308                return EBADF;
     309        }
     310        if (FILES[fd] != NULL) {
     311                fibril_mutex_unlock(&VFS_DATA->lock);
     312                return EEXIST;
    294313        }
    295314       
     
    299318       
    300319        return EOK;
     320}
     321
     322static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
     323{
     324        fibril_mutex_unlock(&file->_lock);
     325       
     326        fibril_mutex_lock(&vfs_data->lock);
     327        vfs_file_delref(vfs_data, file);
     328        fibril_mutex_unlock(&vfs_data->lock);
    301329}
    302330
     
    312340                        vfs_file_addref(vfs_data, file);
    313341                        fibril_mutex_unlock(&vfs_data->lock);
     342                       
     343                        fibril_mutex_lock(&file->_lock);
     344                        if (file->node == NULL) {
     345                                _vfs_file_put(vfs_data, file);
     346                                return NULL;
     347                        }
     348                        assert(file != NULL);
     349                        assert(file->node != NULL);
    314350                        return file;
    315351                }
     
    331367}
    332368
    333 static 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 
    340369/** Stop using a file structure.
    341370 *
     
    347376}
    348377
    349 void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
     378void vfs_op_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
    350379{
    351380        vfs_client_data_t *donor_data = NULL;
    352381        vfs_client_data_t *acceptor_data = NULL;
    353382        vfs_file_t *donor_file = NULL;
    354         vfs_file_t *acceptor_file = NULL;
    355383        vfs_boxed_handle_t *bh;
    356         int acceptor_fd;
    357384
    358385        acceptor_data = async_get_client_data_by_id(acceptor_id);
     
    364391
    365392        link_initialize(&bh->link);
    366         bh->handle = -1;
     393        bh->node = NULL;
    367394
    368395        donor_data = async_get_client_data_by_id(donor_id);
     
    373400        if (!donor_file)
    374401                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;
    381402
    382403        /*
     
    384405         */
    385406        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;
     407        bh->node = donor_file->node;
     408        bh->permissions = donor_file->permissions;
    397409
    398410out:
     
    408420        if (donor_file)
    409421                _vfs_file_put(donor_data, donor_file);
    410         if (acceptor_file)
    411                 _vfs_file_put(acceptor_data, acceptor_file);
    412 
    413 }
    414 
    415 int vfs_wait_handle_internal(void)
     422}
     423
     424int vfs_wait_handle_internal(bool high_fd)
    416425{
    417426        vfs_client_data_t *vfs_data = VFS_DATA;
    418         int fd;
    419427       
    420428        fibril_mutex_lock(&vfs_data->lock);
     
    426434
    427435        vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
    428         fd = bh->handle;
     436
     437        vfs_file_t *file;
     438        int fd = _vfs_fd_alloc(vfs_data, &file, high_fd);
     439        if (fd < 0) {
     440                vfs_node_delref(bh->node);
     441                free(bh);
     442                return fd;
     443        }
     444       
     445        file->node = bh->node;
     446        file->permissions = bh->permissions;
     447        vfs_file_put(file);
    429448        free(bh);
    430 
    431449        return fd;
    432450}
Note: See TracChangeset for help on using the changeset viewer.