Changeset 320c884 in mainline for uspace/srv/vfs/vfs_open.c


Ignore:
Timestamp:
2007-11-04T19:47:32Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
798f364
Parents:
89cb140
Message:

A lot of more VFS prototyping.
VFS_OPEN gets reasonably complete, fix a limitation that prevented file
structures from being shared by multiple file descriptors, add functions for
file descriptor management, introduce unlink_futex and two new VFS operations
VFS_UNLINK and VFS_RENAME.

File:
1 edited

Legend:

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

    r89cb140 r320c884  
    3939#include <async.h>
    4040#include <errno.h>
     41#include <futex.h>
     42#include <sys/types.h>
    4143#include <stdlib.h>
    42 #include <string.h>
    43 #include <bool.h>
    44 #include <futex.h>
    45 #include <libadt/list.h>
    46 #include <sys/types.h>
    4744#include "vfs.h"
    48 
    49 /** Per-connection futex protecting the files array. */
    50 __thread atomic_t files_futex = FUTEX_INITIALIZER;
    51 
    52 /**
    53  * This is a per-connection table of open files.
    54  * Our assumption is that each client opens only one connection and therefore
    55  * there is one table of open files per task. However, this may not be the case
    56  * and the client can open more connections to VFS. In that case, there will be
    57  * several tables and several file handle name spaces per task. Besides of this,
    58  * the functionality will stay unchanged. So unless the client knows what it is
    59  * doing, it should open one connection to VFS only.
    60  *
    61  * Allocation of the open files table is deferred until the client makes the
    62  * first VFS_OPEN operation.
    63  */
    64 __thread vfs_file_t *files = NULL;
    65 
    66 /** Initialize the table of open files. */
    67 static bool vfs_conn_open_files_init(void)
    68 {
    69         /*
    70          * Optimized fast path that will never go to sleep unnecessarily.
    71          * The assumption is that once files is non-zero, it will never be zero
    72          * again.
    73          */
    74         if (files)
    75                 return true;
    76                
    77         futex_down(&files_futex);
    78         if (!files) {
    79                 files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t));
    80                 if (!files) {
    81                         futex_up(&files_futex);
    82                         return false;
    83                 }
    84                 memset(files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t));
    85         }
    86         futex_up(&files_futex);
    87         return true;
    88 }
    8945
    9046void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    9147{
    92         if (!vfs_conn_open_files_init()) {
     48        if (!vfs_files_init()) {
    9349                ipc_answer_fast_0(rid, ENOMEM);
    9450                return;
     
    12884
    12985        int rc;
    130         if (rc = ipc_data_deliver(callid, &call, path, size)) {
     86        if ((rc = ipc_data_deliver(callid, &call, path, size))) {
    13187                ipc_answer_fast_0(rid, rc);
    13288                free(path);
     
    13591       
    13692        /*
     93         * Avoid the race condition in which the file can be deleted before we
     94         * find/create-and-lock the VFS node corresponding to the looked-up
     95         * triplet.
     96         */
     97        futex_down(&unlink_futex);
     98
     99        /*
    137100         * The path is now populated and we can call vfs_lookup_internal().
    138101         */
     
    140103        rc = vfs_lookup_internal(path, size, &triplet, NULL);
    141104        if (rc) {
     105                futex_up(&unlink_futex);
    142106                ipc_answer_fast_0(rid, rc);
    143107                free(path);
     
    151115
    152116        vfs_node_t *node = vfs_node_get(&triplet);
    153         // TODO: not finished   
     117        futex_up(&unlink_futex);
     118
     119        /*
     120         * Get ourselves a file descriptor and the corresponding vfs_file_t
     121         * structure.
     122         */
     123        int fd = vfs_fd_alloc();
     124        if (fd < 0) {
     125                vfs_node_put(node);
     126                ipc_answer_fast_0(rid, fd);
     127                return;
     128        }
     129        vfs_file_t *file = vfs_file_get(fd);
     130        file->node = node;
     131
     132        /*
     133         * The following increase in reference count is for the fact that the
     134         * file is being opened and that a file structure is pointing to it.
     135         * It is necessary so that the file will not disappear when
     136         * vfs_node_put() is called. The reference will be dropped by the
     137         * respective VFS_CLOSE.
     138         */
     139        vfs_node_addref(node);
     140        vfs_node_put(node);
     141
     142        /*
     143         * Success! Return the new file descriptor to the client.
     144         */
     145        ipc_answer_fast_1(rid, EOK, fd);
    154146}
    155147
Note: See TracChangeset for help on using the changeset viewer.