Changeset ad4b32c in mainline for uspace/srv/fs/fat/fat_fat.c


Ignore:
Timestamp:
2009-09-04T21:50:59Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
309ede1
Parents:
7e266ff (diff), 40240b1 (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 mainline changes.

File:
1 edited

Legend:

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

    r7e266ff rad4b32c  
    6161 * @param dev_handle    Device handle of the device with the file.
    6262 * @param firstc        First cluster to start the walk with.
    63  * @param lastc         If non-NULL, output argument hodling the last cluster number visited.
     63 * @param lastc         If non-NULL, output argument hodling the last cluster
     64 *                      number visited.
     65 * @param numc          If non-NULL, output argument holding the number of
     66 *                      clusters seen during the walk.
    6467 * @param max_clusters  Maximum number of clusters to visit.   
    6568 *
    66  * @return              Number of clusters seen during the walk.
    67  */
    68 uint16_t
     69 * @return              EOK on success or a negative error code.
     70 */
     71int
    6972fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
    70     fat_cluster_t *lastc, uint16_t max_clusters)
     73    fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters)
    7174{
    7275        block_t *b;
     
    8487                if (lastc)
    8588                        *lastc = firstc;
    86                 return 0;
     89                if (numc)
     90                        *numc = 0;
     91                return EOK;
    8792        }
    8893
     
    98103                /* read FAT1 */
    99104                rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
    100                 assert(rc == EOK);
     105                if (rc != EOK)
     106                        return rc;
    101107                clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
    102108                assert(clst != FAT_CLST_BAD);
    103109                rc = block_put(b);
    104                 assert(rc == EOK);
     110                if (rc != EOK)
     111                        return rc;
    105112                clusters++;
    106113        }
     
    108115        if (lastc && clst < FAT_CLST_LAST1)
    109116                *lastc = clst;
    110 
    111         return clusters;
     117        if (numc)
     118                *numc = clusters;
     119
     120        return EOK;
    112121}
    113122
    114123/** Read block from file located on a FAT file system.
    115124 *
     125 * @param block         Pointer to a block pointer for storing result.
    116126 * @param bs            Buffer holding the boot sector of the file system.
    117127 * @param dev_handle    Device handle of the file system.
     
    121131 * @param flags         Flags passed to libblock.
    122132 *
    123  * @return              Block structure holding the requested block.
    124  */
    125 block_t *
    126 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
    127     bn_t bn, int flags)
    128 {
    129         block_t *b;
     133 * @return              EOK on success or a negative error code.
     134 */
     135int
     136_fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle,
     137    fat_cluster_t firstc, bn_t bn, int flags)
     138{
    130139        unsigned bps;
    131140        unsigned rscnt;         /* block address of the first FAT */
     
    134143        unsigned sf;
    135144        unsigned ssa;           /* size of the system area */
    136         unsigned clusters, max_clusters;
     145        uint16_t clusters;
     146        unsigned max_clusters;
    137147        fat_cluster_t lastc;
    138148        int rc;
     
    150160                /* root directory special case */
    151161                assert(bn < rds);
    152                 rc = block_get(&b, dev_handle, rscnt + bs->fatcnt * sf + bn,
     162                rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn,
    153163                    flags);
    154                 assert(rc == EOK);
    155                 return b;
     164                return rc;
    156165        }
    157166
    158167        max_clusters = bn / bs->spc;
    159         clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,
     168        rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters,
    160169            max_clusters);
     170        if (rc != EOK)
     171                return rc;
    161172        assert(clusters == max_clusters);
    162173
    163         rc = block_get(&b, dev_handle, ssa +
    164             (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags);
    165         assert(rc == EOK);
    166 
    167         return b;
     174        rc = block_get(block, dev_handle,
     175            ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags);
     176
     177        return rc;
    168178}
    169179
     
    177187 *                      this argument is ignored.
    178188 * @param pos           Position in the last node block.
    179  */
    180 void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
     189 *
     190 * @return              EOK on success or a negative error code.
     191 */
     192int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
    181193{
    182194        uint16_t bps;
     
    196208                int flags = (o % bps == 0) ?
    197209                    BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
    198                 b = fat_block_get(bs, nodep, o / bps, flags);
     210                rc = fat_block_get(&b, bs, nodep, o / bps, flags);
     211                if (rc != EOK)
     212                        return rc;
    199213                memset(b->data + o % bps, 0, bps - o % bps);
    200214                b->dirty = true;                /* need to sync node */
    201215                rc = block_put(b);
    202                 assert(rc == EOK);
     216                if (rc != EOK)
     217                        return rc;
    203218        }
    204219       
    205220        if (o >= pos)
    206                 return;
     221                return EOK;
    207222       
    208223        /* zero out the initial part of the new cluster chain */
    209224        for (o = boundary; o < pos; o += bps) {
    210                 b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,
     225                rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl,
    211226                    (o - boundary) / bps, BLOCK_FLAGS_NOREAD);
     227                if (rc != EOK)
     228                        return rc;
    212229                memset(b->data, 0, min(bps, pos - o));
    213230                b->dirty = true;                /* need to sync node */
    214231                rc = block_put(b);
    215                 assert(rc == EOK);
    216         }
     232                if (rc != EOK)
     233                        return rc;
     234        }
     235
     236        return EOK;
    217237}
    218238
     
    222242 * @param dev_handle    Device handle for the file system.
    223243 * @param clst          Cluster which to get.
    224  *
    225  * @return              Value found in the cluster.
    226  */
    227 fat_cluster_t
    228 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst)
     244 * @param value         Output argument holding the value of the cluster.
     245 *
     246 * @return              EOK or a negative error code.
     247 */
     248int
     249fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst,
     250    fat_cluster_t *value)
    229251{
    230252        block_t *b;
    231253        uint16_t bps;
    232254        uint16_t rscnt;
    233         fat_cluster_t *cp, value;
     255        fat_cluster_t *cp;
    234256        int rc;
    235257
     
    239261        rc = block_get(&b, dev_handle, rscnt +
    240262            (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
    241         assert(rc == EOK);
     263        if (rc != EOK)
     264                return rc;
    242265        cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
    243         value = uint16_t_le2host(*cp);
     266        *value = uint16_t_le2host(*cp);
    244267        rc = block_put(b);
    245         assert(rc == EOK);
    246        
    247         return value;
     268       
     269        return rc;
    248270}
    249271
     
    255277 * @param clst          Cluster which is to be set.
    256278 * @param value         Value to set the cluster with.
    257  */
    258 void
     279 *
     280 * @return              EOK on success or a negative error code.
     281 */
     282int
    259283fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
    260284    fat_cluster_t clst, fat_cluster_t value)
     
    274298        rc = block_get(&b, dev_handle, rscnt + sf * fatno +
    275299            (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
    276         assert(rc == EOK);
     300        if (rc != EOK)
     301                return rc;
    277302        cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
    278303        *cp = host2uint16_t_le(value);
    279304        b->dirty = true;                /* need to sync block */
    280305        rc = block_put(b);
    281         assert(rc == EOK);
     306        return rc;
    282307}
    283308
     
    288313 * @param lifo          Chain of allocated clusters.
    289314 * @param nclsts        Number of clusters in the lifo chain.
    290  */
    291 void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle,
     315 *
     316 * @return              EOK on success or a negative error code.
     317 */
     318int fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle,
    292319    fat_cluster_t *lifo, unsigned nclsts)
    293320{
    294321        uint8_t fatno;
    295322        unsigned c;
     323        int rc;
    296324
    297325        for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
    298326                for (c = 0; c < nclsts; c++) {
    299                         fat_set_cluster(bs, dev_handle, fatno, lifo[c],
     327                        rc = fat_set_cluster(bs, dev_handle, fatno, lifo[c],
    300328                            c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
     329                        if (rc != EOK)
     330                                return rc;
    301331                }
    302332        }
     333
     334        return EOK;
    303335}
    304336
     
    347379        for (b = 0, cl = 0; b < sf; b++) {
    348380                rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE);
     381                if (rc != EOK)
     382                        goto error;
    349383                for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
    350384                        fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
     
    362396                                        /* we are almost done */
    363397                                        rc = block_put(blk);
    364                                         assert(rc == EOK);
     398                                        if (rc != EOK)
     399                                                goto error;
    365400                                        /* update the shadow copies of FAT */
    366                                         fat_alloc_shadow_clusters(bs,
     401                                        rc = fat_alloc_shadow_clusters(bs,
    367402                                            dev_handle, lifo, nclsts);
     403                                        if (rc != EOK)
     404                                                goto error;
    368405                                        *mcl = lifo[found - 1];
    369406                                        *lcl = lifo[0];
     
    375412                }
    376413                rc = block_put(blk);
    377                 assert(rc == EOK);
     414                if (rc != EOK) {
     415error:
     416                        fibril_mutex_unlock(&fat_alloc_lock);
     417                        free(lifo);
     418                        return rc;
     419                }
    378420        }
    379421        fibril_mutex_unlock(&fat_alloc_lock);
     
    384426         */
    385427        while (found--) {
    386                 fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
     428                rc = fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
    387429                    FAT_CLST_RES0);
     430                if (rc != EOK) {
     431                        free(lifo);
     432                        return rc;
     433                }
    388434        }
    389435       
     
    397443 * @param dev_handle    Device handle of the file system.
    398444 * @param firstc        First cluster in the chain which is to be freed.
    399  */
    400 void
     445 *
     446 * @return              EOK on success or a negative return code.
     447 */
     448int
    401449fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc)
    402450{
    403451        unsigned fatno;
    404452        fat_cluster_t nextc;
     453        int rc;
    405454
    406455        /* Mark all clusters in the chain as free in all copies of FAT. */
    407456        while (firstc < FAT_CLST_LAST1) {
    408457                assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD);
    409                 nextc = fat_get_cluster(bs, dev_handle, firstc);
    410                 for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
    411                         fat_set_cluster(bs, dev_handle, fatno, firstc,
     458                rc = fat_get_cluster(bs, dev_handle, firstc, &nextc);
     459                if (rc != EOK)
     460                        return rc;
     461                for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
     462                        rc = fat_set_cluster(bs, dev_handle, fatno, firstc,
    412463                            FAT_CLST_RES0);
     464                        if (rc != EOK)
     465                                return rc;
     466                }
     467
    413468                firstc = nextc;
    414469        }
     470
     471        return EOK;
    415472}
    416473
     
    420477 * @param nodep         Node representing the file.
    421478 * @param mcl           First cluster of the cluster chain to append.
    422  */
    423 void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
     479 *
     480 * @return              EOK on success or a negative error code.
     481 */
     482int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
    424483{
    425484        dev_handle_t dev_handle = nodep->idx->dev_handle;
    426485        fat_cluster_t lcl;
     486        uint16_t numc;
    427487        uint8_t fatno;
    428 
    429         if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
    430             (uint16_t) -1) == 0) {
     488        int rc;
     489
     490        rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc,
     491            (uint16_t) -1);
     492        if (rc != EOK)
     493                return rc;
     494
     495        if (numc == 0) {
    431496                /* No clusters allocated to the node yet. */
    432497                nodep->firstc = mcl;
    433498                nodep->dirty = true;            /* need to sync node */
    434                 return;
    435         }
    436 
    437         for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
    438                 fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
     499                return EOK;
     500        }
     501
     502        for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
     503                rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl,
     504                    mcl);
     505                if (rc != EOK)
     506                        return rc;
     507        }
     508
     509        return EOK;
    439510}
    440511
     
    446517 *                      argument is FAT_CLST_RES0, then all clusters will
    447518 *                      be chopped off.
    448  */
    449 void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
    450 {
     519 *
     520 * @return              EOK on success or a negative return code.
     521 */
     522int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
     523{
     524        int rc;
     525
    451526        dev_handle_t dev_handle = nodep->idx->dev_handle;
    452527        if (lastc == FAT_CLST_RES0) {
    453528                /* The node will have zero size and no clusters allocated. */
    454                 fat_free_clusters(bs, dev_handle, nodep->firstc);
     529                rc = fat_free_clusters(bs, dev_handle, nodep->firstc);
     530                if (rc != EOK)
     531                        return rc;
    455532                nodep->firstc = FAT_CLST_RES0;
    456533                nodep->dirty = true;            /* need to sync node */
     
    459536                unsigned fatno;
    460537
    461                 nextc = fat_get_cluster(bs, dev_handle, lastc);
     538                rc = fat_get_cluster(bs, dev_handle, lastc, &nextc);
     539                if (rc != EOK)
     540                        return rc;
    462541
    463542                /* Terminate the cluster chain in all copies of FAT. */
    464                 for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
    465                         fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1);
     543                for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
     544                        rc = fat_set_cluster(bs, dev_handle, fatno, lastc,
     545                            FAT_CLST_LAST1);
     546                        if (rc != EOK)
     547                                return rc;
     548                }
    466549
    467550                /* Free all following clusters. */
    468                 fat_free_clusters(bs, dev_handle, nextc);
    469         }
    470 }
    471 
    472 void
     551                rc = fat_free_clusters(bs, dev_handle, nextc);
     552                if (rc != EOK)
     553                        return rc;
     554        }
     555
     556        return EOK;
     557}
     558
     559int
    473560fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c)
    474561{
     
    481568       
    482569        for (i = 0; i < bs->spc; i++) {
    483                 b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD);
     570                rc = _fat_block_get(&b, bs, dev_handle, c, i,
     571                    BLOCK_FLAGS_NOREAD);
     572                if (rc != EOK)
     573                        return rc;
    484574                memset(b->data, 0, bps);
    485575                b->dirty = true;
    486576                rc = block_put(b);
    487                 assert(rc == EOK);
    488         }
     577                if (rc != EOK)
     578                        return rc;
     579        }
     580
     581        return EOK;
    489582}
    490583
Note: See TracChangeset for help on using the changeset viewer.