Rev 3110 | Rev 3574 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3110 | Rev 3111 | ||
|---|---|---|---|
| Line 81... | Line 81... | ||
| 81 | u->next = 0; |
81 | u->next = 0; |
| 82 | u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; |
82 | u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; |
| 83 | list_initialize(&u->freed_head); |
83 | list_initialize(&u->freed_head); |
| 84 | } |
84 | } |
| 85 | 85 | ||
| - | 86 | static unused_t *unused_find(dev_handle_t dev_handle, bool lock) |
|
| - | 87 | { |
|
| - | 88 | unused_t *u; |
|
| - | 89 | link_t *l; |
|
| - | 90 | ||
| - | 91 | if (lock) |
|
| - | 92 | futex_down(&unused_futex); |
|
| - | 93 | for (l = unused_head.next; l != &unused_head; l = l->next) { |
|
| - | 94 | u = list_get_instance(l, unused_t, link); |
|
| - | 95 | if (u->dev_handle == dev_handle) |
|
| - | 96 | return u; |
|
| - | 97 | } |
|
| - | 98 | if (lock) |
|
| - | 99 | futex_up(&unused_futex); |
|
| - | 100 | return NULL; |
|
| - | 101 | } |
|
| - | 102 | ||
| 86 | /** Futex protecting the up_hash and ui_hash. */ |
103 | /** Futex protecting the up_hash and ui_hash. */ |
| 87 | static futex_t used_futex = FUTEX_INITIALIZER; |
104 | static futex_t used_futex = FUTEX_INITIALIZER; |
| 88 | 105 | ||
| 89 | /** |
106 | /** |
| 90 | * Global hash table of all used fat_idx_t structures. |
107 | * Global hash table of all used fat_idx_t structures. |
| Line 197... | Line 214... | ||
| 197 | }; |
214 | }; |
| 198 | 215 | ||
| 199 | /** Allocate a VFS index which is not currently in use. */ |
216 | /** Allocate a VFS index which is not currently in use. */ |
| 200 | static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
217 | static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
| 201 | { |
218 | { |
| 202 | link_t *l; |
- | |
| 203 | unused_t *u; |
219 | unused_t *u; |
| 204 | 220 | ||
| 205 | assert(index); |
221 | assert(index); |
| 206 | futex_down(&unused_futex); |
- | |
| 207 | for (l = unused_head.next; l != &unused_head; l = l->next) { |
- | |
| 208 | u = list_get_instance(l, unused_t, link); |
- | |
| 209 | if (u->dev_handle == dev_handle) |
222 | u = unused_find(dev_handle, true); |
| 210 | goto hit; |
223 | if (!u) |
| 211 | } |
- | |
| 212 | futex_up(&unused_futex); |
- | |
| 213 | - | ||
| 214 | /* dev_handle not found */ |
- | |
| 215 | return false; |
224 | return false; |
| 216 | 225 | ||
| 217 | hit: |
- | |
| 218 | if (list_empty(&u->freed_head)) { |
226 | if (list_empty(&u->freed_head)) { |
| 219 | if (u->remaining) { |
227 | if (u->remaining) { |
| 220 | /* |
228 | /* |
| 221 | * There are no freed indices, allocate one directly |
229 | * There are no freed indices, allocate one directly |
| 222 | * from the counter. |
230 | * from the counter. |
| Line 268... | Line 276... | ||
| 268 | } |
276 | } |
| 269 | 277 | ||
| 270 | /** Free a VFS index, which is no longer in use. */ |
278 | /** Free a VFS index, which is no longer in use. */ |
| 271 | static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index) |
279 | static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index) |
| 272 | { |
280 | { |
| 273 | link_t *l; |
- | |
| 274 | unused_t *u; |
281 | unused_t *u; |
| 275 | 282 | ||
| 276 | futex_down(&unused_futex); |
- | |
| 277 | for (l = unused_head.next; l != &unused_head; l = l->next) { |
- | |
| 278 | u = list_get_instance(l, unused_t, link); |
- | |
| 279 | if (u->dev_handle == dev_handle) |
283 | u = unused_find(dev_handle, true); |
| 280 | goto hit; |
- | |
| 281 | } |
- | |
| 282 | futex_up(&unused_futex); |
- | |
| 283 | - | ||
| 284 | /* should not happen */ |
- | |
| 285 | assert(0); |
284 | assert(u); |
| 286 | 285 | ||
| 287 | hit: |
- | |
| 288 | if (u->next == index + 1) { |
286 | if (u->next == index + 1) { |
| 289 | /* The index can be returned directly to the counter. */ |
287 | /* The index can be returned directly to the counter. */ |
| 290 | u->next--; |
288 | u->next--; |
| 291 | u->remaining++; |
289 | u->remaining++; |
| 292 | } else { |
290 | } else { |
| Line 428... | Line 426... | ||
| 428 | hash_table_destroy(&ui_hash); |
426 | hash_table_destroy(&ui_hash); |
| 429 | } |
427 | } |
| 430 | 428 | ||
| 431 | int fat_idx_init_by_dev_handle(dev_handle_t dev_handle) |
429 | int fat_idx_init_by_dev_handle(dev_handle_t dev_handle) |
| 432 | { |
430 | { |
| - | 431 | unused_t *u; |
|
| - | 432 | int rc = EOK; |
|
| - | 433 | ||
| 433 | unused_t *u = (unused_t *) malloc(sizeof(unused_t)); |
434 | u = (unused_t *) malloc(sizeof(unused_t)); |
| 434 | if (!u) |
435 | if (!u) |
| 435 | return ENOMEM; |
436 | return ENOMEM; |
| 436 | unused_initialize(u, dev_handle); |
437 | unused_initialize(u, dev_handle); |
| 437 | futex_down(&unused_futex); |
438 | futex_down(&unused_futex); |
| - | 439 | if (!unused_find(dev_handle, false)) |
|
| 438 | list_append(&u->link, &unused_head); |
440 | list_append(&u->link, &unused_head); |
| - | 441 | else |
|
| - | 442 | rc = EEXIST; |
|
| 439 | futex_up(&unused_futex); |
443 | futex_up(&unused_futex); |
| 440 | return EOK; |
444 | return rc; |
| 441 | } |
445 | } |
| 442 | 446 | ||
| 443 | void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) |
447 | void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) |
| 444 | { |
448 | { |
| 445 | unused_t *u; |
449 | unused_t *u; |
| 446 | link_t *l; |
- | |
| 447 | - | ||
| 448 | futex_down(&unused_futex); |
- | |
| 449 | for (l = unused_head.next; l != &unused_head; l = l->next) { |
- | |
| 450 | u = list_get_instance(l, unused_t, link); |
- | |
| 451 | if (u->dev_handle == dev_handle) |
- | |
| 452 | goto hit; |
- | |
| 453 | } |
- | |
| 454 | futex_up(&unused_futex); |
- | |
| 455 | - | ||
| 456 | assert(false); /* should not happen */ |
- | |
| 457 | 450 | ||
| - | 451 | u = unused_find(dev_handle, true); |
|
| 458 | hit: |
452 | assert(u); |
| 459 | list_remove(&u->link); |
453 | list_remove(&u->link); |
| 460 | futex_up(&unused_futex); |
454 | futex_up(&unused_futex); |
| 461 | 455 | ||
| 462 | while (!list_empty(&u->freed_head)) { |
456 | while (!list_empty(&u->freed_head)) { |
| 463 | freed_t *f; |
457 | freed_t *f; |