Changeset 0fdd6bb in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2008-11-23T16:22:40Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a5da446
Parents:
d2093d6
Message:

Add somewhat functional fat_link().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    rd2093d6 r0fdd6bb  
    344344int fat_link(void *prnt, void *chld, const char *name)
    345345{
    346         return ENOTSUP; /* not supported at the moment */
     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                /*
     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
     410hit:
     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;
    347439}
    348440
     
    375467                        switch (fat_classify_dentry(d)) {
    376468                        case FAT_DENTRY_SKIP:
     469                        case FAT_DENTRY_FREE:
    377470                                continue;
    378471                        case FAT_DENTRY_LAST:
     
    382475                        default:
    383476                        case FAT_DENTRY_VALID:
    384                                 dentry_name_canonify(d, name);
     477                                fat_dentry_name_get(d, name);
    385478                                break;
    386479                        }
     
    465558                        switch (fat_classify_dentry(d)) {
    466559                        case FAT_DENTRY_SKIP:
     560                        case FAT_DENTRY_FREE:
    467561                                continue;
    468562                        case FAT_DENTRY_LAST:
     
    699793                                switch (fat_classify_dentry(d)) {
    700794                                case FAT_DENTRY_SKIP:
     795                                case FAT_DENTRY_FREE:
    701796                                        continue;
    702797                                case FAT_DENTRY_LAST:
     
    705800                                default:
    706801                                case FAT_DENTRY_VALID:
    707                                         dentry_name_canonify(d, name);
     802                                        fat_dentry_name_get(d, name);
    708803                                        block_put(b);
    709804                                        goto hit;
Note: See TracChangeset for help on using the changeset viewer.