Subversion Repositories HelenOS

Rev

Rev 2859 | Rev 2864 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2859 Rev 2863
Line 249... Line 249...
249
static void fat_sync_node(fat_node_t *node)
249
static void fat_sync_node(fat_node_t *node)
250
{
250
{
251
    /* TODO */
251
    /* TODO */
252
}
252
}
253
 
253
 
254
/** Instantiate a FAT in-core node.
254
/** Instantiate a FAT in-core node. */
255
 *
-
 
256
 * FAT stores the info necessary for instantiation of a node in the parent of
-
 
257
 * that node.  This design necessitated the addition of the parent node index
-
 
258
 * parameter to this otherwise generic libfs API.
-
 
259
 */
-
 
260
static void *
255
static void *
261
fat_node_get(dev_handle_t dev_handle, fs_index_t index, fs_index_t pindex)
256
fat_node_get(dev_handle_t dev_handle, fs_index_t index)
262
{
257
{
263
    link_t *lnk;
-
 
264
    fat_node_t *node = NULL;
-
 
265
    block_t *b;
-
 
266
    unsigned bps;
-
 
267
    unsigned dps;
-
 
268
    fat_dentry_t *d;
-
 
269
    unsigned i, j;
-
 
270
 
-
 
271
    unsigned long key[] = {
-
 
272
        [FIN_KEY_DEV_HANDLE] = dev_handle,
-
 
273
        [FIN_KEY_INDEX] = index
-
 
274
    };
-
 
275
 
-
 
276
    futex_down(&fin_futex);
-
 
277
    lnk = hash_table_find(&fin_hash, key);
-
 
278
    if (lnk) {
-
 
279
        /*
-
 
280
         * The in-core node was found in the hash table.
-
 
281
         */
-
 
282
        node = hash_table_get_instance(lnk, fat_node_t, fin_link);
-
 
283
        if (!node->refcnt++)
-
 
284
            list_remove(&node->ffn_link);
-
 
285
        futex_up(&fin_futex);
-
 
286
       
-
 
287
        /* Make sure that the node is fully instantiated. */
-
 
288
        futex_down(&node->lock);
-
 
289
        futex_up(&node->lock);
-
 
290
       
-
 
291
        return (void *) node;  
-
 
292
    }
-
 
293
 
-
 
294
    bps = fat_bps_get(dev_handle);
-
 
295
    dps = bps / sizeof(fat_dentry_t);
-
 
296
   
-
 
297
    if (!list_empty(&ffn_head)) {
-
 
298
        /*
-
 
299
         * We are going to reuse a node from the free list.
-
 
300
         */
-
 
301
        lnk = ffn_head.next;
-
 
302
        list_remove(lnk);
-
 
303
        node = list_get_instance(lnk, fat_node_t, ffn_link);
-
 
304
        assert(!node->refcnt);
-
 
305
        if (node->dirty)
-
 
306
            fat_sync_node(node);
-
 
307
        key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
-
 
308
        key[FIN_KEY_INDEX] = node->index;
-
 
309
        hash_table_remove(&fin_hash, key, sizeof(key)/sizeof(*key));
-
 
310
    } else {
-
 
311
        /*
-
 
312
         * We need to allocate a new node.
-
 
313
         */
-
 
314
        node = malloc(sizeof(fat_node_t));
-
 
315
        if (!node)
-
 
316
            return NULL;
258
    return NULL;    /* TODO */
317
    }
-
 
318
    fat_node_initialize(node);
-
 
319
    node->refcnt++;
-
 
320
    node->lnkcnt++;
-
 
321
    node->dev_handle = dev_handle;
-
 
322
    node->index = index;
-
 
323
    node->pindex = pindex;
-
 
324
    key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
-
 
325
    key[FIN_KEY_INDEX] = node->index;
-
 
326
    hash_table_insert(&fin_hash, key, &node->fin_link);
-
 
327
 
-
 
328
    /*
-
 
329
     * We have already put the node back to fin_hash.
-
 
330
     * The node is not yet fully instantiated so we lock it prior to
-
 
331
     * unlocking fin_hash.
-
 
332
     */
-
 
333
    futex_down(&node->lock);
-
 
334
    futex_up(&fin_futex);
-
 
335
 
-
 
336
    /*
-
 
337
     * Because of the design of the FAT file system, we have no clue about
-
 
338
     * how big (i.e. how many directory entries it contains) is the parent
-
 
339
     * of the node we are trying to instantiate.  However, we know that it
-
 
340
     * must contain a directory entry for our node of interest.  We simply
-
 
341
     * scan the parent until we find it.
-
 
342
     */
-
 
343
    for (i = 0; ; i++) {
-
 
344
        b = fat_block_get(node->dev_handle, node->pindex, i);
-
 
345
        for (j = 0; j < dps; j++) {
-
 
346
            d = ((fat_dentry_t *)b->data) + j;
-
 
347
            if (d->firstc == node->index)
-
 
348
                goto found;
-
 
349
        }
-
 
350
        block_put(b);
-
 
351
    }
-
 
352
   
-
 
353
found:
-
 
354
    if (!(d->attr & (FAT_ATTR_SUBDIR | FAT_ATTR_VOLLABEL)))
-
 
355
        node->type = FAT_FILE;
-
 
356
    if ((d->attr & FAT_ATTR_SUBDIR) || !index)
-
 
357
        node->type = FAT_DIRECTORY;
-
 
358
    assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY));
