Changes in uspace/srv/fs/ext2fs/ext2fs_ops.c [4e00f87:f73b291] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/ext2fs/ext2fs_ops.c
r4e00f87 rf73b291 49 49 #include <byteorder.h> 50 50 #include <adt/hash_table.h> 51 #include <adt/hash.h>52 51 #include <adt/list.h> 53 52 #include <assert.h> … … 63 62 #define EXT2FS_NODE(node) ((node) ? (ext2fs_node_t *) (node)->data : NULL) 64 63 #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 65 68 66 69 typedef struct ext2fs_instance { … … 75 78 ext2_inode_ref_t *inode_ref; 76 79 fs_node_t *fs_node; 77 ht_link_t link;80 link_t link; 78 81 unsigned int references; 79 82 } ext2fs_node_t; … … 119 122 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 120 123 121 /* 122 * Hash table interface for open nodes hash table 123 */ 124 125 typedef struct { 126 service_id_t service_id; 127 fs_index_t index; 128 } node_key_t; 129 130 static 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 136 static 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 146 static 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 155 static hash_table_ops_t open_nodes_ops = { 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 = { 156 153 .hash = open_nodes_hash, 157 .key_hash = open_nodes_key_hash, 158 .key_equal = open_nodes_key_equal, 159 .equal = NULL, 160 .remove_callback = NULL, 154 .compare = open_nodes_compare, 155 .remove_callback = open_nodes_remove_cb, 161 156 }; 162 157 … … 166 161 int ext2fs_global_init(void) 167 162 { 168 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 163 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 164 OPEN_NODES_KEYS, &open_nodes_ops)) { 169 165 return ENOMEM; 170 166 } … … 320 316 321 317 /* Check if the node is not already open */ 322 node_key_t key= {323 .service_id= inst->service_id,324 .index = index318 unsigned long key[] = { 319 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id, 320 [OPEN_NODES_INODE_KEY] = index, 325 321 }; 326 ht_link_t *already_open = hash_table_find(&open_nodes, &key);322 link_t *already_open = hash_table_find(&open_nodes, key); 327 323 328 324 if (already_open) { 329 enode = hash_table_get_inst (already_open, ext2fs_node_t, link);325 enode = hash_table_get_instance(already_open, ext2fs_node_t, link); 330 326 *rfn = enode->fs_node; 331 327 enode->references++; … … 361 357 enode->references = 1; 362 358 enode->fs_node = node; 359 link_initialize(&enode->link); 363 360 364 361 node->data = enode; 365 362 *rfn = node; 366 363 367 hash_table_insert(&open_nodes, &enode->link);364 hash_table_insert(&open_nodes, key, &enode->link); 368 365 inst->open_nodes_count++; 369 366 … … 411 408 int ext2fs_node_put_core(ext2fs_node_t *enode) 412 409 { 413 node_key_t key = { 414 .service_id = enode->instance->service_id, 415 .index = enode->inode_ref->index 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, 416 415 }; 417 418 hash_table_remove(&open_nodes, &key); 419 416 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 420 417 assert(enode->instance->open_nodes_count > 0); 421 418 enode->instance->open_nodes_count--; 422 419 423 intrc = ext2_filesystem_put_inode_ref(enode->inode_ref);420 rc = ext2_filesystem_put_inode_ref(enode->inode_ref); 424 421 if (rc != EOK) { 425 422 EXT2FS_DBG("ext2_filesystem_put_inode_ref failed");
Note:
See TracChangeset
for help on using the changeset viewer.