Changeset b818cff in mainline


Ignore:
Timestamp:
2007-11-06T17:26:28Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
44358c1
Parents:
6537572
Message:

VFS work.
Implement VFS node hash table management.

Location:
uspace/srv/vfs
Files:
3 edited

Legend:

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

    r6537572 rb818cff  
    125125
    126126        /*
     127         * Initialize VFS node hash table.
     128         */
     129        if (!vfs_nodes_init()) {
     130                printf("Failed to initialize the VFS node hash table.\n");
     131                return ENOMEM;
     132        }
     133
     134        /*
    127135         * Allocate and initialize the Path Lookup Buffer.
    128136         */
  • uspace/srv/vfs/vfs.h

    r6537572 rb818cff  
    179179extern int vfs_lookup_internal(char *, size_t, vfs_triplet_t *, vfs_pair_t *);
    180180
    181 
     181extern bool vfs_nodes_init(void);
    182182extern vfs_node_t *vfs_node_get(vfs_triplet_t *);
    183183extern void vfs_node_put(vfs_node_t *);
     184
     185#define MAX_OPEN_FILES  128
    184186
    185187extern bool vfs_files_init(void);
     
    194196extern void vfs_node_delref(vfs_node_t *);
    195197
    196 #define MAX_OPEN_FILES  128     
    197 
    198198extern void vfs_register(ipc_callid_t, ipc_call_t *);
    199199extern void vfs_mount(ipc_callid_t, ipc_call_t *);
  • uspace/srv/vfs/vfs_node.c

    r6537572 rb818cff  
    3737
    3838#include "vfs.h"
     39#include <stdlib.h>
     40#include <string.h>
     41#include <atomic.h>
     42#include <futex.h>
     43#include <libadt/hash_table.h>
     44
     45/** Futex protecting the VFS node hash table. */
     46atomic_t nodes_futex = FUTEX_INITIALIZER;
     47
     48#define NODES_BUCKETS_LOG       8
     49#define NODES_BUCKETS           (1 << NODES_BUCKETS_LOG)
     50
     51/** VFS node hash table containing all active, in-memory VFS nodes. */
     52hash_table_t nodes;
     53
     54#define KEY_FS_HANDLE   0
     55#define KEY_DEV_HANDLE  1
     56#define KEY_INDEX       2
     57
     58static hash_index_t nodes_hash(unsigned long []);
     59static int nodes_compare(unsigned long [], hash_count_t, link_t *);
     60static void nodes_remove_callback(link_t *);
     61
     62/** VFS node hash table operations. */
     63hash_table_operations_t nodes_ops = {
     64        .hash = nodes_hash,
     65        .compare = nodes_compare,
     66        .remove_callback = nodes_remove_callback
     67};
     68
     69/** Initialize the VFS node hash table.
     70 *
     71 * @return              Return true on success, false on failure.
     72 */
     73bool vfs_nodes_init(void)
     74{
     75        return hash_table_create(&nodes, NODES_BUCKETS, 3, &nodes_ops);
     76}
     77
     78static inline void _vfs_node_addref(vfs_node_t *node)
     79{
     80        node->refcnt++;
     81}
    3982
    4083/** Increment reference count of a VFS node.
     
    4487void vfs_node_addref(vfs_node_t *node)
    4588{
    46         /* TODO */
     89        futex_down(&nodes_futex);
     90        _vfs_node_addref(node);
     91        futex_up(&nodes_futex);
    4792}
    4893
     
    55100void vfs_node_delref(vfs_node_t *node)
    56101{
    57         /* TODO */
     102        futex_down(&nodes_futex);
     103        if (node->refcnt-- == 1) {
     104                unsigned long key[] = {
     105                        [KEY_FS_HANDLE] = node->fs_handle,
     106                        [KEY_DEV_HANDLE] = node->dev_handle,
     107                        [KEY_INDEX] = node->index
     108                };
     109                hash_table_remove(&nodes, key, 3);
     110        }
     111        futex_up(&nodes_futex);
    58112}
    59113
     
    72126vfs_node_t *vfs_node_get(vfs_triplet_t *triplet)
    73127{
    74         /* TODO */
    75         return NULL;
     128        unsigned long key[] = {
     129                [KEY_FS_HANDLE] = triplet->fs_handle,
     130                [KEY_DEV_HANDLE] = triplet->dev_handle,
     131                [KEY_INDEX] = triplet->index
     132        };
     133        link_t *tmp;
     134        vfs_node_t *node;
     135
     136        futex_down(&nodes_futex);
     137        tmp = hash_table_find(&nodes, key);
     138        if (!tmp) {
     139                node = (vfs_node_t *) malloc(sizeof(vfs_node_t));
     140                if (!node) {
     141                        futex_up(&nodes_futex);
     142                        return NULL;
     143                }
     144                memset(node, 0, sizeof(vfs_node_t));
     145                node->fs_handle = triplet->fs_handle;
     146                node->dev_handle = triplet->fs_handle;
     147                node->index = triplet->index;
     148                link_initialize(&node->nh_link);
     149                hash_table_insert(&nodes, key, &node->nh_link);
     150        } else {
     151                node = hash_table_get_instance(tmp, vfs_node_t, nh_link);       
     152        }
     153        _vfs_node_addref(node);
     154        futex_up(&nodes_futex);
     155
     156        return node;
    76157}
    77158
     
    89170}
    90171
     172hash_index_t nodes_hash(unsigned long key[])
     173{
     174        hash_index_t a = key[KEY_FS_HANDLE] << (NODES_BUCKETS_LOG / 4);
     175        hash_index_t b = (a | key[KEY_DEV_HANDLE]) << (NODES_BUCKETS_LOG / 2);
     176       
     177        return (b | key[KEY_INDEX]) & ~(NODES_BUCKETS - 1);
     178}
     179
     180int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item)
     181{
     182        vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);
     183        return (node->fs_handle == key[KEY_FS_HANDLE]) &&
     184            (node->dev_handle == key[KEY_DEV_HANDLE]) &&
     185            (node->index == key[KEY_INDEX]);
     186}
     187
     188void nodes_remove_callback(link_t *item)
     189{
     190        vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);
     191        free(node);
     192}
     193
    91194/**
    92195 * @}
Note: See TracChangeset for help on using the changeset viewer.