Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/mfs/mfs_ops.c

    r4e00f87 r9d58539  
    3535#include <align.h>
    3636#include <adt/hash_table.h>
    37 #include <adt/hash.h>
    3837#include "mfs.h"
    3938
     39#define OPEN_NODES_KEYS 2
     40#define OPEN_NODES_SERVICE_KEY 0
     41#define OPEN_NODES_INODE_KEY 1
     42#define OPEN_NODES_BUCKETS 256
    4043
    4144static bool check_magic_number(uint16_t magic, bool *native,
     
    5861static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name);
    5962static int mfs_destroy_node(fs_node_t *fn);
     63static hash_index_t open_nodes_hash(unsigned long key[]);
     64static int open_nodes_compare(unsigned long key[], hash_count_t keys,
     65    link_t *item);
     66static void open_nodes_remove_cb(link_t *link);
    6067static int mfs_node_get(fs_node_t **rfn, service_id_t service_id,
    6168    fs_index_t index);
     
    8895
    8996/* Hash table interface for open nodes hash table */
    90 
    91 typedef struct {
    92         service_id_t service_id;
    93         fs_index_t index;
    94 } node_key_t;
    95 
    96 static size_t
    97 open_nodes_key_hash(void *key)
    98 {
    99         node_key_t *node_key = (node_key_t*)key;
    100         return hash_combine(node_key->service_id, node_key->index);
    101 }
    102 
    103 static size_t
    104 open_nodes_hash(const ht_link_t *item)
    105 {
    106         struct mfs_node *m = hash_table_get_inst(item, struct mfs_node, link);
    107         return hash_combine(m->instance->service_id, m->ino_i->index);
    108 }
    109 
    110 static bool
    111 open_nodes_key_equal(void *key, const ht_link_t *item)
    112 {
    113         node_key_t *node_key = (node_key_t*)key;
    114         struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link);
    115 
    116         return node_key->service_id == mnode->instance->service_id
    117                 && node_key->index == mnode->ino_i->index;
    118 }
    119 
    120 static hash_table_ops_t open_nodes_ops = {
     97static hash_index_t
     98open_nodes_hash(unsigned long key[])
     99{
     100        /* TODO: This is very simple and probably can be improved */
     101        return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;
     102}
     103
     104static int
     105open_nodes_compare(unsigned long key[], hash_count_t keys,
     106    link_t *item)
     107{
     108        struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link);
     109        assert(keys > 0);
     110        if (mnode->instance->service_id !=
     111            ((service_id_t) key[OPEN_NODES_SERVICE_KEY])) {
     112                return false;
     113        }
     114        if (keys == 1) {
     115                return true;
     116        }
     117        assert(keys == 2);
     118        return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]);
     119}
     120
     121static void
     122open_nodes_remove_cb(link_t *link)
     123{
     124        /* We don't use remove callback for this hash table */
     125}
     126
     127static hash_table_operations_t open_nodes_ops = {
    121128        .hash = open_nodes_hash,
    122         .key_hash = open_nodes_key_hash,
    123         .key_equal = open_nodes_key_equal,
    124         .equal = NULL,
    125         .remove_callback = NULL,
     129        .compare = open_nodes_compare,
     130        .remove_callback = open_nodes_remove_cb,
    126131};
    127132
     
    129134mfs_global_init(void)
    130135{
    131         if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) {
     136        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
     137            OPEN_NODES_KEYS, &open_nodes_ops)) {
    132138                return ENOMEM;
    133139        }
     
    400406        mnode->refcnt = 1;
    401407
     408        link_initialize(&mnode->link);
     409
     410        unsigned long key[] = {
     411                [OPEN_NODES_SERVICE_KEY] = inst->service_id,
     412                [OPEN_NODES_INODE_KEY] = inum,
     413        };
     414
    402415        fibril_mutex_lock(&open_nodes_lock);
    403         hash_table_insert(&open_nodes, &mnode->link);
     416        hash_table_insert(&open_nodes, key, &mnode->link);
    404417        fibril_mutex_unlock(&open_nodes_lock);
    405418        inst->open_nodes_cnt++;
     
    500513        mnode->refcnt--;
    501514        if (mnode->refcnt == 0) {
    502                 hash_table_remove_item(&open_nodes, &mnode->link);
     515                unsigned long key[] = {
     516                        [OPEN_NODES_SERVICE_KEY] = mnode->instance->service_id,
     517                        [OPEN_NODES_INODE_KEY] = mnode->ino_i->index
     518                };
     519                hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
    503520                assert(mnode->instance->open_nodes_cnt > 0);
    504521                mnode->instance->open_nodes_cnt--;
     
    559576
    560577        /* Check if the node is not already open */
    561         node_key_t key = {
    562                 .service_id = inst->service_id,
    563                 .index = index
     578        unsigned long key[] = {
     579                [OPEN_NODES_SERVICE_KEY] = inst->service_id,
     580                [OPEN_NODES_INODE_KEY] = index,
    564581        };
    565        
    566         ht_link_t *already_open = hash_table_find(&open_nodes, &key);
     582        link_t *already_open = hash_table_find(&open_nodes, key);
    567583
    568584        if (already_open) {
    569                 mnode = hash_table_get_inst(already_open, struct mfs_node, link);
     585                mnode = hash_table_get_instance(already_open, struct mfs_node, link);
    570586                *rfn = mnode->fsnode;
    571587                mnode->refcnt++;
     
    598614        mnode->ino_i = ino_i;
    599615        mnode->refcnt = 1;
     616        link_initialize(&mnode->link);
    600617
    601618        mnode->instance = inst;
     
    604621        *rfn = node;
    605622
    606         hash_table_insert(&open_nodes, &mnode->link);
     623        hash_table_insert(&open_nodes, key, &mnode->link);
    607624        inst->open_nodes_cnt++;
    608625
Note: See TracChangeset for help on using the changeset viewer.