Ignore:
File:
1 edited

Legend:

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

    r19f857a ra93d79a  
    6060#define FS_NODE(node)   ((node) ? (node)->bp : NULL)
    6161
     62#define DPS(bs)         (BPS((bs)) / sizeof(fat_dentry_t))
     63#define BPC(bs)         (BPS((bs)) * SPC((bs)))
     64
    6265/** Mutex protecting the list of cached free FAT nodes. */
    6366static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
     
    101104        node->refcnt = 0;
    102105        node->dirty = false;
     106        node->lastc_cached_valid = false;
     107        node->lastc_cached_value = FAT_CLST_LAST1;
     108        node->currc_cached_valid = false;
     109        node->currc_cached_bn = 0;
     110        node->currc_cached_value = FAT_CLST_LAST1;
    103111}
    104112
     
    108116        fat_bs_t *bs;
    109117        fat_dentry_t *d;
    110         uint16_t bps;
    111         unsigned dps;
    112118        int rc;
    113119       
     
    115121
    116122        bs = block_bb_get(node->idx->dev_handle);
    117         bps = uint16_t_le2host(bs->bps);
    118         dps = bps / sizeof(fat_dentry_t);
    119123       
    120124        /* Read the block that contains the dentry of interest. */
    121125        rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc,
    122             (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
     126            NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
     127            BLOCK_FLAGS_NONE);
    123128        if (rc != EOK)
    124129                return rc;
    125130
    126         d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
     131        d = ((fat_dentry_t *)b->data) + (node->idx->pdi % DPS(bs));
    127132
    128133        d->firstc = host2uint16_t_le(node->firstc);
     
    266271        fat_dentry_t *d;
    267272        fat_node_t *nodep = NULL;
    268         unsigned bps;
    269         unsigned spc;
    270         unsigned dps;
    271273        int rc;
    272274
     
    298300
    299301        bs = block_bb_get(idxp->dev_handle);
    300         bps = uint16_t_le2host(bs->bps);
    301         spc = bs->spc;
    302         dps = bps / sizeof(fat_dentry_t);
    303302
    304303        /* Read the block that contains the dentry of interest. */
    305         rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc,
    306             (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
     304        rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, NULL,
     305            (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    307306        if (rc != EOK) {
    308307                (void) fat_node_put(FS_NODE(nodep));
     
    310309        }
    311310
    312         d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
     311        d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
    313312        if (d->attr & FAT_ATTR_SUBDIR) {
    314313                /*
     
    330329                        return rc;
    331330                }
    332                 nodep->size = bps * spc * clusters;
     331                nodep->size = BPS(bs) * SPC(bs) * clusters;
    333332        } else {
    334333                nodep->type = FAT_FILE;
     
    368367        char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    369368        unsigned i, j;
    370         unsigned bps;           /* bytes per sector */
    371         unsigned dps;           /* dentries per sector */
    372369        unsigned blocks;
    373370        fat_dentry_t *d;
     371        dev_handle_t dev_handle;
    374372        block_t *b;
    375373        int rc;
    376374
    377375        fibril_mutex_lock(&parentp->idx->lock);
    378         bs = block_bb_get(parentp->idx->dev_handle);
    379         bps = uint16_t_le2host(bs->bps);
    380         dps = bps / sizeof(fat_dentry_t);
    381         blocks = parentp->size / bps;
     376        dev_handle = parentp->idx->dev_handle;
     377        fibril_mutex_unlock(&parentp->idx->lock);
     378
     379        bs = block_bb_get(dev_handle);
     380        blocks = parentp->size / BPS(bs);
    382381        for (i = 0; i < blocks; i++) {
    383382                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
    384                 if (rc != EOK) {
    385                         fibril_mutex_unlock(&parentp->idx->lock);
     383                if (rc != EOK)
    386384                        return rc;
    387                 }
    388                 for (j = 0; j < dps; j++) {
     385                for (j = 0; j < DPS(bs); j++) {
    389386                        d = ((fat_dentry_t *)b->data) + j;
    390387                        switch (fat_classify_dentry(d)) {
     
    395392                                /* miss */
    396393                                rc = block_put(b);
    397                                 fibril_mutex_unlock(&parentp->idx->lock);
    398394                                *rfn = NULL;
    399395                                return rc;
     
    406402                                /* hit */
    407403                                fat_node_t *nodep;
    408                                 /*
    409                                  * Assume tree hierarchy for locking.  We
    410                                  * already have the parent and now we are going
    411                                  * to lock the child.  Never lock in the oposite
    412                                  * order.
    413                                  */
    414                                 fat_idx_t *idx = fat_idx_get_by_pos(
    415                                     parentp->idx->dev_handle, parentp->firstc,
    416                                     i * dps + j);
    417                                 fibril_mutex_unlock(&parentp->idx->lock);
     404                                fat_idx_t *idx = fat_idx_get_by_pos(dev_handle,
     405                                    parentp->firstc, i * DPS(bs) + j);
    418406                                if (!idx) {
    419407                                        /*
     
    438426                }
    439427                rc = block_put(b);
    440                 if (rc != EOK) {
    441                         fibril_mutex_unlock(&parentp->idx->lock);
     428                if (rc != EOK)
    442429                        return rc;
    443                 }
    444         }
    445 
    446         fibril_mutex_unlock(&parentp->idx->lock);
     430        }
     431
    447432        *rfn = NULL;
    448433        return EOK;
     
    513498        fat_bs_t *bs;
    514499        fat_cluster_t mcl, lcl;
    515         uint16_t bps;
    516500        int rc;
    517501
    518502        bs = block_bb_get(dev_handle);
    519         bps = uint16_t_le2host(bs->bps);
    520503        if (flags & L_DIRECTORY) {
    521504                /* allocate a cluster */
     
    546529                nodep->type = FAT_DIRECTORY;
    547530                nodep->firstc = mcl;
    548                 nodep->size = bps * bs->spc;
     531                nodep->size = BPS(bs) * SPC(bs);
    549532        } else {
    550533                nodep->type = FAT_FILE;
     
    609592        block_t *b;
    610593        unsigned i, j;
    611         uint16_t bps;
    612         unsigned dps;
    613594        unsigned blocks;
    614595        fat_cluster_t mcl, lcl;
     
    640621        fibril_mutex_lock(&parentp->idx->lock);
    641622        bs = block_bb_get(parentp->idx->dev_handle);
    642         bps = uint16_t_le2host(bs->bps);
    643         dps = bps / sizeof(fat_dentry_t);
    644 
    645         blocks = parentp->size / bps;
     623
     624        blocks = parentp->size / BPS(bs);
    646625
    647626        for (i = 0; i < blocks; i++) {
     
    651630                        return rc;
    652631                }
    653                 for (j = 0; j < dps; j++) {
     632                for (j = 0; j < DPS(bs); j++) {
    654633                        d = ((fat_dentry_t *)b->data) + j;
    655634                        switch (fat_classify_dentry(d)) {
     
    691670                return rc;
    692671        }
    693         rc = fat_append_clusters(bs, parentp, mcl);
     672        rc = fat_append_clusters(bs, parentp, mcl, lcl);
    694673        if (rc != EOK) {
    695674                (void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl);
     
    697676                return rc;
    698677        }
    699         parentp->size += bps * bs->spc;
     678        parentp->size += BPS(bs) * SPC(bs);
    700679        parentp->dirty = true;          /* need to sync node */
    701680        rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     
    771750
    772751        childp->idx->pfc = parentp->firstc;
    773         childp->idx->pdi = i * dps + j;
     752        childp->idx->pdi = i * DPS(bs) + j;
    774753        fibril_mutex_unlock(&childp->idx->lock);
    775754
     
    793772        fat_bs_t *bs;
    794773        fat_dentry_t *d;
    795         uint16_t bps;
    796774        block_t *b;
    797775        bool has_children;
     
    812790        fibril_mutex_lock(&childp->idx->lock);
    813791        bs = block_bb_get(childp->idx->dev_handle);
    814         bps = uint16_t_le2host(bs->bps);
    815792
    816793        rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc,
    817             (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
     794            NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    818795            BLOCK_FLAGS_NONE);
    819796        if (rc != EOK)
    820797                goto error;
    821798        d = (fat_dentry_t *)b->data +
    822             (childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
     799            (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
    823800        /* mark the dentry as not-currently-used */
    824801        d->name[0] = FAT_DENTRY_ERASED;
     
    852829        fat_bs_t *bs;
    853830        fat_node_t *nodep = FAT_NODE(fn);
    854         unsigned bps;
    855         unsigned dps;
    856831        unsigned blocks;
    857832        block_t *b;
     
    866841        fibril_mutex_lock(&nodep->idx->lock);
    867842        bs = block_bb_get(nodep->idx->dev_handle);
    868         bps = uint16_t_le2host(bs->bps);
    869         dps = bps / sizeof(fat_dentry_t);
    870 
    871         blocks = nodep->size / bps;
     843
     844        blocks = nodep->size / BPS(bs);
    872845
    873846        for (i = 0; i < blocks; i++) {
     
    879852                        return rc;
    880853                }
    881                 for (j = 0; j < dps; j++) {
     854                for (j = 0; j < DPS(bs); j++) {
    882855                        d = ((fat_dentry_t *)b->data) + j;
    883856                        switch (fat_classify_dentry(d)) {
     
    976949        enum cache_mode cmode;
    977950        fat_bs_t *bs;
    978         uint16_t bps;
    979         uint16_t rde;
    980951       
    981952        /* Accept the mount options */
     
    1014985        bs = block_bb_get(dev_handle);
    1015986       
    1016         /* Read the number of root directory entries. */
    1017         bps = uint16_t_le2host(bs->bps);
    1018         rde = uint16_t_le2host(bs->root_ent_max);
    1019 
    1020         if (bps != BS_SIZE) {
     987        if (BPS(bs) != BS_SIZE) {
    1021988                block_fini(dev_handle);
    1022989                ipc_answer_0(rid, ENOTSUP);
     
    1025992
    1026993        /* Initialize the block cache */
    1027         rc = block_cache_init(dev_handle, bps, 0 /* XXX */, cmode);
     994        rc = block_cache_init(dev_handle, BPS(bs), 0 /* XXX */, cmode);
    1028995        if (rc != EOK) {
    1029996                block_fini(dev_handle);
     
    10871054        rootp->refcnt = 1;
    10881055        rootp->lnkcnt = 0;      /* FS root is not linked */
    1089         rootp->size = rde * sizeof(fat_dentry_t);
     1056        rootp->size = RDE(bs) * sizeof(fat_dentry_t);
    10901057        rootp->idx = ridxp;
    10911058        ridxp->nodep = rootp;
     
    11651132        fat_node_t *nodep;
    11661133        fat_bs_t *bs;
    1167         uint16_t bps;
    11681134        size_t bytes;
    11691135        block_t *b;
     
    11911157
    11921158        bs = block_bb_get(dev_handle);
    1193         bps = uint16_t_le2host(bs->bps);
    11941159
    11951160        if (nodep->type == FAT_FILE) {
     
    12041169                        (void) async_data_read_finalize(callid, NULL, 0);
    12051170                } else {
    1206                         bytes = min(len, bps - pos % bps);
     1171                        bytes = min(len, BPS(bs) - pos % BPS(bs));
    12071172                        bytes = min(bytes, nodep->size - pos);
    1208                         rc = fat_block_get(&b, bs, nodep, pos / bps,
     1173                        rc = fat_block_get(&b, bs, nodep, pos / BPS(bs),
    12091174                            BLOCK_FLAGS_NONE);
    12101175                        if (rc != EOK) {
     
    12141179                                return;
    12151180                        }
    1216                         (void) async_data_read_finalize(callid, b->data + pos % bps,
    1217                             bytes);
     1181                        (void) async_data_read_finalize(callid,
     1182                            b->data + pos % BPS(bs), bytes);
    12181183                        rc = block_put(b);
    12191184                        if (rc != EOK) {
     
    12301195
    12311196                assert(nodep->type == FAT_DIRECTORY);
    1232                 assert(nodep->size % bps == 0);
    1233                 assert(bps % sizeof(fat_dentry_t) == 0);
     1197                assert(nodep->size % BPS(bs) == 0);
     1198                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    12341199
    12351200                /*
     
    12391204                 * the position pointer accordingly.
    12401205                 */
    1241                 bnum = (pos * sizeof(fat_dentry_t)) / bps;
    1242                 while (bnum < nodep->size / bps) {
     1206                bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
     1207                while (bnum < nodep->size / BPS(bs)) {
    12431208                        aoff64_t o;
    12441209
     
    12471212                        if (rc != EOK)
    12481213                                goto err;
    1249                         for (o = pos % (bps / sizeof(fat_dentry_t));
    1250                             o < bps / sizeof(fat_dentry_t);
     1214                        for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
     1215                            o < BPS(bs) / sizeof(fat_dentry_t);
    12511216                            o++, pos++) {
    12521217                                d = ((fat_dentry_t *)b->data) + o;
     
    13061271        size_t bytes, size;
    13071272        block_t *b;
    1308         uint16_t bps;
    1309         unsigned spc;
    1310         unsigned bpc;           /* bytes per cluster */
    13111273        aoff64_t boundary;
    13121274        int flags = BLOCK_FLAGS_NONE;
     
    13341296
    13351297        bs = block_bb_get(dev_handle);
    1336         bps = uint16_t_le2host(bs->bps);
    1337         spc = bs->spc;
    1338         bpc = bps * spc;
    13391298
    13401299        /*
     
    13451304         * value signalizing a smaller number of bytes written.
    13461305         */
    1347         bytes = min(len, bps - pos % bps);
    1348         if (bytes == bps)
     1306        bytes = min(len, BPS(bs) - pos % BPS(bs));
     1307        if (bytes == BPS(bs))
    13491308                flags |= BLOCK_FLAGS_NOREAD;
    13501309       
    1351         boundary = ROUND_UP(nodep->size, bpc);
     1310        boundary = ROUND_UP(nodep->size, BPC(bs));
    13521311        if (pos < boundary) {
    13531312                /*
     
    13641323                        return;
    13651324                }
    1366                 rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
     1325                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
    13671326                if (rc != EOK) {
    13681327                        (void) fat_node_put(fn);
     
    13711330                        return;
    13721331                }
    1373                 (void) async_data_write_finalize(callid, b->data + pos % bps,
    1374                     bytes);
     1332                (void) async_data_write_finalize(callid,
     1333                    b->data + pos % BPS(bs), bytes);
    13751334                b->dirty = true;                /* need to sync block */
    13761335                rc = block_put(b);
     
    13961355                fat_cluster_t mcl, lcl;
    13971356 
    1398                 nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
     1357                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    13991358                /* create an independent chain of nclsts clusters in all FATs */
    14001359                rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
     
    14151374                        return;
    14161375                }
    1417                 rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
    1418                     flags);
     1376                rc = _fat_block_get(&b, bs, dev_handle, lcl, NULL,
     1377                    (pos / BPS(bs)) % SPC(bs), flags);
    14191378                if (rc != EOK) {
    14201379                        (void) fat_free_clusters(bs, dev_handle, mcl);
     
    14241383                        return;
    14251384                }
    1426                 (void) async_data_write_finalize(callid, b->data + pos % bps,
    1427                     bytes);
     1385                (void) async_data_write_finalize(callid,
     1386                    b->data + pos % BPS(bs), bytes);
    14281387                b->dirty = true;                /* need to sync block */
    14291388                rc = block_put(b);
     
    14381397                 * node's cluster chain.
    14391398                 */
    1440                 rc = fat_append_clusters(bs, nodep, mcl);
     1399                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    14411400                if (rc != EOK) {
    14421401                        (void) fat_free_clusters(bs, dev_handle, mcl);
     
    14621421        fat_node_t *nodep;
    14631422        fat_bs_t *bs;
    1464         uint16_t bps;
    1465         uint8_t spc;
    1466         unsigned bpc;   /* bytes per cluster */
    14671423        int rc;
    14681424
     
    14791435
    14801436        bs = block_bb_get(dev_handle);
    1481         bps = uint16_t_le2host(bs->bps);
    1482         spc = bs->spc;
    1483         bpc = bps * spc;
    14841437
    14851438        if (nodep->size == size) {
     
    14911444                 */
    14921445                rc = EINVAL;
    1493         } else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
     1446        } else if (ROUND_UP(nodep->size, BPC(bs)) == ROUND_UP(size, BPC(bs))) {
    14941447                /*
    14951448                 * The node will be shrunk, but no clusters will be deallocated.
     
    15091462                        fat_cluster_t lastc;
    15101463                        rc = fat_cluster_walk(bs, dev_handle, nodep->firstc,
    1511                             &lastc, NULL, (size - 1) / bpc);
     1464                            &lastc, NULL, (size - 1) / BPC(bs));
    15121465                        if (rc != EOK)
    15131466                                goto out;
     
    15641517void fat_sync(ipc_callid_t rid, ipc_call_t *request)
    15651518{
    1566         /* Dummy implementation */
    1567         ipc_answer_0(rid, EOK);
     1519        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1520        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1521       
     1522        fs_node_t *fn;
     1523        int rc = fat_node_get(&fn, dev_handle, index);
     1524        if (rc != EOK) {
     1525                ipc_answer_0(rid, rc);
     1526                return;
     1527        }
     1528        if (!fn) {
     1529                ipc_answer_0(rid, ENOENT);
     1530                return;
     1531        }
     1532       
     1533        fat_node_t *nodep = FAT_NODE(fn);
     1534       
     1535        nodep->dirty = true;
     1536        rc = fat_node_sync(nodep);
     1537       
     1538        fat_node_put(fn);
     1539        ipc_answer_0(rid, rc);
    15681540}
    15691541
Note: See TracChangeset for help on using the changeset viewer.