Subversion Repositories HelenOS

Rev

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

Rev 3625 Rev 3628
Line 341... Line 341...
341
    return EOK;
341
    return EOK;
342
}
342
}
343
 
343
 
344
int fat_link(void *prnt, void *chld, const char *name)
344
int fat_link(void *prnt, void *chld, const char *name)
345
{
345
{
-
 
346
    fat_node_t *parentp = (fat_node_t *)prnt;
-
 
347
    fat_node_t *childp = (fat_node_t *)chld;
-
 
348
    fat_dentry_t *d;
-
 
349
    fat_bs_t *bs;
-
 
350
    block_t *b;
-
 
351
    int i, j;
-
 
352
    uint16_t bps;
-
 
353
    unsigned dps;
-
 
354
    unsigned blocks;
-
 
355
 
-
 
356
    futex_down(&childp->lock);
-
 
357
    if (childp->lnkcnt == 1) {
-
 
358
        /*
346
    return ENOTSUP; /* not supported at the moment */
359
         * On FAT, we don't support multiple hard links.
-
 
360
         */
-
 
361
        futex_up(&childp->lock);
-
 
362
        return EMLINK;
-
 
363
    }
-
 
364
    assert(childp->lnkcnt == 0);
-
 
365
    futex_up(&childp->lock);
-
 
366
 
-
 
367
    if (!fat_dentry_name_verify(name)) {
-
 
368
        /*
-
 
369
         * Attempt to create unsupported name.
-
 
370
         */
-
 
371
        return ENOTSUP;
-
 
372
    }
-
 
373
 
-
 
374
    /*
-
 
375
     * Get us an unused parent node's dentry or grow the parent and allocate
-
 
376
     * a new one.
-
 
377
     */
-
 
378
   
-
 
379
    futex_down(&parentp->idx->lock);
-
 
380
    bs = block_bb_get(parentp->idx->dev_handle);
-
 
381
    bps = uint16_t_le2host(bs->bps);
-
 
382
    dps = bps / sizeof(fat_dentry_t);
-
 
383
 
-
 
384
    blocks = parentp->size / bps;
-
 
385
 
-
 
386
    for (i = 0; i < blocks; i++) {
-
 
387
        b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
-
 
388
        for (j = 0; j < dps; j++) {
-
 
389
            d = ((fat_dentry_t *)b->data) + j;
-
 
390
            switch (fat_classify_dentry(d)) {
-
 
391
            case FAT_DENTRY_SKIP:
-
 
392
            case FAT_DENTRY_VALID:
-
 
393
                /* skipping used and meta entries */
-
 
394
                continue;
-
 
395
            case FAT_DENTRY_FREE:
-
 
396
            case FAT_DENTRY_LAST:
-
 
397
                /* found an empty slot */
-
 
398
                goto hit;
-
 
399
            }
-
 
400
        }
-
 
401
        block_put(b);
-
 
402
    }
-
 
403
   
-
 
404
    /*
-
 
405
     * We need to grow the parent in order to create a new unused dentry.
-
 
406
     */
-
 
407
    futex_up(&parentp->idx->lock);
-
 
408
    return ENOTSUP; /* XXX */
-
 
409
 
-
 
410
hit:
-
 
411
    /*
-
 
412
     * At this point we only establish the link between the parent and the
-
 
413
     * child.  The dentry, except of the name and the extension, will remain
-
 
414
     * uninitialized until the the corresponding node is synced. Thus the
-
 
415
     * valid dentry data is kept in the child node structure.
-
 
416
     */
-
 
417
    memset(d, 0, sizeof(fat_dentry_t));
-
 
418
    fat_dentry_name_set(d, name);
-
 
419
    b->dirty = true;        /* need to sync block */
-
 
420
    block_put(b);
-
 
421
    futex_up(&parentp->idx->lock);
-
 
422
 
-
 
423
    futex_down(&childp->idx->lock);
-
 
424
    childp->idx->pfc = parentp->firstc;
-
 
425
    childp->idx->pdi = i * dps + j;
-
 
426
    futex_up(&childp->idx->lock);
-
 
427
 
-
 
428
    futex_down(&childp->lock);
-
 
429
    childp->lnkcnt = 1;
-
 
430
    childp->dirty = true;       /* need to sync node */
-
 
431
    futex_up(&childp->lock);
-
 
432
 
-
 
433
    /*
-
 
434
     * Hash in the index structure into the position hash.
-
 
435
     */
-
 
436
    fat_idx_hashin(childp->idx);
-
 
437
 
-
 
438
    return EOK;
347
}
439
}
348
 
