Changes in uspace/srv/fs/tmpfs/tmpfs_ops.c [4e00f87:b33870b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
r4e00f87 rb33870b 50 50 #include <sys/types.h> 51 51 #include <adt/hash_table.h> 52 #include <adt/hash.h>53 52 #include <as.h> 54 53 #include <libfs.h> … … 56 55 #define min(a, b) ((a) < (b) ? (a) : (b)) 57 56 #define max(a, b) ((a) > (b) ? (a) : (b)) 57 58 #define NODES_BUCKETS 256 58 59 59 60 /** All root nodes have index 0. */ … … 141 142 hash_table_t nodes; 142 143 143 /* 144 * Implementation of hash table interface for the nodes hash table. 145 */ 146 147 typedef struct { 148 service_id_t service_id; 149 fs_index_t index; 150 } node_key_t; 151 152 static 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 158 static 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 164 static 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 172 static void nodes_remove_callback(ht_link_t *item) 173 { 174 tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link); 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); 175 175 176 176 while (!list_empty(&nodep->cs_list)) { … … 192 192 193 193 /** TMPFS nodes hash table operations. */ 194 hash_table_op s_t nodes_ops = {194 hash_table_operations_t nodes_ops = { 195 195 .hash = nodes_hash, 196 .key_hash = nodes_key_hash, 197 .key_equal = nodes_key_equal, 198 .equal = NULL, 196 .compare = nodes_compare, 199 197 .remove_callback = nodes_remove_callback 200 198 }; … … 209 207 nodep->size = 0; 210 208 nodep->data = NULL; 209 link_initialize(&nodep->nh_link); 211 210 list_initialize(&nodep->cs_list); 212 211 } … … 221 220 bool tmpfs_init(void) 222 221 { 223 if (!hash_table_create(&nodes, 0, 0, &nodes_ops))222 if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops)) 224 223 return false; 225 224 … … 239 238 } 240 239 241 static 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 252 240 static void tmpfs_instance_done(service_id_t service_id) 253 { 254 hash_table_apply(&nodes, rm_service_id_nodes, &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); 255 253 } 256 254 … … 274 272 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 275 273 { 276 node_key_t key = { 277 .service_id = service_id, 278 .index = index 279 }; 280 281 ht_link_t *lnk = hash_table_find(&nodes, &key); 282 274 unsigned long key[] = { 275 [NODES_KEY_DEV] = service_id, 276 [NODES_KEY_INDEX] = index 277 }; 278 link_t *lnk = hash_table_find(&nodes, key); 283 279 if (lnk) { 284 280 tmpfs_node_t *nodep; 285 nodep = hash_table_get_inst (lnk, tmpfs_node_t, nh_link);281 nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link); 286 282 *rfn = FS_NODE(nodep); 287 283 } else { … … 335 331 336 332 /* Insert the new node into the nodes hash table. */ 337 hash_table_insert(&nodes, &nodep->nh_link); 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); 338 338 *rfn = FS_NODE(nodep); 339 339 return EOK; … … 346 346 assert(!nodep->lnkcnt); 347 347 assert(list_empty(&nodep->cs_list)); 348 349 hash_table_remove_item(&nodes, &nodep->nh_link); 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); 350 354 351 355 /* … … 472 476 * Lookup the respective TMPFS node. 473 477 */ 474 node_key_t key = {475 .service_id = service_id,476 .index = index477 };478 479 h t_link_t *hlp = hash_table_find(&nodes, &key);478 link_t *hlp; 479 unsigned long key[] = { 480 [NODES_KEY_DEV] = service_id, 481 [NODES_KEY_INDEX] = index 482 }; 483 hlp = hash_table_find(&nodes, key); 480 484 if (!hlp) 481 485 return ENOENT; 482 483 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t,nh_link);486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 487 nh_link); 484 488 485 489 /* … … 534 538 * Lookup the respective TMPFS node. 535 539 */ 536 node_key_t key = { 537 .service_id = service_id, 538 .index = index 539 }; 540 541 ht_link_t *hlp = hash_table_find(&nodes, &key); 542 540 link_t *hlp; 541 unsigned long key[] = { 542 [NODES_KEY_DEV] = service_id, 543 [NODES_KEY_INDEX] = index 544 }; 545 hlp = hash_table_find(&nodes, key); 543 546 if (!hlp) 544 547 return ENOENT; 545 546 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t,nh_link);548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 549 nh_link); 547 550 548 551 /* … … 597 600 * Lookup the respective TMPFS node. 598 601 */ 599 node_key_t key = { 600 .service_id = service_id, 601 .index = index 602 }; 603 604 ht_link_t *hlp = hash_table_find(&nodes, &key); 605 602 unsigned long key[] = { 603 [NODES_KEY_DEV] = service_id, 604 [NODES_KEY_INDEX] = index 605 }; 606 link_t *hlp = hash_table_find(&nodes, key); 606 607 if (!hlp) 607 608 return ENOENT; 608 tmpfs_node_t *nodep = hash_table_get_inst (hlp, tmpfs_node_t, nh_link);609 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link); 609 610 610 611 if (size == nodep->size) … … 635 636 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 636 637 { 637 node_key_t key = {638 .service_id = service_id,639 .index = index640 };641 642 h t_link_t *hlp = hash_table_find(&nodes, &key);638 link_t *hlp; 639 unsigned long key[] = { 640 [NODES_KEY_DEV] = service_id, 641 [NODES_KEY_INDEX] = index 642 }; 643 hlp = hash_table_find(&nodes, key); 643 644 if (!hlp) 644 645 return ENOENT; 645 tmpfs_node_t *nodep = hash_table_get_inst (hlp, tmpfs_node_t,646 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 646 647 nh_link); 647 648 return tmpfs_destroy_node(FS_NODE(nodep));
Note:
See TracChangeset
for help on using the changeset viewer.