Changeset 062d900 in mainline for uspace/srv/fs/ext2fs/ext2fs_ops.c
- Timestamp:
- 2012-10-09T11:49:43Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4e00f87
- Parents:
- 87e9392
- git-author:
- Adam Hraska <adam.hraska+hos@…> (2012-10-09 11:49:43)
- git-committer:
- Jakub Jermar <jakub@…> (2012-10-09 11:49:43)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/ext2fs/ext2fs_ops.c
r87e9392 r062d900 49 49 #include <byteorder.h> 50 50 #include <adt/hash_table.h> 51 #include <adt/hash.h> 51 52 #include <adt/list.h> 52 53 #include <assert.h> … … 62 63 #define EXT2FS_NODE(node) ((node) ? (ext2fs_node_t *) (node)->data : NULL) 63 64 #define EXT2FS_DBG(format, ...) {if (false) printf("ext2fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);} 64 #define OPEN_NODES_KEYS 265 #define OPEN_NODES_DEV_HANDLE_KEY 066 #define OPEN_NODES_INODE_KEY 167 #define OPEN_NODES_BUCKETS 25668 65 69 66 typedef struct ext2fs_instance { … … 78 75 ext2_inode_ref_t *inode_ref; 79 76 fs_node_t *fs_node; 80 link_t link;77 ht_link_t link; 81 78 unsigned int references; 82 79 } ext2fs_node_t; … … 122 119 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 123 120 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 = { 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 = { 153 156 .hash = open_nodes_hash, 154 .compare = open_nodes_compare, 155 .remove_callback = open_nodes_remove_cb, 157 .key_hash = open_nodes_key_hash, 158 .key_equal = open_nodes_key_equal, 159 .equal = 0, 160 .remove_callback = 0, 156 161 }; 157 162 … … 161 166 int ext2fs_global_init(void) 162 167 { 163 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 164 OPEN_NODES_KEYS, &open_nodes_ops)) { 168 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 165 169 return ENOMEM; 166 170 } … … 316 320 317 321 /* Check if the node is not already open */ 318 unsigned long key[]= {319 [OPEN_NODES_DEV_HANDLE_KEY]= inst->service_id,320 [OPEN_NODES_INODE_KEY] = index,322 node_key_t key = { 323 .service_id = inst->service_id, 324 .index = index 321 325 }; 322 link_t *already_open = hash_table_find(&open_nodes,key);326 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 323 327 324 328 if (already_open) { 325 enode = hash_table_get_inst ance(already_open, ext2fs_node_t, link);329 enode = hash_table_get_inst(already_open, ext2fs_node_t, link); 326 330 *rfn = enode->fs_node; 327 331 enode->references++; … … 357 361 enode->references = 1; 358 362 enode->fs_node = node; 359 link_initialize(&enode->link);360 363 361 364 node->data = enode; 362 365 *rfn = node; 363 366 364 hash_table_insert(&open_nodes, key,&enode->link);367 hash_table_insert(&open_nodes, &enode->link); 365 368 inst->open_nodes_count++; 366 369 … … 408 411 int ext2fs_node_put_core(ext2fs_node_t *enode) 409 412 { 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, 413 node_key_t key = { 414 .service_id = enode->instance->service_id, 415 .index = enode->inode_ref->index 415 416 }; 416 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 417 418 hash_table_remove(&open_nodes, &key); 419 417 420 assert(enode->instance->open_nodes_count > 0); 418 421 enode->instance->open_nodes_count--; 419 422 420 rc = ext2_filesystem_put_inode_ref(enode->inode_ref);423 int rc = ext2_filesystem_put_inode_ref(enode->inode_ref); 421 424 if (rc != EOK) { 422 425 EXT2FS_DBG("ext2_filesystem_put_inode_ref failed");
Note:
See TracChangeset
for help on using the changeset viewer.