440
 
349
int fat_unlink(void *prnt, void *chld)
441
int fat_unlink(void *prnt, void *chld)
350
{
442
{
351
    return ENOTSUP; /* not supported at the moment */
443
    return ENOTSUP; /* not supported at the moment */
Line 372... Line 464...
372
        b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
464
        b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
373
        for (j = 0; j < dps; j++) {
465
        for (j = 0; j < dps; j++) {
374
            d = ((fat_dentry_t *)b->data) + j;
466
            d = ((fat_dentry_t *)b->data) + j;
375
            switch (fat_classify_dentry(d)) {
467
            switch (fat_classify_dentry(d)) {
376
            case FAT_DENTRY_SKIP:
468
            case FAT_DENTRY_SKIP:
-
 
469
            case FAT_DENTRY_FREE:
377
                continue;
470
                continue;
378
            case FAT_DENTRY_LAST:
471
            case FAT_DENTRY_LAST:
379
                block_put(b);
472
                block_put(b);
380
                futex_up(&parentp->idx->lock);
473
                futex_up(&parentp->idx->lock);
381
                return NULL;
474
                return NULL;
382
            default:
475
            default:
383
            case FAT_DENTRY_VALID:
476
            case FAT_DENTRY_VALID:
384
                dentry_name_canonify(d, name);
477
                fat_dentry_name_get(d, name);
385
                break;
478
                break;
386
            }
479
            }
387
            if (stricmp(name, component) == 0) {
480
            if (stricmp(name, component) == 0) {
388
                /* hit */
481
                /* hit */
389
                void *node;
482
                void *node;
Line 462... Line 555...
462
        b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
555
        b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
463
        for (j = 0; j < dps; j++) {
556
        for (j = 0; j < dps; j++) {
464
            d = ((fat_dentry_t *)b->data) + j;
557
            d = ((fat_dentry_t *)b->data) + j;
465
            switch (fat_classify_dentry(d)) {
558
            switch (fat_classify_dentry(d)) {
466
            case FAT_DENTRY_SKIP:
559
            case FAT_DENTRY_SKIP:
-
 
560
            case FAT_DENTRY_FREE:
467
                continue;
561
                continue;
468
            case FAT_DENTRY_LAST:
562
            case FAT_DENTRY_LAST:
469
                block_put(b);
563
                block_put(b);
470
                futex_up(&nodep->idx->lock);
564
                futex_up(&nodep->idx->lock);
471
                return false;
565
                return false;
Line 696... Line 790...
696
                o < bps / sizeof(fat_dentry_t);
790
                o < bps / sizeof(fat_dentry_t);
697
                o++, pos++) {
791
                o++, pos++) {
698
                d = ((fat_dentry_t *)b->data) + o;
792
                d = ((fat_dentry_t *)b->data) + o;
699
                switch (fat_classify_dentry(d)) {
793
                switch (fat_classify_dentry(d)) {
700
                case FAT_DENTRY_SKIP:
794
                case FAT_DENTRY_SKIP:
-
 
795
                case FAT_DENTRY_FREE:
701
                    continue;
796
                    continue;
702
                case FAT_DENTRY_LAST:
797
                case FAT_DENTRY_LAST:
703
                    block_put(b);
798
                    block_put(b);
704
                    goto miss;
799
                    goto miss;
705
                default:
800
                default:
706
                case FAT_DENTRY_VALID:
801
                case FAT_DENTRY_VALID:
707
                    dentry_name_canonify(d, name);
802
                    fat_dentry_name_get(d, name);
708
                    block_put(b);
803
                    block_put(b);
709
                    goto hit;
804
                    goto hit;
710
                }
805
                }
711
            }
806
            }
712
            block_put(b);
807
            block_put(b);