Changes in uspace/srv/fs/fat/fat_idx.c [c7bbf029:ebddd71] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_idx.c
rc7bbf029 rebddd71 59 59 typedef struct { 60 60 link_t link; 61 devmap_handle_t devmap_handle;61 service_id_t service_id; 62 62 63 63 /** Next unassigned index. */ 64 fs_index_t 64 fs_index_t next; 65 65 /** Number of remaining unassigned indices. */ 66 uint64_t 66 uint64_t remaining; 67 67 68 68 /** Sorted list of intervals of freed indices. */ 69 li nk_t freed_head;69 list_t freed_list; 70 70 } unused_t; 71 71 … … 74 74 75 75 /** List of unused structures. */ 76 static LIST_INITIALIZE(unused_ head);77 78 static void unused_initialize(unused_t *u, devmap_handle_t devmap_handle)76 static LIST_INITIALIZE(unused_list); 77 78 static void unused_initialize(unused_t *u, service_id_t service_id) 79 79 { 80 80 link_initialize(&u->link); 81 u-> devmap_handle = devmap_handle;81 u->service_id = service_id; 82 82 u->next = 0; 83 83 u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; 84 list_initialize(&u->freed_ head);85 } 86 87 static unused_t *unused_find( devmap_handle_t devmap_handle, bool lock)84 list_initialize(&u->freed_list); 85 } 86 87 static unused_t *unused_find(service_id_t service_id, bool lock) 88 88 { 89 89 unused_t *u; 90 link_t *l;91 90 92 91 if (lock) 93 92 fibril_mutex_lock(&unused_lock); 94 for (l = unused_head.next; l != &unused_head; l = l->next) { 93 94 list_foreach(unused_list, l) { 95 95 u = list_get_instance(l, unused_t, link); 96 if (u-> devmap_handle == devmap_handle)96 if (u->service_id == service_id) 97 97 return u; 98 98 } 99 99 100 if (lock) 100 101 fibril_mutex_unlock(&unused_lock); … … 107 108 /** 108 109 * Global hash table of all used fat_idx_t structures. 109 * The index structures are hashed by the devmap_handle, parent node's first110 * The index structures are hashed by the service_id, parent node's first 110 111 * cluster and index within the parent directory. 111 112 */ … … 115 116 #define UPH_BUCKETS (1 << UPH_BUCKETS_LOG) 116 117 117 #define UPH_ DH_KEY 0118 #define UPH_SID_KEY 0 118 119 #define UPH_PFC_KEY 1 119 120 #define UPH_PDI_KEY 2 … … 121 122 static hash_index_t pos_hash(unsigned long key[]) 122 123 { 123 devmap_handle_t devmap_handle = (devmap_handle_t)key[UPH_DH_KEY];124 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 124 125 fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY]; 125 126 unsigned pdi = (unsigned)key[UPH_PDI_KEY]; … … 141 142 h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 142 143 (UPH_BUCKETS_LOG / 2); 143 h |= ( devmap_handle& ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<144 h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 144 145 (3 * (UPH_BUCKETS_LOG / 4)); 145 146 … … 149 150 static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item) 150 151 { 151 devmap_handle_t devmap_handle = (devmap_handle_t)key[UPH_DH_KEY];152 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 152 153 fat_cluster_t pfc; 153 154 unsigned pdi; … … 156 157 switch (keys) { 157 158 case 1: 158 return ( devmap_handle == fidx->devmap_handle);159 return (service_id == fidx->service_id); 159 160 case 3: 160 161 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 161 162 pdi = (unsigned) key[UPH_PDI_KEY]; 162 return ( devmap_handle == fidx->devmap_handle) && (pfc == fidx->pfc) &&163 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 163 164 (pdi == fidx->pdi); 164 165 default: … … 182 183 /** 183 184 * Global hash table of all used fat_idx_t structures. 184 * The index structures are hashed by the devmap_handleand index.185 * The index structures are hashed by the service_id and index. 185 186 */ 186 187 static hash_table_t ui_hash; … … 189 190 #define UIH_BUCKETS (1 << UIH_BUCKETS_LOG) 190 191 191 #define UIH_ DH_KEY 0192 #define UIH_SID_KEY 0 192 193 #define UIH_INDEX_KEY 1 193 194 194 195 static hash_index_t idx_hash(unsigned long key[]) 195 196 { 196 devmap_handle_t devmap_handle = (devmap_handle_t)key[UIH_DH_KEY];197 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 197 198 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 198 199 199 200 hash_index_t h; 200 201 201 h = devmap_handle& ((1 << (UIH_BUCKETS_LOG / 2)) - 1);202 h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1); 202 203 h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) << 203 204 (UIH_BUCKETS_LOG / 2); … … 208 209 static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) 209 210 { 210 devmap_handle_t devmap_handle = (devmap_handle_t)key[UIH_DH_KEY];211 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 211 212 fs_index_t index; 212 213 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); … … 214 215 switch (keys) { 215 216 case 1: 216 return ( devmap_handle == fidx->devmap_handle);217 return (service_id == fidx->service_id); 217 218 case 2: 218 219 index = (fs_index_t) key[UIH_INDEX_KEY]; 219 return ( devmap_handle == fidx->devmap_handle) &&220 return (service_id == fidx->service_id) && 220 221 (index == fidx->index); 221 222 default: … … 240 241 241 242 /** Allocate a VFS index which is not currently in use. */ 242 static bool fat_index_alloc( devmap_handle_t devmap_handle, fs_index_t *index)243 static bool fat_index_alloc(service_id_t service_id, fs_index_t *index) 243 244 { 244 245 unused_t *u; 245 246 246 247 assert(index); 247 u = unused_find( devmap_handle, true);248 u = unused_find(service_id, true); 248 249 if (!u) 249 250 return false; 250 251 251 if (list_empty(&u->freed_ head)) {252 if (list_empty(&u->freed_list)) { 252 253 if (u->remaining) { 253 254 /* … … 262 263 } else { 263 264 /* There are some freed indices which we can reuse. */ 264 freed_t *f = list_get_instance( u->freed_head.next, freed_t,265 link);265 freed_t *f = list_get_instance(list_first(&u->freed_list), 266 freed_t, link); 266 267 *index = f->first; 267 268 if (f->first++ == f->last) { … … 302 303 303 304 /** Free a VFS index, which is no longer in use. */ 304 static void fat_index_free( devmap_handle_t devmap_handle, fs_index_t index)305 static void fat_index_free(service_id_t service_id, fs_index_t index) 305 306 { 306 307 unused_t *u; 307 308 308 u = unused_find( devmap_handle, true);309 u = unused_find(service_id, true); 309 310 assert(u); 310 311 … … 320 321 link_t *lnk; 321 322 freed_t *n; 322 for (lnk = u->freed_ head.next; lnk != &u->freed_head;323 for (lnk = u->freed_list.head.next; lnk != &u->freed_list.head; 323 324 lnk = lnk->next) { 324 325 freed_t *f = list_get_instance(lnk, freed_t, link); 325 326 if (f->first == index + 1) { 326 327 f->first--; 327 if (lnk->prev != &u->freed_ head)328 if (lnk->prev != &u->freed_list.head) 328 329 try_coalesce_intervals(lnk->prev, lnk, 329 330 lnk); … … 333 334 if (f->last == index - 1) { 334 335 f->last++; 335 if (lnk->next != &u->freed_ head)336 if (lnk->next != &u->freed_list.head) 336 337 try_coalesce_intervals(lnk, lnk->next, 337 338 lnk); … … 359 360 n->first = index; 360 361 n->last = index; 361 list_append(&n->link, &u->freed_ head);362 list_append(&n->link, &u->freed_list); 362 363 } 363 364 fibril_mutex_unlock(&unused_lock); 364 365 } 365 366 366 static int fat_idx_create(fat_idx_t **fidxp, devmap_handle_t devmap_handle)367 static int fat_idx_create(fat_idx_t **fidxp, service_id_t service_id) 367 368 { 368 369 fat_idx_t *fidx; … … 371 372 if (!fidx) 372 373 return ENOMEM; 373 if (!fat_index_alloc( devmap_handle, &fidx->index)) {374 if (!fat_index_alloc(service_id, &fidx->index)) { 374 375 free(fidx); 375 376 return ENOSPC; … … 379 380 link_initialize(&fidx->uih_link); 380 381 fibril_mutex_initialize(&fidx->lock); 381 fidx-> devmap_handle = devmap_handle;382 fidx->service_id = service_id; 382 383 fidx->pfc = FAT_CLST_RES0; /* no parent yet */ 383 384 fidx->pdi = 0; … … 388 389 } 389 390 390 int fat_idx_get_new(fat_idx_t **fidxp, devmap_handle_t devmap_handle)391 int fat_idx_get_new(fat_idx_t **fidxp, service_id_t service_id) 391 392 { 392 393 fat_idx_t *fidx; … … 394 395 395 396 fibril_mutex_lock(&used_lock); 396 rc = fat_idx_create(&fidx, devmap_handle);397 rc = fat_idx_create(&fidx, service_id); 397 398 if (rc != EOK) { 398 399 fibril_mutex_unlock(&used_lock); … … 401 402 402 403 unsigned long ikey[] = { 403 [UIH_ DH_KEY] = devmap_handle,404 [UIH_SID_KEY] = service_id, 404 405 [UIH_INDEX_KEY] = fidx->index, 405 406 }; … … 414 415 415 416 fat_idx_t * 416 fat_idx_get_by_pos( devmap_handle_t devmap_handle, fat_cluster_t pfc, unsigned pdi)417 fat_idx_get_by_pos(service_id_t service_id, fat_cluster_t pfc, unsigned pdi) 417 418 { 418 419 fat_idx_t *fidx; 419 420 link_t *l; 420 421 unsigned long pkey[] = { 421 [UPH_ DH_KEY] = devmap_handle,422 [UPH_SID_KEY] = service_id, 422 423 [UPH_PFC_KEY] = pfc, 423 424 [UPH_PDI_KEY] = pdi, … … 431 432 int rc; 432 433 433 rc = fat_idx_create(&fidx, devmap_handle);434 rc = fat_idx_create(&fidx, service_id); 434 435 if (rc != EOK) { 435 436 fibril_mutex_unlock(&used_lock); … … 438 439 439 440 unsigned long ikey[] = { 440 [UIH_ DH_KEY] = devmap_handle,441 [UIH_SID_KEY] = service_id, 441 442 [UIH_INDEX_KEY] = fidx->index, 442 443 }; … … 457 458 { 458 459 unsigned long pkey[] = { 459 [UPH_ DH_KEY] = idx->devmap_handle,460 [UPH_SID_KEY] = idx->service_id, 460 461 [UPH_PFC_KEY] = idx->pfc, 461 462 [UPH_PDI_KEY] = idx->pdi, … … 470 471 { 471 472 unsigned long pkey[] = { 472 [UPH_ DH_KEY] = idx->devmap_handle,473 [UPH_SID_KEY] = idx->service_id, 473 474 [UPH_PFC_KEY] = idx->pfc, 474 475 [UPH_PDI_KEY] = idx->pdi, … … 481 482 482 483 fat_idx_t * 483 fat_idx_get_by_index( devmap_handle_t devmap_handle, fs_index_t index)484 fat_idx_get_by_index(service_id_t service_id, fs_index_t index) 484 485 { 485 486 fat_idx_t *fidx = NULL; 486 487 link_t *l; 487 488 unsigned long ikey[] = { 488 [UIH_ DH_KEY] = devmap_handle,489 [UIH_SID_KEY] = service_id, 489 490 [UIH_INDEX_KEY] = index, 490 491 }; … … 508 509 { 509 510 unsigned long ikey[] = { 510 [UIH_ DH_KEY] = idx->devmap_handle,511 [UIH_SID_KEY] = idx->service_id, 511 512 [UIH_INDEX_KEY] = idx->index, 512 513 }; 513 devmap_handle_t devmap_handle = idx->devmap_handle;514 service_id_t service_id = idx->service_id; 514 515 fs_index_t index = idx->index; 515 516 … … 525 526 fibril_mutex_unlock(&used_lock); 526 527 /* Release the VFS index. */ 527 fat_index_free( devmap_handle, index);528 fat_index_free(service_id, index); 528 529 /* The index structure itself is freed in idx_remove_callback(). */ 529 530 } … … 547 548 } 548 549 549 int fat_idx_init_by_ devmap_handle(devmap_handle_t devmap_handle)550 int fat_idx_init_by_service_id(service_id_t service_id) 550 551 { 551 552 unused_t *u; … … 555 556 if (!u) 556 557 return ENOMEM; 557 unused_initialize(u, devmap_handle);558 unused_initialize(u, service_id); 558 559 fibril_mutex_lock(&unused_lock); 559 if (!unused_find( devmap_handle, false)) {560 list_append(&u->link, &unused_ head);560 if (!unused_find(service_id, false)) { 561 list_append(&u->link, &unused_list); 561 562 } else { 562 563 free(u); … … 567 568 } 568 569 569 void fat_idx_fini_by_ devmap_handle(devmap_handle_t devmap_handle)570 void fat_idx_fini_by_service_id(service_id_t service_id) 570 571 { 571 572 unsigned long ikey[] = { 572 [UIH_ DH_KEY] = devmap_handle573 [UIH_SID_KEY] = service_id 573 574 }; 574 575 unsigned long pkey[] = { 575 [UPH_ DH_KEY] = devmap_handle576 [UPH_SID_KEY] = service_id 576 577 }; 577 578 … … 589 590 * Free the unused and freed structures for this instance. 590 591 */ 591 unused_t *u = unused_find( devmap_handle, true);592 unused_t *u = unused_find(service_id, true); 592 593 assert(u); 593 594 list_remove(&u->link); 594 595 fibril_mutex_unlock(&unused_lock); 595 596 596 while (!list_empty(&u->freed_ head)) {597 while (!list_empty(&u->freed_list)) { 597 598 freed_t *f; 598 f = list_get_instance( u->freed_head.next, freed_t, link);599 f = list_get_instance(list_first(&u->freed_list), freed_t, link); 599 600 list_remove(&f->link); 600 601 free(f);
Note:
See TracChangeset
for help on using the changeset viewer.