Rev 3386 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3386 | Rev 4153 | ||
|---|---|---|---|
| Line 212... | Line 212... | ||
| 212 | .compare = idx_compare, |
212 | .compare = idx_compare, |
| 213 | .remove_callback = idx_remove_callback, |
213 | .remove_callback = idx_remove_callback, |
| 214 | }; |
214 | }; |
| 215 | 215 | ||
| 216 | /** Allocate a VFS index which is not currently in use. */ |
216 | /** Allocate a VFS index which is not currently in use. */ |
| 217 | static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
217 | static bool fat_index_alloc(dev_handle_t dev_handle, fs_index_t *index) |
| 218 | { |
218 | { |
| 219 | unused_t *u; |
219 | unused_t *u; |
| 220 | 220 | ||
| 221 | assert(index); |
221 | assert(index); |
| 222 | u = unused_find(dev_handle, true); |
222 | u = unused_find(dev_handle, true); |
| Line 274... | Line 274... | ||
| 274 | } |
274 | } |
| 275 | } |
275 | } |
| 276 | } |
276 | } |
| 277 | 277 | ||
| 278 | /** Free a VFS index, which is no longer in use. */ |
278 | /** Free a VFS index, which is no longer in use. */ |
| 279 | static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index) |
279 | static void fat_index_free(dev_handle_t dev_handle, fs_index_t index) |
| 280 | { |
280 | { |
| 281 | unused_t *u; |
281 | unused_t *u; |
| 282 | 282 | ||
| 283 | u = unused_find(dev_handle, true); |
283 | u = unused_find(dev_handle, true); |
| 284 | assert(u); |
284 | assert(u); |
| Line 336... | Line 336... | ||
| 336 | list_append(&n->link, &u->freed_head); |
336 | list_append(&n->link, &u->freed_head); |
| 337 | } |
337 | } |
| 338 | futex_up(&unused_futex); |
338 | futex_up(&unused_futex); |
| 339 | } |
339 | } |
| 340 | 340 | ||
| - | 341 | static fat_idx_t *fat_idx_create(dev_handle_t dev_handle) |
|
| - | 342 | { |
|
| - | 343 | fat_idx_t *fidx; |
|
| - | 344 | ||
| - | 345 | fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); |
|
| - | 346 | if (!fidx) |
|
| - | 347 | return NULL; |
|
| - | 348 | if (!fat_index_alloc(dev_handle, &fidx->index)) { |
|
| - | 349 | free(fidx); |
|
| - | 350 | return NULL; |
|
| - | 351 | } |
|
| - | 352 | ||
| - | 353 | link_initialize(&fidx->uph_link); |
|
| - | 354 | link_initialize(&fidx->uih_link); |
|
| - | 355 | futex_initialize(&fidx->lock, 1); |
|
| - | 356 | fidx->dev_handle = dev_handle; |
|
| - | 357 | fidx->pfc = FAT_CLST_RES0; /* no parent yet */ |
|
| - | 358 | fidx->pdi = 0; |
|
| - | 359 | fidx->nodep = NULL; |
|
| - | 360 | ||
| - | 361 | return fidx; |
|
| - | 362 | } |
|
| - | 363 | ||
| - | 364 | fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle) |
|
| - | 365 | { |
|
| - | 366 | fat_idx_t *fidx; |
|
| - | 367 | ||
| - | 368 | futex_down(&used_futex); |
|
| - | 369 | fidx = fat_idx_create(dev_handle); |
|
| - | 370 | if (!fidx) { |
|
| - | 371 | futex_up(&used_futex); |
|
| - | 372 | return NULL; |
|
| - | 373 | } |
|
| - | 374 | ||
| - | 375 | unsigned long ikey[] = { |
|
| - | 376 | [UIH_DH_KEY] = dev_handle, |
|
| - | 377 | [UIH_INDEX_KEY] = fidx->index, |
|
| - | 378 | }; |
|
| - | 379 | ||
| - | 380 | hash_table_insert(&ui_hash, ikey, &fidx->uih_link); |
|
| - | 381 | futex_down(&fidx->lock); |
|
| - | 382 | futex_up(&used_futex); |
|
| - | 383 | ||
| - | 384 | return fidx; |
|
| - | 385 | } |
|
| - | 386 | ||
| 341 | fat_idx_t * |
387 | fat_idx_t * |
| 342 | fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi) |
388 | fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi) |
| 343 | { |
389 | { |
| 344 | fat_idx_t *fidx; |
390 | fat_idx_t *fidx; |
| 345 | link_t *l; |
391 | link_t *l; |
| Line 352... | Line 398... | ||
| 352 | futex_down(&used_futex); |
398 | futex_down(&used_futex); |
| 353 | l = hash_table_find(&up_hash, pkey); |
399 | l = hash_table_find(&up_hash, pkey); |
| 354 | if (l) { |
400 | if (l) { |
| 355 | fidx = hash_table_get_instance(l, fat_idx_t, uph_link); |
401 | fidx = hash_table_get_instance(l, fat_idx_t, uph_link); |
| 356 | } else { |
402 | } else { |
| 357 | fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); |
403 | fidx = fat_idx_create(dev_handle); |
| 358 | if (!fidx) { |
404 | if (!fidx) { |
| 359 | futex_up(&used_futex); |
405 | futex_up(&used_futex); |
| 360 | return NULL; |
406 | return NULL; |
| 361 | } |
407 | } |
| 362 | if (!fat_idx_alloc(dev_handle, &fidx->index)) { |
- | |
| 363 | free(fidx); |
- | |
| 364 | futex_up(&used_futex); |
- | |
| 365 | return NULL; |
- | |
| 366 | } |
- | |
| 367 | 408 | ||
| 368 | unsigned long ikey[] = { |
409 | unsigned long ikey[] = { |
| 369 | [UIH_DH_KEY] = dev_handle, |
410 | [UIH_DH_KEY] = dev_handle, |
| 370 | [UIH_INDEX_KEY] = fidx->index, |
411 | [UIH_INDEX_KEY] = fidx->index, |
| 371 | }; |
412 | }; |
| 372 | 413 | ||
| 373 | link_initialize(&fidx->uph_link); |
- | |
| 374 | link_initialize(&fidx->uih_link); |
- | |
| 375 | futex_initialize(&fidx->lock, 1); |
- | |
| 376 | fidx->dev_handle = dev_handle; |
- | |
| 377 | fidx->pfc = pfc; |
414 | fidx->pfc = pfc; |
| 378 | fidx->pdi = pdi; |
415 | fidx->pdi = pdi; |
| 379 | fidx->nodep = NULL; |
- | |
| 380 | 416 | ||
| 381 | hash_table_insert(&up_hash, pkey, &fidx->uph_link); |
417 | hash_table_insert(&up_hash, pkey, &fidx->uph_link); |
| 382 | hash_table_insert(&ui_hash, ikey, &fidx->uih_link); |
418 | hash_table_insert(&ui_hash, ikey, &fidx->uih_link); |
| 383 | } |
419 | } |
| 384 | futex_down(&fidx->lock); |
420 | futex_down(&fidx->lock); |
| 385 | futex_up(&used_futex); |
421 | futex_up(&used_futex); |
| 386 | 422 | ||
| 387 | return fidx; |
423 | return fidx; |
| 388 | } |
424 | } |
| 389 | 425 | ||
| - | 426 | void fat_idx_hashin(fat_idx_t *idx) |
|
| - | 427 | { |
|
| - | 428 | unsigned long pkey[] = { |
|
| - | 429 | [UPH_DH_KEY] = idx->dev_handle, |
|
| - | 430 | [UPH_PFC_KEY] = idx->pfc, |
|
| - | 431 | [UPH_PDI_KEY] = idx->pdi, |
|
| - | 432 | }; |
|
| - | 433 | ||
| - | 434 | futex_down(&used_futex); |
|
| - | 435 | hash_table_insert(&up_hash, pkey, &idx->uph_link); |
|
| - | 436 | futex_up(&used_futex); |
|
| - | 437 | } |
|
| - | 438 | ||
| - | 439 | void fat_idx_hashout(fat_idx_t *idx) |
|
| - | 440 | { |
|
| - | 441 | unsigned long pkey[] = { |
|
| - | 442 | [UPH_DH_KEY] = idx->dev_handle, |
|
| - | 443 | [UPH_PFC_KEY] = idx->pfc, |
|
| - | 444 | [UPH_PDI_KEY] = idx->pdi, |
|
| - | 445 | }; |
|
| - | 446 | ||
| - | 447 | futex_down(&used_futex); |
|
| - | 448 | hash_table_remove(&up_hash, pkey, 3); |
|
| - | 449 | futex_up(&used_futex); |
|
| - | 450 | } |
|
| - | 451 | ||
| 390 | fat_idx_t * |
452 | fat_idx_t * |
| 391 | fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index) |
453 | fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index) |
| 392 | { |
454 | { |
| 393 | fat_idx_t *fidx = NULL; |
455 | fat_idx_t *fidx = NULL; |
| 394 | link_t *l; |
456 | link_t *l; |
| Line 406... | Line 468... | ||
| 406 | futex_up(&used_futex); |
468 | futex_up(&used_futex); |
| 407 | 469 | ||
| 408 | return fidx; |
470 | return fidx; |
| 409 | } |
471 | } |
| 410 | 472 | ||
| - | 473 | /** Destroy the index structure. |
|
| - | 474 | * |
|
| - | 475 | * @param idx The index structure to be destroyed. |
|
| - | 476 | */ |
|
| - | 477 | void fat_idx_destroy(fat_idx_t *idx) |
|
| - | 478 | { |
|
| - | 479 | unsigned long ikey[] = { |
|
| - | 480 | [UIH_DH_KEY] = idx->dev_handle, |
|
| - | 481 | [UIH_INDEX_KEY] = idx->index, |
|
| - | 482 | }; |
|
| - | 483 | ||
| - | 484 | assert(idx->pfc == FAT_CLST_RES0); |
|
| - | 485 | ||
| - | 486 | futex_down(&used_futex); |
|
| - | 487 | /* |
|
| - | 488 | * Since we can only free unlinked nodes, the index structure is not |
|
| - | 489 | * present in the position hash (uph). We therefore hash it out from |
|
| - | 490 | * the index hash only. |
|
| - | 491 | */ |
|
| - | 492 | hash_table_remove(&ui_hash, ikey, 2); |
|
| - | 493 | futex_up(&used_futex); |
|
| - | 494 | /* Release the VFS index. */ |
|
| - | 495 | fat_index_free(idx->dev_handle, idx->index); |
|
| - | 496 | /* Deallocate the structure. */ |
|
| - | 497 | free(idx); |
|
| - | 498 | } |
|
| - | 499 | ||
| 411 | int fat_idx_init(void) |
500 | int fat_idx_init(void) |
| 412 | { |
501 | { |
| 413 | if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops)) |
502 | if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops)) |
| 414 | return ENOMEM; |
503 | return ENOMEM; |
| 415 | if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) { |
504 | if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) { |