Changeset bc216a0 in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.c
- Timestamp:
- 2012-08-07T22:13:44Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- da68871a
- Parents:
- b17518e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
rb17518e rbc216a0 50 50 #include <sys/types.h> 51 51 #include <adt/hash_table.h> 52 #include <adt/hash.h> 52 53 #include <as.h> 53 54 #include <libfs.h> … … 140 141 hash_table_t nodes; 141 142 142 #define NODES_KEY_DEV 0 143 #define NODES_KEY_INDEX 1 144 145 /* Implementation of hash table interface for the nodes hash table. */ 146 static size_t nodes_key_hash(unsigned long key[]) 147 { 148 /* Based on Effective Java, 2nd Edition. */ 149 size_t hash = 17; 150 hash = 37 * hash + key[NODES_KEY_DEV]; 151 hash = 37 * hash + key[NODES_KEY_INDEX]; 152 return hash; 153 } 154 155 static size_t nodes_hash(const link_t *item) 156 { 157 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, nh_link); 158 159 unsigned long key[] = { 160 [NODES_KEY_DEV] = nodep->service_id, 161 [NODES_KEY_INDEX] = nodep->index 162 }; 163 164 return nodes_key_hash(key); 165 } 166 167 static bool nodes_match(unsigned long key[], size_t keys, const link_t *item) 168 { 169 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 170 nh_link); 171 172 switch (keys) { 173 case 1: 174 return (nodep->service_id == key[NODES_KEY_DEV]); 175 case 2: 176 return ((nodep->service_id == key[NODES_KEY_DEV]) && 177 (nodep->index == key[NODES_KEY_INDEX])); 178 default: 179 assert((keys == 1) || (keys == 2)); 180 } 181 182 return 0; 183 } 184 185 static void nodes_remove_callback(link_t *item) 186 { 187 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 188 nh_link); 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); 189 175 190 176 while (!list_empty(&nodep->cs_list)) { … … 209 195 .hash = nodes_hash, 210 196 .key_hash = nodes_key_hash, 211 . match = nodes_match,197 .key_equal = nodes_key_equal, 212 198 .equal = 0, 213 199 .remove_callback = nodes_remove_callback … … 223 209 nodep->size = 0; 224 210 nodep->data = NULL; 225 link_initialize(&nodep->nh_link);226 211 list_initialize(&nodep->cs_list); 227 212 } … … 236 221 bool tmpfs_init(void) 237 222 { 238 if (!hash_table_create(&nodes, 0, 2, &nodes_ops))223 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 239 224 return false; 240 225 … … 254 239 } 255 240 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 256 252 static void tmpfs_instance_done(service_id_t service_id) 257 { 258 unsigned long key[] = { 259 [NODES_KEY_DEV] = service_id 260 }; 261 /* 262 * Here we are making use of one special feature of our hash table 263 * implementation, which allows to remove more items based on a partial 264 * key match. In the following, we are going to remove all nodes 265 * matching our device handle. The nodes_remove_callback() function will 266 * take care of resource deallocation. 267 */ 268 hash_table_remove(&nodes, key, 1); 253 { 254 hash_table_apply(&nodes, rm_service_id_nodes, &service_id); 269 255 } 270 256 … … 288 274 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 289 275 { 290 unsigned long key[]= {291 [NODES_KEY_DEV]= service_id,292 [NODES_KEY_INDEX]= index276 node_key_t key = { 277 .service_id = service_id, 278 .index = index 293 279 }; 294 link_t *lnk = hash_table_find(&nodes, key); 280 281 ht_link_t *lnk = hash_table_find(&nodes, &key); 282 295 283 if (lnk) { 296 284 tmpfs_node_t *nodep; 297 nodep = hash_table_get_inst ance(lnk, tmpfs_node_t, nh_link);285 nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link); 298 286 *rfn = FS_NODE(nodep); 299 287 } else { … … 358 346 assert(!nodep->lnkcnt); 359 347 assert(list_empty(&nodep->cs_list)); 360 361 unsigned long key[] = { 362 [NODES_KEY_DEV] = nodep->service_id, 363 [NODES_KEY_INDEX] = nodep->index 364 }; 365 hash_table_remove(&nodes, key, 2); 348 349 hash_table_remove_item(&nodes, &nodep->nh_link); 366 350 367 351 /* … … 488 472 * Lookup the respective TMPFS node. 489 473 */ 490 link_t *hlp; 491 unsigned long key[] = { 492 [NODES_KEY_DEV] = service_id, 493 [NODES_KEY_INDEX] = index 474 node_key_t key = { 475 .service_id = service_id, 476 .index = index 494 477 }; 495 hlp = hash_table_find(&nodes, key); 478 479 ht_link_t *hlp = hash_table_find(&nodes, &key); 496 480 if (!hlp) 497 481 return ENOENT; 498 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,499 482 483 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 500 484 501 485 /* … … 550 534 * Lookup the respective TMPFS node. 551 535 */ 552 link_t *hlp; 553 unsigned long key[] = { 554 [NODES_KEY_DEV] = service_id, 555 [NODES_KEY_INDEX] = index 536 node_key_t key = { 537 .service_id = service_id, 538 .index = index 556 539 }; 557 hlp = hash_table_find(&nodes, key); 540 541 ht_link_t *hlp = hash_table_find(&nodes, &key); 542 558 543 if (!hlp) 559 544 return ENOENT; 560 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,561 545 546 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 562 547 563 548 /* … … 612 597 * Lookup the respective TMPFS node. 613 598 */ 614 unsigned long key[]= {615 [NODES_KEY_DEV]= service_id,616 [NODES_KEY_INDEX]= index599 node_key_t key = { 600 .service_id = service_id, 601 .index = index 617 602 }; 618 link_t *hlp = hash_table_find(&nodes, key); 603 604 ht_link_t *hlp = hash_table_find(&nodes, &key); 605 619 606 if (!hlp) 620 607 return ENOENT; 621 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t, nh_link);608 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 622 609 623 610 if (size == nodep->size) … … 648 635 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 649 636 { 650 link_t *hlp; 651 unsigned long key[] = { 652 [NODES_KEY_DEV] = service_id, 653 [NODES_KEY_INDEX] = index 637 node_key_t key = { 638 .service_id = service_id, 639 .index = index 654 640 }; 655 hlp = hash_table_find(&nodes, key); 641 642 ht_link_t *hlp = hash_table_find(&nodes, &key); 656 643 if (!hlp) 657 644 return ENOENT; 658 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t,645 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, 659 646 nh_link); 660 647 return tmpfs_destroy_node(FS_NODE(nodep));
Note:
See TracChangeset
for help on using the changeset viewer.