Changes in uspace/srv/fs/fat/fat_idx.c [ebddd71:4e00f87] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_idx.c
rebddd71 r4e00f87 41 41 #include <str.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <adt/list.h> 44 45 #include <assert.h> … … 58 59 */ 59 60 typedef struct { 60 link_t 61 service_id_t 61 link_t link; 62 service_id_t service_id; 62 63 63 64 /** Next unassigned index. */ … … 97 98 return u; 98 99 } 99 100 100 101 if (lock) 101 102 fibril_mutex_unlock(&unused_lock); … … 113 114 static hash_table_t up_hash; 114 115 115 #define UPH_BUCKETS_LOG 12 116 #define UPH_BUCKETS (1 << UPH_BUCKETS_LOG) 117 118 #define UPH_SID_KEY 0 119 #define UPH_PFC_KEY 1 120 #define UPH_PDI_KEY 2 121 122 static hash_index_t pos_hash(unsigned long key[]) 123 { 124 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 125 fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY]; 126 unsigned pdi = (unsigned)key[UPH_PDI_KEY]; 127 128 hash_index_t h; 129 130 /* 131 * The least significant half of all bits are the least significant bits 132 * of the parent node's first cluster. 133 * 134 * The least significant half of the most significant half of all bits 135 * are the least significant bits of the node's dentry index within the 136 * parent directory node. 137 * 138 * The most significant half of the most significant half of all bits 139 * are the least significant bits of the device handle. 140 */ 141 h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1); 142 h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 143 (UPH_BUCKETS_LOG / 2); 144 h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 145 (3 * (UPH_BUCKETS_LOG / 4)); 146 147 return h; 148 } 149 150 static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item) 151 { 152 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 116 typedef struct { 117 service_id_t service_id; 153 118 fat_cluster_t pfc; 154 119 unsigned pdi; 155 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 156 157 switch (keys) { 158 case 1: 159 return (service_id == fidx->service_id); 160 case 3: 161 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 162 pdi = (unsigned) key[UPH_PDI_KEY]; 163 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 164 (pdi == fidx->pdi); 165 default: 166 assert((keys == 1) || (keys == 3)); 167 } 168 169 return 0; 170 } 171 172 static void pos_remove_callback(link_t *item) 173 { 174 /* nothing to do */ 175 } 176 177 static hash_table_operations_t uph_ops = { 120 } pos_key_t; 121 122 static inline size_t pos_key_hash(void *key) 123 { 124 pos_key_t *pos = (pos_key_t*)key; 125 126 size_t hash = 0; 127 hash = hash_combine(pos->pfc, pos->pdi); 128 return hash_combine(hash, pos->service_id); 129 } 130 131 static size_t pos_hash(const ht_link_t *item) 132 { 133 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 134 135 pos_key_t pkey = { 136 .service_id = fidx->service_id, 137 .pfc = fidx->pfc, 138 .pdi = fidx->pdi, 139 }; 140 141 return pos_key_hash(&pkey); 142 } 143 144 static bool pos_key_equal(void *key, const ht_link_t *item) 145 { 146 pos_key_t *pos = (pos_key_t*)key; 147 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 148 149 return pos->service_id == fidx->service_id 150 && pos->pdi == fidx->pdi 151 && pos->pfc == fidx->pfc; 152 } 153 154 static hash_table_ops_t uph_ops = { 178 155 .hash = pos_hash, 179 .compare = pos_compare, 180 .remove_callback = pos_remove_callback, 156 .key_hash = pos_key_hash, 157 .key_equal = pos_key_equal, 158 .equal = NULL, 159 .remove_callback = NULL, 181 160 }; 182 161 … … 187 166 static hash_table_t ui_hash; 188 167 189 #define UIH_BUCKETS_LOG 12 190 #define UIH_BUCKETS (1 << UIH_BUCKETS_LOG) 191 192 #define UIH_SID_KEY 0 193 #define UIH_INDEX_KEY 1 194 195 static hash_index_t idx_hash(unsigned long key[]) 196 { 197 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 198 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 199 200 hash_index_t h; 201 202 h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1); 203 h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) << 204 (UIH_BUCKETS_LOG / 2); 205 206 return h; 207 } 208 209 static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) 210 { 211 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 168 typedef struct { 169 service_id_t service_id; 212 170 fs_index_t index; 213 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 214 215 switch (keys) { 216 case 1: 217 return (service_id == fidx->service_id); 218 case 2: 219 index = (fs_index_t) key[UIH_INDEX_KEY]; 220 return (service_id == fidx->service_id) && 221 (index == fidx->index); 222 default: 223 assert((keys == 1) || (keys == 2)); 224 } 225 226 return 0; 227 } 228 229 static void idx_remove_callback(link_t *item) 230 { 231 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 171 } idx_key_t; 172 173 static size_t idx_key_hash(void *key_arg) 174 { 175 idx_key_t *key = (idx_key_t*)key_arg; 176 return hash_combine(key->service_id, key->index); 177 } 178 179 static size_t idx_hash(const ht_link_t *item) 180 { 181 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 182 return hash_combine(fidx->service_id, fidx->index); 183 } 184 185 static bool idx_key_equal(void *key_arg, const ht_link_t *item) 186 { 187 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 188 idx_key_t *key = (idx_key_t*)key_arg; 189 190 return key->index == fidx->index && key->service_id == fidx->service_id; 191 } 192 193 static void idx_remove_callback(ht_link_t *item) 194 { 195 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 232 196 233 197 free(fidx); 234 198 } 235 199 236 static hash_table_op erations_t uih_ops = {200 static hash_table_ops_t uih_ops = { 237 201 .hash = idx_hash, 238 .compare = idx_compare, 202 .key_hash = idx_key_hash, 203 .key_equal = idx_key_equal, 204 .equal = NULL, 239 205 .remove_callback = idx_remove_callback, 240 206 }; … … 377 343 } 378 344 379 link_initialize(&fidx->uph_link);380 link_initialize(&fidx->uih_link);381 345 fibril_mutex_initialize(&fidx->lock); 382 346 fidx->service_id = service_id; … … 401 365 } 402 366 403 unsigned long ikey[] = { 404 [UIH_SID_KEY] = service_id, 405 [UIH_INDEX_KEY] = fidx->index, 406 }; 407 408 hash_table_insert(&ui_hash, ikey, &fidx->uih_link); 367 hash_table_insert(&ui_hash, &fidx->uih_link); 409 368 fibril_mutex_lock(&fidx->lock); 410 369 fibril_mutex_unlock(&used_lock); … … 418 377 { 419 378 fat_idx_t *fidx; 420 link_t *l; 421 unsigned long pkey[]= {422 [UPH_SID_KEY]= service_id,423 [UPH_PFC_KEY]= pfc,424 [UPH_PDI_KEY]= pdi,379 380 pos_key_t pos_key = { 381 .service_id = service_id, 382 .pfc = pfc, 383 .pdi = pdi, 425 384 }; 426 385 427 386 fibril_mutex_lock(&used_lock); 428 l = hash_table_find(&up_hash, pkey);387 ht_link_t *l = hash_table_find(&up_hash, &pos_key); 429 388 if (l) { 430 fidx = hash_table_get_inst ance(l, fat_idx_t, uph_link);389 fidx = hash_table_get_inst(l, fat_idx_t, uph_link); 431 390 } else { 432 391 int rc; … … 438 397 } 439 398 440 unsigned long ikey[] = {441 [UIH_SID_KEY] = service_id,442 [UIH_INDEX_KEY] = fidx->index,443 };444 445 399 fidx->pfc = pfc; 446 400 fidx->pdi = pdi; 447 401 448 hash_table_insert(&up_hash, pkey,&fidx->uph_link);449 hash_table_insert(&ui_hash, ikey,&fidx->uih_link);402 hash_table_insert(&up_hash, &fidx->uph_link); 403 hash_table_insert(&ui_hash, &fidx->uih_link); 450 404 } 451 405 fibril_mutex_lock(&fidx->lock); … … 457 411 void fat_idx_hashin(fat_idx_t *idx) 458 412 { 459 unsigned long pkey[] = { 460 [UPH_SID_KEY] = idx->service_id, 461 [UPH_PFC_KEY] = idx->pfc, 462 [UPH_PDI_KEY] = idx->pdi, 463 }; 464 465 fibril_mutex_lock(&used_lock); 466 hash_table_insert(&up_hash, pkey, &idx->uph_link); 413 fibril_mutex_lock(&used_lock); 414 hash_table_insert(&up_hash, &idx->uph_link); 467 415 fibril_mutex_unlock(&used_lock); 468 416 } … … 470 418 void fat_idx_hashout(fat_idx_t *idx) 471 419 { 472 unsigned long pkey[] = { 473 [UPH_SID_KEY] = idx->service_id, 474 [UPH_PFC_KEY] = idx->pfc, 475 [UPH_PDI_KEY] = idx->pdi, 476 }; 477 478 fibril_mutex_lock(&used_lock); 479 hash_table_remove(&up_hash, pkey, 3); 420 fibril_mutex_lock(&used_lock); 421 hash_table_remove_item(&up_hash, &idx->uph_link); 480 422 fibril_mutex_unlock(&used_lock); 481 423 } … … 485 427 { 486 428 fat_idx_t *fidx = NULL; 487 link_t *l; 488 unsigned long ikey[]= {489 [UIH_SID_KEY]= service_id,490 [UIH_INDEX_KEY]= index,429 430 idx_key_t idx_key = { 431 .service_id = service_id, 432 .index = index, 491 433 }; 492 434 493 435 fibril_mutex_lock(&used_lock); 494 l = hash_table_find(&ui_hash, ikey);436 ht_link_t *l = hash_table_find(&ui_hash, &idx_key); 495 437 if (l) { 496 fidx = hash_table_get_inst ance(l, fat_idx_t, uih_link);438 fidx = hash_table_get_inst(l, fat_idx_t, uih_link); 497 439 fibril_mutex_lock(&fidx->lock); 498 440 } … … 508 450 void fat_idx_destroy(fat_idx_t *idx) 509 451 { 510 unsigned long ikey[]= {511 [UIH_SID_KEY]= idx->service_id,512 [UIH_INDEX_KEY]= idx->index,452 idx_key_t idx_key = { 453 .service_id = idx->service_id, 454 .index = idx->index, 513 455 }; 514 service_id_t service_id = idx->service_id;515 fs_index_t index = idx->index;516 456 517 457 assert(idx->pfc == FAT_CLST_RES0); … … 523 463 * the index hash only. 524 464 */ 525 hash_table_remove(&ui_hash, ikey, 2);465 hash_table_remove(&ui_hash, &idx_key); 526 466 fibril_mutex_unlock(&used_lock); 527 467 /* Release the VFS index. */ 528 fat_index_free( service_id,index);468 fat_index_free(idx_key.service_id, idx_key.index); 529 469 /* The index structure itself is freed in idx_remove_callback(). */ 530 470 } … … 532 472 int fat_idx_init(void) 533 473 { 534 if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))474 if (!hash_table_create(&up_hash, 0, 0, &uph_ops)) 535 475 return ENOMEM; 536 if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {476 if (!hash_table_create(&ui_hash, 0, 0, &uih_ops)) { 537 477 hash_table_destroy(&up_hash); 538 478 return ENOMEM; … … 544 484 { 545 485 /* We assume the hash tables are empty. */ 486 assert(hash_table_empty(&up_hash) && hash_table_empty(&ui_hash)); 546 487 hash_table_destroy(&up_hash); 547 488 hash_table_destroy(&ui_hash); … … 568 509 } 569 510 511 static bool rm_pos_service_id(ht_link_t *item, void *arg) 512 { 513 service_id_t service_id = *(service_id_t*)arg; 514 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 515 516 if (fidx->service_id == service_id) { 517 hash_table_remove_item(&up_hash, item); 518 } 519 520 return true; 521 } 522 523 static bool rm_idx_service_id(ht_link_t *item, void *arg) 524 { 525 service_id_t service_id = *(service_id_t*)arg; 526 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 527 528 if (fidx->service_id == service_id) { 529 hash_table_remove_item(&ui_hash, item); 530 } 531 532 return true; 533 } 534 570 535 void fat_idx_fini_by_service_id(service_id_t service_id) 571 536 { 572 unsigned long ikey[] = {573 [UIH_SID_KEY] = service_id574 };575 unsigned long pkey[] = {576 [UPH_SID_KEY] = service_id577 };578 579 537 /* 580 538 * Remove this instance's index structure from up_hash and ui_hash. … … 583 541 */ 584 542 fibril_mutex_lock(&used_lock); 585 hash_table_ remove(&up_hash, pkey, 1);586 hash_table_ remove(&ui_hash, ikey, 1);543 hash_table_apply(&up_hash, rm_pos_service_id, &service_id); 544 hash_table_apply(&ui_hash, rm_idx_service_id, &service_id); 587 545 fibril_mutex_unlock(&used_lock); 588 546
Note:
See TracChangeset
for help on using the changeset viewer.