Changeset 320c884 in mainline


Ignore:
Timestamp:
2007-11-04T19:47:32Z (17 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.

Location:
uspace/srv/vfs
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/Makefile

    r89cb140 r320c884  
    4444        vfs.c \
    4545        vfs_node.c \
     46        vfs_file.c \
    4647        vfs_register.c \
    4748        vfs_lookup.c \
    4849        vfs_mount.c \
    49         vfs_open.c
     50        vfs_open.c \
     51        vfs_unlink.c
    5052
    5153OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
  • uspace/srv/vfs/vfs.c

    r89cb140 r320c884  
    101101                case VFS_WRITE:
    102102                case VFS_SEEK:
     103                case VFS_UNLINK:
     104                case VFS_RENAME:
    103105                default:
    104106                        ipc_answer_fast_0(callid, ENOTSUP);
  • uspace/srv/vfs/vfs.h

    r89cb140 r320c884  
    5757        VFS_WRITE,
    5858        VFS_SEEK,
     59        VFS_RENAME,
     60        VFS_UNLINK,
    5961        VFS_LAST,               /* keep this the last member of the enum */
    6062} vfs_request_t;
     
    131133typedef struct {
    132134        VFS_TRIPLET;            /**< Identity of the node. */
    133         atomic_t refcnt;        /**< Usage counter. */
     135        unsigned refcnt;        /**< Usage counter. */
     136        link_t nh_link;         /**< Node hash-table link. */
    134137} vfs_node_t;
    135138
     
    142145       
    143146        /** Number of file handles referencing this file. */
    144         atomic_t refcnt;
     147        unsigned refcnt;
    145148
    146149        /** Current position in the file. */
     
    167170extern link_t plb_head;         /**< List of active PLB entries. */
    168171
     172extern atomic_t unlink_futex;   /**< VFS_{CREATE|OPEN|UNLINK} serialization. */
     173
    169174extern int vfs_grab_phone(int);
    170175extern void vfs_release_phone(int);
     
    173178
    174179extern int vfs_lookup_internal(char *, size_t, vfs_triplet_t *, vfs_pair_t *);
     180
     181
    175182extern vfs_node_t *vfs_node_get(vfs_triplet_t *);
     183extern void vfs_node_put(vfs_node_t *);
     184
     185extern bool vfs_files_init(void);
     186extern vfs_file_t *vfs_file_get(int);
     187extern int vfs_fd_alloc(void);
     188extern void vfs_fd_free(int);
     189
     190extern void vfs_file_addref(vfs_file_t *);
     191extern void vfs_file_delref(vfs_file_t *);
     192
     193extern void vfs_node_addref(vfs_node_t *);
     194extern void vfs_node_delref(vfs_node_t *);
    176195
    177196#define MAX_OPEN_FILES  128     
  • uspace/srv/vfs/vfs_node.c

    r89cb140 r320c884  
    3838#include "vfs.h"
    3939
     40/** Increment reference count of a VFS node.
     41 *
     42 * @param node          VFS node that will have its refcnt incremented.
     43 */
     44void vfs_node_addref(vfs_node_t *node)
     45{
     46        /* TODO */
     47}
     48
     49/** Decrement reference count of a VFS node.
     50 *
     51 * This function handles the case when the reference count drops to zero.
     52 *
     53 * @param node          VFS node that will have its refcnt decremented.
     54 */
     55void vfs_node_delref(vfs_node_t *node)
     56{
     57        /* TODO */
     58}
     59
     60/** Find VFS node.
     61 *
     62 * This function will try to lookup the given triplet in the VFS node hash
     63 * table. In case the triplet is not found there, a new VFS node is created.
     64 * In any case, the VFS node will have its reference count incremented. Every
     65 * node returned by this call should be eventually put back by calling
     66 * vfs_node_put() on it.
     67 *
     68 * @param triplet       Triplet encoding the identity of the VFS node.
     69 *
     70 * @return              VFS node corresponding to the given triplet.
     71 */
    4072vfs_node_t *vfs_node_get(vfs_triplet_t *triplet)
    4173{
    42         return NULL;    // TODO: not implemented
     74        /* TODO */
     75        return NULL;
     76}
     77
     78/** Return VFS node when no longer needed by the caller.
     79 *
     80 * This function will remove the reference on the VFS node created by
     81 * vfs_node_get(). This function can only be called as a closing bracket to the
     82 * preceding vfs_node_get() call.
     83 *
     84 * @param node          VFS node being released.
     85 */
     86void vfs_node_put(vfs_node_t *node)
     87{
     88        vfs_node_delref(node);
    4389}
    4490
  • 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.