Changeset bc216a0 in mainline for uspace/srv/fs/cdfs/cdfs_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/cdfs/cdfs_ops.c
rb17518e rbc216a0 37 37 */ 38 38 39 #include "cdfs_ops.h" 39 40 #include <bool.h> 40 41 #include <adt/hash_table.h> 42 #include <adt/hash.h> 41 43 #include <malloc.h> 42 44 #include <mem.h> … … 50 52 #include "cdfs.h" 51 53 #include "cdfs_endian.h" 52 #include "cdfs_ops.h"53 54 54 55 /** Standard CD-ROM block size */ 55 56 #define BLOCK_SIZE 2048 56 57 57 /** Implicit node cache size 58 * 59 * More nodes can be actually cached if the files remain 60 * opended. 61 * 62 */ 63 #define NODE_CACHE_SIZE 200 64 65 #define NODES_KEY_SRVC 0 66 #define NODES_KEY_INDEX 1 58 #define NODE_CACHE_SIZE 200 67 59 68 60 /** All root nodes have index 0 */ … … 203 195 service_id_t service_id; /**< Service ID of block device */ 204 196 205 link_t nh_link;/**< Nodes hash table link */197 ht_link_t nh_link; /**< Nodes hash table link */ 206 198 cdfs_dentry_type_t type; /**< Dentry type */ 207 199 … … 224 216 static hash_table_t nodes; 225 217 226 static size_t nodes_key_hash(unsigned long key[]) 227 { 228 return key[NODES_KEY_INDEX]; 229 } 230 231 static size_t nodes_hash(const link_t *item) 232 { 233 cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link); 234 235 unsigned long key[] = { 236 [NODES_KEY_INDEX] = node->index 237 }; 238 239 return nodes_key_hash(key); 240 } 241 242 static bool nodes_match(unsigned long key[], size_t keys, const link_t *item) 243 { 244 cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link); 245 246 if (keys == 1) { 247 return (node->service_id == key[NODES_KEY_SRVC]); 248 } else { 249 assert(keys == 2); 250 return ((node->service_id == key[NODES_KEY_SRVC]) && 251 (node->index == key[NODES_KEY_INDEX])); 252 } 253 } 254 255 static bool nodes_equal(const link_t *item1, const link_t *item2) 256 { 257 cdfs_node_t *node1 = hash_table_get_instance(item1, cdfs_node_t, nh_link); 258 cdfs_node_t *node2 = hash_table_get_instance(item2, cdfs_node_t, nh_link); 259 260 return node1->service_id == node2->service_id 261 && node1->index == node2->index; 262 } 263 264 static void nodes_remove_callback(link_t *item) 265 { 266 cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link); 218 /* 219 * Hash table support functions. 220 */ 221 222 typedef struct { 223 service_id_t service_id; 224 fs_index_t index; 225 } ht_key_t; 226 227 static size_t nodes_key_hash(void *k) 228 { 229 ht_key_t *key = (ht_key_t*)k; 230 return hash_combine(key->service_id, key->index); 231 } 232 233 static size_t nodes_hash(const ht_link_t *item) 234 { 235 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 236 return hash_combine(node->service_id, node->index); 237 } 238 239 static bool nodes_key_equal(void *k, const ht_link_t *item) 240 { 241 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 242 ht_key_t *key = (ht_key_t*)k; 243 244 return key->service_id == node->service_id && key->index == node->index; 245 } 246 247 static void nodes_remove_callback(ht_link_t *item) 248 { 249 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 267 250 268 251 assert(node->type == CDFS_DIRECTORY); … … 283 266 .hash = nodes_hash, 284 267 .key_hash = nodes_key_hash, 285 . match = nodes_match,286 .equal = nodes_equal,268 .key_equal = nodes_key_equal, 269 .equal = 0, 287 270 .remove_callback = nodes_remove_callback 288 271 }; … … 291 274 fs_index_t index) 292 275 { 293 unsigned long key[]= {294 [NODES_KEY_SRVC] = service_id,295 [NODES_KEY_INDEX] = index276 ht_key_t key = { 277 .index = index, 278 .service_id = service_id 296 279 }; 297 280 298 link_t *link = hash_table_find(&nodes,key);281 ht_link_t *link = hash_table_find(&nodes, &key); 299 282 if (link) { 300 283 cdfs_node_t *node = 301 hash_table_get_inst ance(link, cdfs_node_t, nh_link);284 hash_table_get_inst(link, cdfs_node_t, nh_link); 302 285 303 286 *rfn = FS_NODE(node); … … 325 308 node->opened = 0; 326 309 327 link_initialize(&node->nh_link);328 310 list_initialize(&node->cs_list); 329 311 } … … 517 499 static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index) 518 500 { 519 unsigned long key[]= {520 [NODES_KEY_SRVC] = service_id,521 [NODES_KEY_INDEX] = index501 ht_key_t key = { 502 .index = index, 503 .service_id = service_id 522 504 }; 523 505 524 link_t *link = hash_table_find(&nodes,key);506 ht_link_t *link = hash_table_find(&nodes, &key); 525 507 if (link) { 526 508 cdfs_node_t *node = 527 hash_table_get_inst ance(link, cdfs_node_t, nh_link);509 hash_table_get_inst(link, cdfs_node_t, nh_link); 528 510 return FS_NODE(node); 529 511 } … … 811 793 } 812 794 795 static bool rm_service_id_nodes(ht_link_t *item, void *arg) 796 { 797 service_id_t service_id = *(service_id_t*)arg; 798 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 799 800 if (node->service_id == service_id) { 801 hash_table_remove_item(&nodes, &node->nh_link); 802 } 803 804 return true; 805 } 806 813 807 static void cdfs_instance_done(service_id_t service_id) 814 808 { 815 unsigned long key[] = { 816 [NODES_KEY_SRVC] = service_id 817 }; 818 819 hash_table_remove(&nodes, key, 1); 809 hash_table_apply(&nodes, rm_service_id_nodes, &service_id); 820 810 block_cache_fini(service_id); 821 811 block_fini(service_id); … … 831 821 size_t *rbytes) 832 822 { 833 unsigned long key[]= {834 [NODES_KEY_SRVC] = service_id,835 [NODES_KEY_INDEX] = index823 ht_key_t key = { 824 .index = index, 825 .service_id = service_id 836 826 }; 837 827 838 link_t *link = hash_table_find(&nodes,key);828 ht_link_t *link = hash_table_find(&nodes, &key); 839 829 if (link == NULL) 840 830 return ENOENT; 841 831 842 832 cdfs_node_t *node = 843 hash_table_get_inst ance(link, cdfs_node_t, nh_link);833 hash_table_get_inst(link, cdfs_node_t, nh_link); 844 834 845 835 if (!node->processed) { … … 921 911 } 922 912 923 static bool cache_remove_closed( link_t *item, void *arg)913 static bool cache_remove_closed(ht_link_t *item, void *arg) 924 914 { 925 915 size_t *premove_cnt = (size_t*)arg; … … 927 917 /* Some nodes were requested to be removed from the cache. */ 928 918 if (0 < *premove_cnt) { 929 cdfs_node_t *node = hash_table_get_inst ance(item, cdfs_node_t, nh_link);919 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 930 920 931 921 if (!node->opened) { … … 957 947 return EOK; 958 948 959 unsigned long key[]= {960 [NODES_KEY_SRVC] = service_id,961 [NODES_KEY_INDEX] = index949 ht_key_t key = { 950 .index = index, 951 .service_id = service_id 962 952 }; 963 953 964 link_t *link = hash_table_find(&nodes,key);954 ht_link_t *link = hash_table_find(&nodes, &key); 965 955 if (link == 0) 966 956 return ENOENT; 967 957 968 958 cdfs_node_t *node = 969 hash_table_get_inst ance(link, cdfs_node_t, nh_link);959 hash_table_get_inst(link, cdfs_node_t, nh_link); 970 960 971 961 assert(node->opened > 0); … … 1013 1003 bool cdfs_init(void) 1014 1004 { 1015 if (!hash_table_create(&nodes, 0, 2, &nodes_ops))1005 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 1016 1006 return false; 1017 1007
Note:
See TracChangeset
for help on using the changeset viewer.