-
 
359
   
-
 
360
    node->size = uint32_t_le2host(d->size);
-
 
361
    block_put(b);
-
 
362
 
-
 
363
    futex_up(&node->lock);
-
 
364
    return node;
-
 
365
}
259
}
366
 
260
 
367
static void fat_node_put(void *node)
261
static void fat_node_put(void *node)
368
{
262
{
369
    fat_node_t *nodep = (fat_node_t *)node;
-
 
370
 
-
 
371
    futex_down(&fin_futex);
-
 
372
    if (!--nodep->refcnt)
263
    /* TODO */
373
        list_append(&nodep->ffn_link, &ffn_head);
-
 
374
    futex_up(&fin_futex);
-
 
375
}
264
}
376
 
265
 
377
static void *fat_create(int flags)
266
static void *fat_create(int flags)
378
{
267
{
379
    return NULL;    /* not supported at the moment */
268
    return NULL;    /* not supported at the moment */
Line 429... Line 318...
429
                break;
318
                break;
430
            }
319
            }
431
            if (strcmp(name, component) == 0) {
320
            if (strcmp(name, component) == 0) {
432
                /* hit */
321
                /* hit */
433
                void *node = fat_node_get(parentp->dev_handle,
322
                void *node = fat_node_get(parentp->dev_handle,
434
                    (fs_index_t)uint16_t_le2host(d->firstc),
323
                    (fs_index_t)uint16_t_le2host(d->firstc));
435
                    parentp->index);
-
 
436
                block_put(b);
324
                block_put(b);
437
                return node;
325
                return node;
438
            }
326
            }
439
        }
327
        }
440
        block_put(b);
328
        block_put(b);
Line 508... Line 396...
508
    return false;
396
    return false;
509
}
397
}
510
 
398
 
511
static void *fat_root_get(dev_handle_t dev_handle)
399
static void *fat_root_get(dev_handle_t dev_handle)
512
{
400
{
513
    return fat_node_get(dev_handle, 0, 0); 
401
    return fat_node_get(dev_handle, 0);
514
}
402
}
515
 
403
 
516
static char fat_plb_get_char(unsigned pos)
404
static char fat_plb_get_char(unsigned pos)
517
{
405
{
518
    return fat_reg.plb_ro[pos % PLB_SIZE];
406
    return fat_reg.plb_ro[pos % PLB_SIZE];