Changeset efdfebc in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.c


Ignore:
Timestamp:
2012-11-06T21:03:44Z (11 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
338810f
Parents:
de73242 (diff), 94795812 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    rde73242 refdfebc  
    5050#include <sys/types.h>
    5151#include <adt/hash_table.h>
     52#include <adt/hash.h>
    5253#include <as.h>
    5354#include <libfs.h>
     
    5556#define min(a, b)               ((a) < (b) ? (a) : (b))
    5657#define max(a, b)               ((a) > (b) ? (a) : (b))
    57 
    58 #define NODES_BUCKETS   256
    5958
    6059/** All root nodes have index 0. */
     
    142141hash_table_t nodes;
    143142
    144 #define NODES_KEY_DEV   0       
    145 #define NODES_KEY_INDEX 1
    146 
    147 /* Implementation of hash table interface for the nodes hash table. */
    148 static hash_index_t nodes_hash(unsigned long key[])
    149 {
    150         return key[NODES_KEY_INDEX] % NODES_BUCKETS;
    151 }
    152 
    153 static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item)
    154 {
    155         tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    156             nh_link);
    157        
    158         switch (keys) {
    159         case 1:
    160                 return (nodep->service_id == key[NODES_KEY_DEV]);
    161         case 2:
    162                 return ((nodep->service_id == key[NODES_KEY_DEV]) &&
    163                     (nodep->index == key[NODES_KEY_INDEX]));
    164         default:
    165                 assert((keys == 1) || (keys == 2));
    166         }
    167 
    168         return 0;
    169 }
    170 
    171 static void nodes_remove_callback(link_t *item)
    172 {
    173         tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    174             nh_link);
     143/*
     144 * Implementation of hash table interface for the nodes hash table.
     145 */
     146
     147typedef struct {
     148        service_id_t service_id;
     149        fs_index_t index;
     150} node_key_t;
     151
     152static size_t nodes_key_hash(void *k)
     153{
     154        node_key_t *key = (node_key_t *)k;
     155        return hash_combine(key->service_id, key->index);
     156}
     157
     158static size_t nodes_hash(const ht_link_t *item)
     159{
     160        tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     161        return hash_combine(nodep->service_id, nodep->index);
     162}
     163
     164static bool nodes_key_equal(void *key_arg, const ht_link_t *item)
     165{
     166        tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     167        node_key_t *key = (node_key_t *)key_arg;
     168       
     169        return key->service_id == node->service_id && key->index == node->index;
     170}
     171
     172static void nodes_remove_callback(ht_link_t *item)
     173{
     174        tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
    175175
    176176        while (!list_empty(&nodep->cs_list)) {
     
    192192
    193193/** TMPFS nodes hash table operations. */
    194 hash_table_operations_t nodes_ops = {
     194hash_table_ops_t nodes_ops = {
    195195        .hash = nodes_hash,
    196         .compare = nodes_compare,
     196        .key_hash = nodes_key_hash,
     197        .key_equal = nodes_key_equal,
     198        .equal = NULL,
    197199        .remove_callback = nodes_remove_callback
    198200};
     
    207209        nodep->size = 0;
    208210        nodep->data = NULL;
    209         link_initialize(&nodep->nh_link);
    210211        list_initialize(&nodep->cs_list);
    211212}
     
    220221bool tmpfs_init(void)
    221222{
    222         if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))
     223        if (!hash_table_create(&nodes, 0, 0, &nodes_ops))
    223224                return false;
    224225       
     
    238239}
    239240
     241static bool rm_service_id_nodes(ht_link_t *item, void *arg)
     242{
     243        service_id_t sid = *(service_id_t*)arg;
     244        tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     245       
     246        if (node->service_id == sid) {
     247                hash_table_remove_item(&nodes, &node->nh_link);
     248        }
     249        return true;
     250}
     251
    240252static void tmpfs_instance_done(service_id_t service_id)
    241 {
    242         unsigned long key[] = {
    243                 [NODES_KEY_DEV] = service_id
    244         };
    245         /*
    246          * Here we are making use of one special feature of our hash table
    247          * implementation, which allows to remove more items based on a partial
    248          * key match. In the following, we are going to remove all nodes
    249          * matching our device handle. The nodes_remove_callback() function will
    250          * take care of resource deallocation.
    251          */
    252         hash_table_remove(&nodes, key, 1);
     253{       
     254        hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
    253255}
    254256
     
    272274int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    273275{
    274         unsigned long key[] = {
    275                 [NODES_KEY_DEV] = service_id,
    276                 [NODES_KEY_INDEX] = index
     276        node_key_t key = {
     277                .service_id = service_id,
     278                .index = index
    277279        };
    278         link_t *lnk = hash_table_find(&nodes, key);
     280       
     281        ht_link_t *lnk = hash_table_find(&nodes, &key);
     282       
    279283        if (lnk) {
    280284                tmpfs_node_t *nodep;
    281                 nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link);
     285                nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link);
    282286                *rfn = FS_NODE(nodep);
    283287        } else {
     
    331335
    332336        /* Insert the new node into the nodes hash table. */
    333         unsigned long key[] = {
    334                 [NODES_KEY_DEV] = nodep->service_id,
    335                 [NODES_KEY_INDEX] = nodep->index
    336         };
    337         hash_table_insert(&nodes, key, &nodep->nh_link);
     337        hash_table_insert(&nodes, &nodep->nh_link);
    338338        *rfn = FS_NODE(nodep);
    339339        return EOK;
     
    346346        assert(!nodep->lnkcnt);
    347347        assert(list_empty(&nodep->cs_list));
    348 
    349         unsigned long key[] = {
    350                 [NODES_KEY_DEV] = nodep->service_id,
    351                 [NODES_KEY_INDEX] = nodep->index
    352         };
    353         hash_table_remove(&nodes, key, 2);
     348       
     349        hash_table_remove_item(&nodes, &nodep->nh_link);
    354350
    355351        /*
     
    476472         * Lookup the respective TMPFS node.
    477473         */
    478         link_t *hlp;
    479         unsigned long key[] = {
    480                 [NODES_KEY_DEV] = service_id,
    481                 [NODES_KEY_INDEX] = index
     474        node_key_t key = {
     475                .service_id = service_id,
     476                .index = index
    482477        };
    483         hlp = hash_table_find(&nodes, key);
     478       
     479        ht_link_t *hlp = hash_table_find(&nodes, &key);
    484480        if (!hlp)
    485481                return ENOENT;
    486         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    487             nh_link);
     482       
     483        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    488484       
    489485        /*
     
    538534         * Lookup the respective TMPFS node.
    539535         */
    540         link_t *hlp;
    541         unsigned long key[] = {
    542                 [NODES_KEY_DEV] = service_id,
    543                 [NODES_KEY_INDEX] = index
     536        node_key_t key = {
     537                .service_id = service_id,
     538                .index = index
    544539        };
    545         hlp = hash_table_find(&nodes, key);
     540       
     541        ht_link_t *hlp = hash_table_find(&nodes, &key);
     542       
    546543        if (!hlp)
    547544                return ENOENT;
    548         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    549             nh_link);
     545       
     546        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    550547
    551548        /*
     
    600597         * Lookup the respective TMPFS node.
    601598         */
    602         unsigned long key[] = {
    603                 [NODES_KEY_DEV] = service_id,
    604                 [NODES_KEY_INDEX] = index
     599        node_key_t key = {
     600                .service_id = service_id,
     601                .index = index
    605602        };
    606         link_t *hlp = hash_table_find(&nodes, key);
     603       
     604        ht_link_t *hlp = hash_table_find(&nodes, &key);
     605       
    607606        if (!hlp)
    608607                return ENOENT;
    609         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
     608        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    610609       
    611610        if (size == nodep->size)
     
    636635static int tmpfs_destroy(service_id_t service_id, fs_index_t index)
    637636{
    638         link_t *hlp;
    639         unsigned long key[] = {
    640                 [NODES_KEY_DEV] = service_id,
    641                 [NODES_KEY_INDEX] = index
     637        node_key_t key = {
     638                .service_id = service_id,
     639                .index = index
    642640        };
    643         hlp = hash_table_find(&nodes, key);
     641       
     642        ht_link_t *hlp = hash_table_find(&nodes, &key);
    644643        if (!hlp)
    645644                return ENOENT;
    646         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
     645        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t,
    647646            nh_link);
    648647        return tmpfs_destroy_node(FS_NODE(nodep));
Note: See TracChangeset for help on using the changeset viewer.