Changeset 9a1d8ab in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2010-07-28T15:27:13Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0b749a3, 482dde7, c0e1be7
Parents:
14f2100 (diff), dba4a23 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/fs.

This merge adds two important optimizations for appending files and doing
sequential I/O on them.

File:
1 edited

Legend:

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

    r14f2100 r9a1d8ab  
    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;
     
    377374        fibril_mutex_lock(&parentp->idx->lock);
    378375        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        blocks = parentp->size / BPS(bs);
    382377        for (i = 0; i < blocks; i++) {
    383378                rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     
    386381                        return rc;
    387382                }
    388                 for (j = 0; j < dps; j++) {
     383                for (j = 0; j < DPS(bs); j++) {
    389384                        d = ((fat_dentry_t *)b->data) + j;
    390385                        switch (fat_classify_dentry(d)) {
     
    414409                                fat_idx_t *idx = fat_idx_get_by_pos(
    415410                                    parentp->idx->dev_handle, parentp->firstc,
    416                                     i * dps + j);
     411                                    i * DPS(bs) + j);
    417412                                fibril_mutex_unlock(&parentp->idx->lock);
    418413                                if (!idx) {
     
    513508        fat_bs_t *bs;
    514509        fat_cluster_t mcl, lcl;
    515         uint16_t bps;
    516510        int rc;
    517511
    518512        bs = block_bb_get(dev_handle);
    519         bps = uint16_t_le2host(bs->bps);
    520513        if (flags & L_DIRECTORY) {
    521514                /* allocate a cluster */
     
    546539                nodep->type = FAT_DIRECTORY;
    547540                nodep->firstc = mcl;
    548                 nodep->size = bps * bs->spc;
     541                nodep->size = BPS(bs) * SPC(bs);
    549542        } else {
    550543                nodep->type = FAT_FILE;
     
    609602        block_t *b;
    610603        unsigned i, j;
    611         uint16_t bps;
    612         unsigned dps;
    613604        unsigned blocks;
    614605        fat_cluster_t mcl, lcl;
     
    640631        fibril_mutex_lock(&parentp->idx->lock);
    641632        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;
     633
     634        blocks = parentp->size / BPS(bs);
    646635
    647636        for (i = 0; i < blocks; i++) {
     
    651640                        return rc;
    652641                }
    653                 for (j = 0; j < dps; j++) {
     642                for (j = 0; j < DPS(bs); j++) {
    654643                        d = ((fat_dentry_t *)b->data) + j;
    655644                        switch (fat_classify_dentry(d)) {
     
    691680                return rc;
    692681        }
    693         rc = fat_append_clusters(bs, parentp, mcl);
     682        rc = fat_append_clusters(bs, parentp, mcl, lcl);
    694683        if (rc != EOK) {
    695684                (void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl);
     
    697686                return rc;
    698687        }
    699         parentp->size += bps * bs->spc;
     688        parentp->size += BPS(bs) * SPC(bs);
    700689        parentp->dirty = true;          /* need to sync node */
    701690        rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
     
    771760
    772761        childp->idx->pfc = parentp->firstc;
    773         childp->idx->pdi = i * dps + j;
     762        childp->idx->pdi = i * DPS(bs) + j;
    774763        fibril_mutex_unlock(&childp->idx->lock);
    775764
     
    793782        fat_bs_t *bs;
    794783        fat_dentry_t *d;
    795         uint16_t bps;
    796784        block_t *b;
    797785        bool has_children;
     
    812800        fibril_mutex_lock(&childp->idx->lock);
    813801        bs = block_bb_get(childp->idx->dev_handle);
    814         bps = uint16_t_le2host(bs->bps);
    815802
    816803        rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc,
    817             (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
     804            NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
    818805            BLOCK_FLAGS_NONE);
    819806        if (rc != EOK)
    820807                goto error;
    821808        d = (fat_dentry_t *)b->data +
    822             (childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
     809            (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
    823810        /* mark the dentry as not-currently-used */
    824811        d->name[0] = FAT_DENTRY_ERASED;
     
    852839        fat_bs_t *bs;
    853840        fat_node_t *nodep = FAT_NODE(fn);
    854         unsigned bps;
    855         unsigned dps;
    856841        unsigned blocks;
    857842        block_t *b;
     
    866851        fibril_mutex_lock(&nodep->idx->lock);
    867852        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;
     853
     854        blocks = nodep->size / BPS(bs);
    872855
    873856        for (i = 0; i < blocks; i++) {
     
    879862                        return rc;
    880863                }
    881                 for (j = 0; j < dps; j++) {
     864                for (j = 0; j < DPS(bs); j++) {
    882865                        d = ((fat_dentry_t *)b->data) + j;
    883866                        switch (fat_classify_dentry(d)) {
     
    976959        enum cache_mode cmode;
    977960        fat_bs_t *bs;
    978         uint16_t bps;
    979         uint16_t rde;
    980961       
    981962        /* Accept the mount options */
     
    1014995        bs = block_bb_get(dev_handle);
    1015996       
    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) {
     997        if (BPS(bs) != BS_SIZE) {
    1021998                block_fini(dev_handle);
    1022999                ipc_answer_0(rid, ENOTSUP);
     
    10251002
    10261003        /* Initialize the block cache */
    1027         rc = block_cache_init(dev_handle, bps, 0 /* XXX */, cmode);
     1004        rc = block_cache_init(dev_handle, BPS(bs), 0 /* XXX */, cmode);
    10281005        if (rc != EOK) {
    10291006                block_fini(dev_handle);
     
    10871064        rootp->refcnt = 1;
    10881065        rootp->lnkcnt = 0;      /* FS root is not linked */
    1089         rootp->size = rde * sizeof(fat_dentry_t);
     1066        rootp->size = RDE(bs) * sizeof(fat_dentry_t);
    10901067        rootp->idx = ridxp;
    10911068        ridxp->nodep = rootp;
     
    11651142        fat_node_t *nodep;
    11661143        fat_bs_t *bs;
    1167         uint16_t bps;
    11681144        size_t bytes;
    11691145        block_t *b;
     
    11911167
    11921168        bs = block_bb_get(dev_handle);
    1193         bps = uint16_t_le2host(bs->bps);
    11941169
    11951170        if (nodep->type == FAT_FILE) {
     
    12041179                        (void) async_data_read_finalize(callid, NULL, 0);
    12051180                } else {
    1206                         bytes = min(len, bps - pos % bps);
     1181                        bytes = min(len, BPS(bs) - pos % BPS(bs));
    12071182                        bytes = min(bytes, nodep->size - pos);
    1208                         rc = fat_block_get(&b, bs, nodep, pos / bps,
     1183                        rc = fat_block_get(&b, bs, nodep, pos / BPS(bs),
    12091184                            BLOCK_FLAGS_NONE);
    12101185                        if (rc != EOK) {
     
    12141189                                return;
    12151190                        }
    1216                         (void) async_data_read_finalize(callid, b->data + pos % bps,
    1217                             bytes);
     1191                        (void) async_data_read_finalize(callid,
     1192                            b->data + pos % BPS(bs), bytes);
    12181193                        rc = block_put(b);
    12191194                        if (rc != EOK) {
     
    12301205
    12311206                assert(nodep->type == FAT_DIRECTORY);
    1232                 assert(nodep->size % bps == 0);
    1233                 assert(bps % sizeof(fat_dentry_t) == 0);
     1207                assert(nodep->size % BPS(bs) == 0);
     1208                assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
    12341209
    12351210                /*
     
    12391214                 * the position pointer accordingly.
    12401215                 */
    1241                 bnum = (pos * sizeof(fat_dentry_t)) / bps;
    1242                 while (bnum < nodep->size / bps) {
     1216                bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
     1217                while (bnum < nodep->size / BPS(bs)) {
    12431218                        aoff64_t o;
    12441219
     
    12471222                        if (rc != EOK)
    12481223                                goto err;
    1249                         for (o = pos % (bps / sizeof(fat_dentry_t));
    1250                             o < bps / sizeof(fat_dentry_t);
     1224                        for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
     1225                            o < BPS(bs) / sizeof(fat_dentry_t);
    12511226                            o++, pos++) {
    12521227                                d = ((fat_dentry_t *)b->data) + o;
     
    13061281        size_t bytes, size;
    13071282        block_t *b;
    1308         uint16_t bps;
    1309         unsigned spc;
    1310         unsigned bpc;           /* bytes per cluster */
    13111283        aoff64_t boundary;
    13121284        int flags = BLOCK_FLAGS_NONE;
     
    13341306
    13351307        bs = block_bb_get(dev_handle);
    1336         bps = uint16_t_le2host(bs->bps);
    1337         spc = bs->spc;
    1338         bpc = bps * spc;
    13391308
    13401309        /*
     
    13451314         * value signalizing a smaller number of bytes written.
    13461315         */
    1347         bytes = min(len, bps - pos % bps);
    1348         if (bytes == bps)
     1316        bytes = min(len, BPS(bs) - pos % BPS(bs));
     1317        if (bytes == BPS(bs))
    13491318                flags |= BLOCK_FLAGS_NOREAD;
    13501319       
    1351         boundary = ROUND_UP(nodep->size, bpc);
     1320        boundary = ROUND_UP(nodep->size, BPC(bs));
    13521321        if (pos < boundary) {
    13531322                /*
     
    13641333                        return;
    13651334                }
    1366                 rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
     1335                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
    13671336                if (rc != EOK) {
    13681337                        (void) fat_node_put(fn);
     
    13711340                        return;
    13721341                }
    1373                 (void) async_data_write_finalize(callid, b->data + pos % bps,
    1374                     bytes);
     1342                (void) async_data_write_finalize(callid,
     1343                    b->data + pos % BPS(bs), bytes);
    13751344                b->dirty = true;                /* need to sync block */
    13761345                rc = block_put(b);
     
    13961365                fat_cluster_t mcl, lcl;
    13971366 
    1398                 nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
     1367                nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
    13991368                /* create an independent chain of nclsts clusters in all FATs */
    14001369                rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
     
    14151384                        return;
    14161385                }
    1417                 rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
    1418                     flags);
     1386                rc = _fat_block_get(&b, bs, dev_handle, lcl, NULL,
     1387                    (pos / BPS(bs)) % SPC(bs), flags);
    14191388                if (rc != EOK) {
    14201389                        (void) fat_free_clusters(bs, dev_handle, mcl);
     
    14241393                        return;
    14251394                }
    1426                 (void) async_data_write_finalize(callid, b->data + pos % bps,
    1427                     bytes);
     1395                (void) async_data_write_finalize(callid,
     1396                    b->data + pos % BPS(bs), bytes);
    14281397                b->dirty = true;                /* need to sync block */
    14291398                rc = block_put(b);
     
    14381407                 * node's cluster chain.
    14391408                 */
    1440                 rc = fat_append_clusters(bs, nodep, mcl);
     1409                rc = fat_append_clusters(bs, nodep, mcl, lcl);
    14411410                if (rc != EOK) {
    14421411                        (void) fat_free_clusters(bs, dev_handle, mcl);
     
    14621431        fat_node_t *nodep;
    14631432        fat_bs_t *bs;
    1464         uint16_t bps;
    1465         uint8_t spc;
    1466         unsigned bpc;   /* bytes per cluster */
    14671433        int rc;
    14681434
     
    14791445
    14801446        bs = block_bb_get(dev_handle);
    1481         bps = uint16_t_le2host(bs->bps);
    1482         spc = bs->spc;
    1483         bpc = bps * spc;
    14841447
    14851448        if (nodep->size == size) {
     
    14911454                 */
    14921455                rc = EINVAL;
    1493         } else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
     1456        } else if (ROUND_UP(nodep->size, BPC(bs)) == ROUND_UP(size, BPC(bs))) {
    14941457                /*
    14951458                 * The node will be shrunk, but no clusters will be deallocated.
     
    15091472                        fat_cluster_t lastc;
    15101473                        rc = fat_cluster_walk(bs, dev_handle, nodep->firstc,
    1511                             &lastc, NULL, (size - 1) / bpc);
     1474                            &lastc, NULL, (size - 1) / BPC(bs));
    15121475                        if (rc != EOK)
    15131476                                goto out;
Note: See TracChangeset for help on using the changeset viewer.