Changes in uspace/srv/fs/ext4fs/ext4fs_ops.c [062d900:38542dc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/ext4fs/ext4fs_ops.c
r062d900 r38542dc 42 42 #include <malloc.h> 43 43 #include <adt/hash_table.h> 44 #include <adt/hash.h>45 44 #include <ipc/loc.h> 46 45 #include "ext4fs.h" … … 49 48 #define EXT4FS_NODE(node) \ 50 49 ((node) ? (ext4fs_node_t *) (node)->data : NULL) 50 51 #define OPEN_NODES_KEYS 2 52 53 #define OPEN_NODES_DEV_HANDLE_KEY 0 54 #define OPEN_NODES_INODE_KEY 1 55 56 #define OPEN_NODES_BUCKETS 256 51 57 52 58 /** … … 67 73 ext4_inode_ref_t *inode_ref; 68 74 fs_node_t *fs_node; 69 ht_link_t link;75 link_t link; 70 76 unsigned int references; 71 77 } ext4fs_node_t; … … 109 115 110 116 /* Hash table interface for open nodes hash table */ 111 112 typedef struct { 113 service_id_t service_id; 114 fs_index_t index; 115 } node_key_t; 116 117 static size_t open_nodes_key_hash(void *key_arg) 118 { 119 node_key_t *key = (node_key_t *)key_arg; 120 return hash_combine(key->service_id, key->index); 121 } 122 123 static size_t open_nodes_hash(const ht_link_t *item) 124 { 125 ext4fs_node_t *enode = hash_table_get_inst(item, ext4fs_node_t, link); 126 return hash_combine(enode->instance->service_id, enode->inode_ref->index); 127 } 128 129 static bool open_nodes_key_equal(void *key_arg, const ht_link_t *item) 130 { 131 node_key_t *key = (node_key_t *)key_arg; 132 ext4fs_node_t *enode = hash_table_get_inst(item, ext4fs_node_t, link); 133 134 return key->service_id == enode->instance->service_id 135 && key->index == enode->inode_ref->index; 136 } 137 138 static hash_table_ops_t open_nodes_ops = { 117 static hash_index_t open_nodes_hash(unsigned long key[]) 118 { 119 /* TODO: This is very simple and probably can be improved */ 120 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS; 121 } 122 123 /** Compare given item with values in hash table. 124 * 125 */ 126 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 127 link_t *item) 128 { 129 assert(keys > 0); 130 131 ext4fs_node_t *enode = 132 hash_table_get_instance(item, ext4fs_node_t, link); 133 134 if (enode->instance->service_id != 135 ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) 136 return false; 137 138 if (keys == 1) 139 return true; 140 141 assert(keys == 2); 142 143 return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]); 144 } 145 146 /** Empty callback to correct hash table initialization. 147 * 148 */ 149 static void open_nodes_remove_cb(link_t *link) 150 { 151 /* We don't use remove callback for this hash table */ 152 } 153 154 static hash_table_operations_t open_nodes_ops = { 139 155 .hash = open_nodes_hash, 140 .key_hash = open_nodes_key_hash, 141 .key_equal = open_nodes_key_equal, 142 .equal = NULL, 143 .remove_callback = NULL, 156 .compare = open_nodes_compare, 157 .remove_callback = open_nodes_remove_cb, 144 158 }; 145 159 … … 154 168 int ext4fs_global_init(void) 155 169 { 156 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) 170 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 171 OPEN_NODES_KEYS, &open_nodes_ops)) 157 172 return ENOMEM; 158 173 … … 300 315 301 316 /* Check if the node is not already open */ 302 node_key_t key= {303 .service_id= inst->service_id,304 .index= index317 unsigned long key[] = { 318 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id, 319 [OPEN_NODES_INODE_KEY] = index 305 320 }; 306 321 307 ht_link_t *already_open = hash_table_find(&open_nodes, &key);322 link_t *already_open = hash_table_find(&open_nodes, key); 308 323 ext4fs_node_t *enode = NULL; 309 324 if (already_open) { 310 enode = hash_table_get_inst (already_open, ext4fs_node_t, link);325 enode = hash_table_get_instance(already_open, ext4fs_node_t, link); 311 326 *rfn = enode->fs_node; 312 327 enode->references++; … … 349 364 enode->references = 1; 350 365 enode->fs_node = fs_node; 366 link_initialize(&enode->link); 351 367 352 368 fs_node->data = enode; 353 369 *rfn = fs_node; 354 370 355 hash_table_insert(&open_nodes, &enode->link);371 hash_table_insert(&open_nodes, key, &enode->link); 356 372 inst->open_nodes_count++; 357 373 … … 370 386 int ext4fs_node_put_core(ext4fs_node_t *enode) 371 387 { 372 hash_table_remove_item(&open_nodes, &enode->link); 388 unsigned long key[] = { 389 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id, 390 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index 391 }; 392 393 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 373 394 assert(enode->instance->open_nodes_count > 0); 374 395 enode->instance->open_nodes_count--; … … 477 498 enode->references = 1; 478 499 500 link_initialize(&enode->link); 501 502 unsigned long key[] = { 503 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id, 504 [OPEN_NODES_INODE_KEY] = inode_ref->index 505 }; 506 479 507 fibril_mutex_lock(&open_nodes_lock); 480 hash_table_insert(&open_nodes, &enode->link);508 hash_table_insert(&open_nodes, key, &enode->link); 481 509 fibril_mutex_unlock(&open_nodes_lock); 482 510 inst->open_nodes_count++;
Note:
See TracChangeset
for help on using the changeset viewer.