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