Changeset b800b0e in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.c
- Timestamp:
- 2012-10-23T13:16:49Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6ecf5b8
- Parents:
- 32b3a12 (diff), b2ac3998 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
r32b3a12 rb800b0e 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> … … 55 56 #define min(a, b) ((a) < (b) ? (a) : (b)) 56 57 #define max(a, b) ((a) > (b) ? (a) : (b)) 57 58 #define NODES_BUCKETS 25659 58 60 59 /** All root nodes have index 0. */ … … 142 141 hash_table_t nodes; 143 142 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); 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); 175 175 176 176 while (!list_empty(&nodep->cs_list)) { … … 192 192 193 193 /** TMPFS nodes hash table operations. */ 194 hash_table_op erations_t nodes_ops = {194 hash_table_ops_t nodes_ops = { 195 195 .hash = nodes_hash, 196 .compare = nodes_compare, 196 .key_hash = nodes_key_hash, 197 .key_equal = nodes_key_equal, 198 .equal = NULL, 197 199 .remove_callback = nodes_remove_callback 198 200 }; … … 207 209 nodep->size = 0; 208 210 nodep->data = NULL; 209 link_initialize(&nodep->nh_link);210 211 list_initialize(&nodep->cs_list); 211 212 } … … 220 221 bool tmpfs_init(void) 221 222 { 222 if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))223 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 223 224 return false; 224 225 … … 238 239 } 239 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 240 252 static void tmpfs_instance_done(service_id_t 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); 253 { 254 hash_table_apply(&nodes, rm_service_id_nodes, &service_id); 253 255 } 254 256 … … 272 274 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 273 275 { 274 unsigned long key[]= {275 [NODES_KEY_DEV]= service_id,276 [NODES_KEY_INDEX]= index276 node_key_t key = { 277 .service_id = service_id, 278 .index = index 277 279 }; 278 link_t *lnk = hash_table_find(&nodes, key); 280 281 ht_link_t *lnk = hash_table_find(&nodes, &key); 282 279 283 if (lnk) { 280 284 tmpfs_node_t *nodep; 281 nodep = hash_table_get_inst ance(lnk, tmpfs_node_t, nh_link);285 nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link); 282 286 *rfn = FS_NODE(nodep); 283 287 } else { … … 331 335 332 336 /* Insert the new node into the nodes hash table. */ 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); 337 hash_table_insert(&nodes, &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 unsigned long key[] = { 350 [NODES_KEY_DEV] = nodep->service_id, 351 [NODES_KEY_INDEX] = nodep->index 352 }; 353 hash_table_remove(&nodes, key, 2); 348 349 hash_table_remove_item(&nodes, &nodep->nh_link); 354 350 355 351 /* … … 476 472 * Lookup the respective TMPFS node. 477 473 */ 478 link_t *hlp; 479 unsigned long key[] = { 480 [NODES_KEY_DEV] = service_id, 481 [NODES_KEY_INDEX] = index 474 node_key_t key = { 475 .service_id = service_id, 476 .index = index 482 477 }; 483 hlp = hash_table_find(&nodes, key); 478 479 ht_link_t *hlp = hash_table_find(&nodes, &key); 484 480 if (!hlp) 485 481 return ENOENT; 486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,487 482 483 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 488 484 489 485 /* … … 538 534 * Lookup the respective TMPFS node. 539 535 */ 540 link_t *hlp; 541 unsigned long key[] = { 542 [NODES_KEY_DEV] = service_id, 543 [NODES_KEY_INDEX] = index 536 node_key_t key = { 537 .service_id = service_id, 538 .index = index 544 539 }; 545 hlp = hash_table_find(&nodes, key); 540 541 ht_link_t *hlp = hash_table_find(&nodes, &key); 542 546 543 if (!hlp) 547 544 return ENOENT; 548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,549 545 546 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 550 547 551 548 /* … … 600 597 * Lookup the respective TMPFS node. 601 598 */ 602 unsigned long key[]= {603 [NODES_KEY_DEV]= service_id,604 [NODES_KEY_INDEX]= index599 node_key_t key = { 600 .service_id = service_id, 601 .index = index 605 602 }; 606 link_t *hlp = hash_table_find(&nodes, key); 603 604 ht_link_t *hlp = hash_table_find(&nodes, &key); 605 607 606 if (!hlp) 608 607 return ENOENT; 609 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); 610 609 611 610 if (size == nodep->size) … … 636 635 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 637 636 { 638 link_t *hlp; 639 unsigned long key[] = { 640 [NODES_KEY_DEV] = service_id, 641 [NODES_KEY_INDEX] = index 637 node_key_t key = { 638 .service_id = service_id, 639 .index = index 642 640 }; 643 hlp = hash_table_find(&nodes, key); 641 642 ht_link_t *hlp = hash_table_find(&nodes, &key); 644 643 if (!hlp) 645 644 return ENOENT; 646 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, 647 646 nh_link); 648 647 return tmpfs_destroy_node(FS_NODE(nodep));
Note:
See TracChangeset
for help on using the changeset viewer.