Changeset bc216a0 in mainline for uspace/srv/fs/ext2fs/ext2fs_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/ext2fs/ext2fs_ops.c
rb17518e rbc216a0 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 65 68 66 typedef struct ext2fs_instance { … … 77 75 ext2_inode_ref_t *inode_ref; 78 76 fs_node_t *fs_node; 79 link_t link;77 ht_link_t link; 80 78 unsigned int references; 81 79 } ext2fs_node_t; … … 121 119 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 122 120 123 /* Hash table interface for open nodes hash table */ 124 static size_t open_nodes_key_hash(unsigned long key[]) 125 { 126 /* Hash construction recommended in Effective Java, 2nd Edition. */ 127 size_t hash = 17; 128 hash = 31 * hash + key[OPEN_NODES_DEV_HANDLE_KEY]; 129 hash = 31 * hash + key[OPEN_NODES_INODE_KEY]; 130 return hash; 131 } 132 133 static size_t open_nodes_hash(const link_t *item) 134 { 135 ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link); 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); 136 139 137 140 assert(enode->instance); 138 141 assert(enode->inode_ref); 139 142 140 unsigned long key[] = { 141 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id, 142 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index, 143 }; 144 145 return open_nodes_key_hash(key); 146 } 147 148 static bool open_nodes_match(unsigned long key[], size_t keys, 149 const link_t *item) 150 { 151 ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link); 152 assert(keys > 0); 153 if (enode->instance->service_id != 154 ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) { 155 return false; 156 } 157 if (keys == 1) { 158 return true; 159 } 160 assert(keys == 2); 161 return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]); 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; 162 153 } 163 154 … … 165 156 .hash = open_nodes_hash, 166 157 .key_hash = open_nodes_key_hash, 167 . match = open_nodes_match,158 .key_equal = open_nodes_key_equal, 168 159 .equal = 0, 169 160 .remove_callback = 0, … … 175 166 int ext2fs_global_init(void) 176 167 { 177 if (!hash_table_create(&open_nodes, 0, OPEN_NODES_KEYS, &open_nodes_ops)) {168 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 178 169 return ENOMEM; 179 170 } … … 329 320 330 321 /* Check if the node is not already open */ 331 unsigned long key[]= {332 [OPEN_NODES_DEV_HANDLE_KEY]= inst->service_id,333 [OPEN_NODES_INODE_KEY] = index,322 node_key_t key = { 323 .service_id = inst->service_id, 324 .index = index 334 325 }; 335 link_t *already_open = hash_table_find(&open_nodes,key);326 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 336 327 337 328 if (already_open) { 338 enode = hash_table_get_inst ance(already_open, ext2fs_node_t, link);329 enode = hash_table_get_inst(already_open, ext2fs_node_t, link); 339 330 *rfn = enode->fs_node; 340 331 enode->references++; … … 370 361 enode->references = 1; 371 362 enode->fs_node = node; 372 link_initialize(&enode->link);373 363 374 364 node->data = enode; … … 421 411 int ext2fs_node_put_core(ext2fs_node_t *enode) 422 412 { 423 int rc; 424 425 unsigned long key[] = { 426 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id, 427 [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 428 416 }; 429 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 417 418 hash_table_remove(&open_nodes, &key); 419 430 420 assert(enode->instance->open_nodes_count > 0); 431 421 enode->instance->open_nodes_count--; 432 422 433 rc = ext2_filesystem_put_inode_ref(enode->inode_ref);423 int rc = ext2_filesystem_put_inode_ref(enode->inode_ref); 434 424 if (rc != EOK) { 435 425 EXT2FS_DBG("ext2_filesystem_put_inode_ref failed");
Note:
See TracChangeset
for help on using the changeset viewer.