Ignore:
File:
1 edited

Legend:

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

    r44ecf89 r7769ec9  
    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,
     109            struct mfs_node, link);
     110        assert(keys > 0);
     111        if (mnode->instance->service_id !=
     112            ((service_id_t) key[OPEN_NODES_SERVICE_KEY])) {
     113                return false;
     114        }
     115        if (keys == 1) {
     116                return true;
     117        }
     118        assert(keys == 2);
     119        return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]);
     120}
     121
     122static void
     123open_nodes_remove_cb(link_t *link)
     124{
     125        /* We don't use remove callback for this hash table */
     126}
     127
     128static hash_table_operations_t open_nodes_ops = {
    121129        .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,
     130        .compare = open_nodes_compare,
     131        .remove_callback = open_nodes_remove_cb,
    126132};
    127133
     
    129135mfs_global_init(void)
    130136{
    131         if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) {
     137        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
     138            OPEN_NODES_KEYS, &open_nodes_ops)) {
    132139                return ENOMEM;
    133140        }
     
    190197                /* This is a V1 or V2 Minix filesystem */
    191198                magic = sb->s_magic;
    192         } else if (check_magic_number(sb3->s_magic, &native, &version, &longnames)) {
     199        } else if (check_magic_number(sb3->s_magic, &native,
     200            &version, &longnames)) {
    193201                /* This is a V3 Minix filesystem */
    194202                magic = sb3->s_magic;
     
    400408        mnode->refcnt = 1;
    401409
     410        link_initialize(&mnode->link);
     411
     412        unsigned long key[] = {
     413                [OPEN_NODES_SERVICE_KEY] = inst->service_id,
     414                [OPEN_NODES_INODE_KEY] = inum,
     415        };
     416
    402417        fibril_mutex_lock(&open_nodes_lock);
    403         hash_table_insert(&open_nodes, &mnode->link);
     418        hash_table_insert(&open_nodes, key, &mnode->link);
    404419        fibril_mutex_unlock(&open_nodes_lock);
    405420        inst->open_nodes_cnt++;
     
    452467
    453468                if (comp_size == dentry_name_size &&
    454                     memcmp(component, d_info.d_name, dentry_name_size) == 0) {
     469                    !bcmp(component, d_info.d_name, dentry_name_size)) {
    455470                        /* Hit! */
    456471                        mfs_node_core_get(rfn, mnode->instance,
     
    500515        mnode->refcnt--;
    501516        if (mnode->refcnt == 0) {
    502                 hash_table_remove_item(&open_nodes, &mnode->link);
     517                unsigned long key[] = {
     518                        [OPEN_NODES_SERVICE_KEY] = mnode->instance->service_id,
     519                        [OPEN_NODES_INODE_KEY] = mnode->ino_i->index
     520                };
     521                hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
    503522                assert(mnode->instance->open_nodes_cnt > 0);
    504523                mnode->instance->open_nodes_cnt--;
     
    559578
    560579        /* Check if the node is not already open */
    561         node_key_t key = {
    562                 .service_id = inst->service_id,
    563                 .index = index
     580        unsigned long key[] = {
     581                [OPEN_NODES_SERVICE_KEY] = inst->service_id,
     582                [OPEN_NODES_INODE_KEY] = index,
    564583        };
    565        
    566         ht_link_t *already_open = hash_table_find(&open_nodes, &key);
     584        link_t *already_open = hash_table_find(&open_nodes, key);
    567585
    568586        if (already_open) {
    569                 mnode = hash_table_get_inst(already_open, struct mfs_node, link);
     587                mnode = hash_table_get_instance(already_open,
     588                    struct mfs_node, link);
    570589                *rfn = mnode->fsnode;
    571590                mnode->refcnt++;
     
    598617        mnode->ino_i = ino_i;
    599618        mnode->refcnt = 1;
     619        link_initialize(&mnode->link);
    600620
    601621        mnode->instance = inst;
     
    604624        *rfn = node;
    605625
    606         hash_table_insert(&open_nodes, &mnode->link);
     626        hash_table_insert(&open_nodes, key, &mnode->link);
    607627        inst->open_nodes_cnt++;
    608628
     
    773793{
    774794        int rc;
    775         fs_node_t *fn = NULL;
     795        fs_node_t *fn;
    776796
    777797        rc = mfs_node_get(&fn, service_id, index);
     
    11081128mfs_sync(service_id_t service_id, fs_index_t index)
    11091129{
    1110         fs_node_t *fn = NULL;
     1130        fs_node_t *fn;
    11111131        int rc = mfs_node_get(&fn, service_id, index);
    11121132        if (rc != EOK)
Note: See TracChangeset for help on using the changeset viewer.