Subversion Repositories HelenOS

Rev

Rev 3110 | Rev 3615 | 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;