Changeset efdfebc in mainline for uspace/srv/fs/ext2fs/ext2fs_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/ext2fs/ext2fs_ops.c

    rde73242 refdfebc  
    3939#include "../../vfs/vfs.h"
    4040#include <libfs.h>
    41 #include <libblock.h>
     41#include <block.h>
    4242#include <libext2.h>
    4343#include <ipc/services.h>
     
    4949#include <byteorder.h>
    5050#include <adt/hash_table.h>
     51#include <adt/hash.h>
    5152#include <adt/list.h>
    5253#include <assert.h>
     
    6263#define EXT2FS_NODE(node)       ((node) ? (ext2fs_node_t *) (node)->data : NULL)
    6364#define EXT2FS_DBG(format, ...) {if (false) printf("ext2fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);}
    64 #define OPEN_NODES_KEYS 2
    65 #define OPEN_NODES_DEV_HANDLE_KEY 0
    66 #define OPEN_NODES_INODE_KEY 1
    67 #define OPEN_NODES_BUCKETS 256
    6865
    6966typedef struct ext2fs_instance {
     
    7875        ext2_inode_ref_t *inode_ref;
    7976        fs_node_t *fs_node;
    80         link_t link;
     77        ht_link_t link;
    8178        unsigned int references;
    8279} ext2fs_node_t;
     
    122119static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
    123120
    124 /* Hash table interface for open nodes hash table */
    125 static hash_index_t open_nodes_hash(unsigned long key[])
    126 {
    127         /* TODO: This is very simple and probably can be improved */
    128         return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;
    129 }
    130 
    131 static int open_nodes_compare(unsigned long key[], hash_count_t keys,
    132     link_t *item)
    133 {
    134         ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link);
    135         assert(keys > 0);
    136         if (enode->instance->service_id !=
    137             ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
    138                 return false;
    139         }
    140         if (keys == 1) {
    141                 return true;
    142         }
    143         assert(keys == 2);
    144         return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]);
    145 }
    146 
    147 static void open_nodes_remove_cb(link_t *link)
    148 {
    149         /* We don't use remove callback for this hash table */
    150 }
    151 
    152 static hash_table_operations_t open_nodes_ops = {
     121/*
     122 * Hash table interface for open nodes hash table
     123 */
     124
     125typedef struct {
     126        service_id_t service_id;
     127        fs_index_t index;
     128} node_key_t;
     129
     130static size_t open_nodes_key_hash(void *key)
     131{
     132        node_key_t *node_key = (node_key_t*)key;
     133        return hash_combine(node_key->service_id, node_key->index);
     134}
     135
     136static size_t open_nodes_hash(const ht_link_t *item)
     137{
     138        ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link);
     139
     140        assert(enode->instance);
     141        assert(enode->inode_ref);
     142       
     143        return hash_combine(enode->instance->service_id, enode->inode_ref->index);
     144}
     145
     146static bool open_nodes_key_equal(void *key, const ht_link_t *item)
     147{
     148        node_key_t *node_key = (node_key_t*)key;
     149        ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link);
     150       
     151        return node_key->service_id == enode->instance->service_id
     152                && node_key->index == enode->inode_ref->index;
     153}
     154
     155static hash_table_ops_t open_nodes_ops = {
    153156        .hash = open_nodes_hash,
    154         .compare = open_nodes_compare,
    155         .remove_callback = open_nodes_remove_cb,
     157        .key_hash = open_nodes_key_hash,
     158        .key_equal = open_nodes_key_equal,
     159        .equal = NULL,
     160        .remove_callback = NULL,
    156161};
    157162
     
    161166int ext2fs_global_init(void)
    162167{
    163         if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
    164             OPEN_NODES_KEYS, &open_nodes_ops)) {
     168        if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) {
    165169                return ENOMEM;
    166170        }
     
    316320       
    317321        /* Check if the node is not already open */
    318         unsigned long key[] = {
    319                 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    320                 [OPEN_NODES_INODE_KEY] = index,
     322        node_key_t key = {
     323                .service_id = inst->service_id,
     324                .index = index
    321325        };
    322         link_t *already_open = hash_table_find(&open_nodes, key);
     326        ht_link_t *already_open = hash_table_find(&open_nodes, &key);
    323327
    324328        if (already_open) {
    325                 enode = hash_table_get_instance(already_open, ext2fs_node_t, link);
     329                enode = hash_table_get_inst(already_open, ext2fs_node_t, link);
    326330                *rfn = enode->fs_node;
    327331                enode->references++;
     
    357361        enode->references = 1;
    358362        enode->fs_node = node;
    359         link_initialize(&enode->link);
    360363       
    361364        node->data = enode;
    362365        *rfn = node;
    363366       
    364         hash_table_insert(&open_nodes, key, &enode->link);
     367        hash_table_insert(&open_nodes, &enode->link);
    365368        inst->open_nodes_count++;
    366369       
     
    408411int ext2fs_node_put_core(ext2fs_node_t *enode)
    409412{
    410         int rc;
    411 
    412         unsigned long key[] = {
    413                 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id,
    414                 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index,
     413        node_key_t key = {
     414                .service_id = enode->instance->service_id,
     415                .index = enode->inode_ref->index
    415416        };
    416         hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
     417
     418        hash_table_remove(&open_nodes, &key);
     419       
    417420        assert(enode->instance->open_nodes_count > 0);
    418421        enode->instance->open_nodes_count--;
    419422
    420         rc = ext2_filesystem_put_inode_ref(enode->inode_ref);
     423        int rc = ext2_filesystem_put_inode_ref(enode->inode_ref);
    421424        if (rc != EOK) {
    422425                EXT2FS_DBG("ext2_filesystem_put_inode_ref failed");
Note: See TracChangeset for help on using the changeset viewer.