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


Ignore:
Timestamp:
2011-08-24T20:10:43Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eb660787
Parents:
7fadb65 (diff), 842a2d2 (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:~romanenko-oleg/helenos/fat.

File:
1 edited

Legend:

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

    r7fadb65 r375ab5e  
    11/*
    22 * Copyright (c) 2008 Jakub Jermar
     3 * Copyright (c) 2011 Oleg Romanenko
    34 * All rights reserved.
    45 *
     
    2930/** @addtogroup fs
    3031 * @{
    31  */ 
     32 */
    3233
    3334/**
     
    5455 * primitive boot sector members.
    5556 */
    56 #define RDS(bs)         ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \
    57                         (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0)
    58 #define SSA(bs)         (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs))
    59 
    6057#define CLBN2PBN(bs, cl, bn) \
    6158        (SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs)))
     59
     60#define IS_ODD(number)  (number & 0x1)
    6261
    6362/**
     
    6564 * during allocation of clusters. The lock does not have to be held durring
    6665 * deallocation of clusters.
    67  */ 
     66 */
    6867static FIBRIL_MUTEX_INITIALIZE(fat_alloc_lock);
    6968
     
    7776 * @param numc          If non-NULL, output argument holding the number of
    7877 *                      clusters seen during the walk.
    79  * @param max_clusters  Maximum number of clusters to visit.   
     78 * @param max_clusters  Maximum number of clusters to visit.
    8079 *
    8180 * @return              EOK on success or a negative error code.
    8281 */
    83 int 
     82int
    8483fat_cluster_walk(fat_bs_t *bs, service_id_t service_id, fat_cluster_t firstc,
    85     fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters)
    86 {
    87         block_t *b;
    88         uint16_t clusters = 0;
    89         fat_cluster_t clst = firstc;
     84    fat_cluster_t *lastc, uint32_t *numc, uint32_t max_clusters)
     85{
     86        uint32_t clusters = 0;
     87        fat_cluster_t clst = firstc, clst_last1 = FAT_CLST_LAST1(bs);
     88        fat_cluster_t clst_bad = FAT_CLST_BAD(bs);
    9089        int rc;
    9190
     
    9998        }
    10099
    101         while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
    102                 aoff64_t fsec;  /* sector offset relative to FAT1 */
    103                 unsigned fidx;  /* FAT1 entry index */
    104 
     100        while (clst < clst_last1 && clusters < max_clusters) {
    105101                assert(clst >= FAT_CLST_FIRST);
    106102                if (lastc)
    107103                        *lastc = clst;  /* remember the last cluster number */
    108                 fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs);
    109                 fidx = clst % (BPS(bs) / sizeof(fat_cluster_t));
     104
    110105                /* read FAT1 */
    111                 rc = block_get(&b, service_id, RSCNT(bs) + fsec,
    112                     BLOCK_FLAGS_NONE);
    113                 if (rc != EOK)
    114                         return rc;
    115                 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
    116                 assert(clst != FAT_CLST_BAD);
    117                 rc = block_put(b);
    118                 if (rc != EOK)
    119                         return rc;
     106                rc = fat_get_cluster(bs, service_id, FAT1, clst, &clst);
     107                if (rc != EOK)
     108                        return rc;
     109
     110                assert(clst != clst_bad);
    120111                clusters++;
    121112        }
    122113
    123         if (lastc && clst < FAT_CLST_LAST1)
     114        if (lastc && clst < clst_last1)
    124115                *lastc = clst;
    125116        if (numc)
     
    151142                return ELIMIT;
    152143
    153         if (nodep->firstc == FAT_CLST_ROOT)
     144        if (!FAT_IS_FAT32(bs) && nodep->firstc == FAT_CLST_ROOT)
    154145                goto fall_through;
    155146
     
    178169        if (rc != EOK)
    179170                return rc;
    180        
     171
    181172        /*
    182173         * Update the "current" cluster cache.
     
    198189 * @param clp           If not NULL, address where the cluster containing bn
    199190 *                      will be stored.
    200  *                      stored 
     191 *                      stored
    201192 * @param bn            Block number.
    202193 * @param flags         Flags passed to libblock.
     
    208199    fat_cluster_t fcl, fat_cluster_t *clp, aoff64_t bn, int flags)
    209200{
    210         uint16_t clusters;
    211         unsigned max_clusters;
     201        uint32_t clusters;
     202        uint32_t max_clusters;
    212203        fat_cluster_t c;
    213204        int rc;
     
    219210                return ELIMIT;
    220211
    221         if (fcl == FAT_CLST_ROOT) {
     212        if (!FAT_IS_FAT32(bs) && fcl == FAT_CLST_ROOT) {
    222213                /* root directory special case */
    223214                assert(bn < RDS(bs));
     
    275266                        return rc;
    276267        }
    277        
     268
    278269        if (o >= pos)
    279270                return EOK;
    280        
     271
    281272        /* zero out the initial part of the new cluster chain */
    282273        for (o = boundary; o < pos; o += BPS(bs)) {
     
    295286}
    296287
    297 /** Get cluster from the first FAT.
     288/** Get cluster from the first FAT. FAT12 version
    298289 *
    299290 * @param bs            Buffer holding the boot sector for the file system.
     
    305296 */
    306297int
     298fat_get_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     299    fat_cluster_t clst, fat_cluster_t *value)
     300{
     301        block_t *b, *b1;
     302        uint16_t byte1, byte2;
     303        aoff64_t offset;
     304        int rc;
     305
     306        offset = (clst + clst/2);
     307        if (offset / BPS(bs) >= SF(bs))
     308                return ERANGE;
     309
     310        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
     311            offset / BPS(bs), BLOCK_FLAGS_NONE);
     312        if (rc != EOK)
     313                return rc;
     314
     315        byte1 = ((uint8_t*) b->data)[offset % BPS(bs)];
     316        /* This cluster access spans a sector boundary. Check only for FAT12 */
     317        if ((offset % BPS(bs)) + 1 == BPS(bs)) {
     318                /* Is it last sector of FAT? */
     319                if (offset / BPS(bs) < SF(bs)) {
     320                        /* No. Reading next sector */
     321                        rc = block_get(&b1, service_id, 1 + RSCNT(bs) +
     322                                SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE);
     323                        if (rc != EOK) {
     324                                block_put(b);
     325                                return rc;
     326                        }
     327                        /*
     328                        * Combining value with last byte of current sector and
     329                        * first byte of next sector
     330                        */
     331                        byte2 = ((uint8_t*) b1->data)[0];
     332
     333                        rc = block_put(b1);
     334                        if (rc != EOK) {
     335                                block_put(b);
     336                                return rc;
     337                        }
     338                }
     339                else {
     340                        /* Yes. It is last sector of FAT */
     341                        block_put(b);
     342                        return ERANGE;
     343                }
     344        }
     345        else
     346                byte2 = ((uint8_t*) b->data)[(offset % BPS(bs))+1];
     347
     348        *value = uint16_t_le2host(byte1 | (byte2 << 8));
     349        if (IS_ODD(clst))
     350                *value = (*value) >> 4;
     351        else
     352                *value = (*value) & FAT12_MASK;
     353       
     354        rc = block_put(b);
     355        return rc;
     356}
     357
     358/** Get cluster from the first FAT. FAT16 version
     359 *
     360 * @param bs            Buffer holding the boot sector for the file system.
     361 * @param service_id    Service ID for the file system.
     362 * @param clst          Cluster which to get.
     363 * @param value         Output argument holding the value of the cluster.
     364 *
     365 * @return              EOK or a negative error code.
     366 */
     367int
     368fat_get_cluster_fat16(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     369    fat_cluster_t clst, fat_cluster_t *value)
     370{
     371        block_t *b;
     372        aoff64_t offset;
     373        int rc;
     374
     375        offset = (clst * FAT16_CLST_SIZE);
     376
     377        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
     378            offset / BPS(bs), BLOCK_FLAGS_NONE);
     379        if (rc != EOK)
     380                return rc;
     381
     382        *value = uint16_t_le2host(*(uint16_t *)(b->data + offset % BPS(bs)));
     383
     384        rc = block_put(b);
     385
     386        return rc;
     387}
     388
     389/** Get cluster from the first FAT. FAT32 version
     390 *
     391 * @param bs            Buffer holding the boot sector for the file system.
     392 * @param service_id    Service ID for the file system.
     393 * @param clst          Cluster which to get.
     394 * @param value         Output argument holding the value of the cluster.
     395 *
     396 * @return              EOK or a negative error code.
     397 */
     398int
     399fat_get_cluster_fat32(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     400    fat_cluster_t clst, fat_cluster_t *value)
     401{
     402        block_t *b;
     403        aoff64_t offset;
     404        int rc;
     405
     406        offset = (clst * FAT32_CLST_SIZE);
     407
     408        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
     409            offset / BPS(bs), BLOCK_FLAGS_NONE);
     410        if (rc != EOK)
     411                return rc;
     412
     413        *value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))) & FAT32_MASK;
     414
     415        rc = block_put(b);
     416
     417        return rc;
     418}
     419
     420
     421/** Get cluster from the first FAT.
     422 *
     423 * @param bs            Buffer holding the boot sector for the file system.
     424 * @param service_id    Service ID for the file system.
     425 * @param clst          Cluster which to get.
     426 * @param value         Output argument holding the value of the cluster.
     427 *
     428 * @return              EOK or a negative error code.
     429 */
     430int
    307431fat_get_cluster(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
    308432    fat_cluster_t clst, fat_cluster_t *value)
    309433{
    310         block_t *b;
    311         fat_cluster_t *cp;
    312         int rc;
    313 
     434        int rc;
     435
     436        assert(fatno < FATCNT(bs));
     437
     438        if (FAT_IS_FAT12(bs)) {
     439                rc = fat_get_cluster_fat12(bs, service_id, fatno, clst, value);
     440        }
     441        else {
     442                if (FAT_IS_FAT32(bs))
     443                        rc = fat_get_cluster_fat32(bs, service_id, fatno, clst, value);
     444                else
     445                        rc = fat_get_cluster_fat16(bs, service_id, fatno, clst, value);
     446        }
     447
     448        return rc;
     449}
     450
     451/** Set cluster in one instance of FAT. FAT12 version.
     452 *
     453 * @param bs            Buffer holding the boot sector for the file system.
     454 * @param service_id    Service ID for the file system.
     455 * @param fatno         Number of the FAT instance where to make the change.
     456 * @param clst          Cluster which is to be set.
     457 * @param value         Value to set the cluster with.
     458 *
     459 * @return              EOK on success or a negative error code.
     460 */
     461int
     462fat_set_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     463    fat_cluster_t clst, fat_cluster_t value)
     464{
     465        block_t *b, *b1=NULL;
     466        aoff64_t offset;
     467        uint16_t byte1, byte2;
     468        int rc;
     469
     470        offset = (clst + clst/2);
     471        if (offset / BPS(bs) >= SF(bs))
     472                return ERANGE;
     473       
    314474        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
    315             (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
     475            offset / BPS(bs), BLOCK_FLAGS_NONE);
    316476        if (rc != EOK)
    317477                return rc;
    318         cp = (fat_cluster_t *)b->data +
    319             clst % (BPS(bs) / sizeof(fat_cluster_t));
    320         *value = uint16_t_le2host(*cp);
     478
     479        byte1 = ((uint8_t*) b->data)[offset % BPS(bs)];
     480        bool border = false;
     481        /* This cluster access spans a sector boundary. Check only for FAT12 */
     482        if ((offset % BPS(bs))+1 == BPS(bs)) {
     483                /* Is it last sector of FAT? */
     484                if (offset / BPS(bs) < SF(bs)) {
     485                        /* No. Reading next sector */
     486                        rc = block_get(&b1, service_id, 1 + RSCNT(bs) +
     487                                SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE);
     488                        if (rc != EOK) {
     489                                block_put(b);
     490                                return rc;
     491                        }
     492                        /*
     493                         * Combining value with last byte of current sector and
     494                         * first byte of next sector
     495                         */
     496                        byte2 = ((uint8_t*) b1->data)[0];
     497                        border = true;
     498                }
     499                else {
     500                        /* Yes. It is last sector of fat */
     501                        block_put(b);
     502                        return ERANGE;
     503                }
     504        }
     505        else
     506                byte2 = ((uint8_t*) b->data)[(offset % BPS(bs))+1];
     507
     508        if (IS_ODD(clst)) {
     509                byte1 &= 0x0f;
     510                byte2 = 0;
     511                value = (value << 4);
     512        } else {
     513                byte1 = 0;
     514                byte2 &= 0xf0;
     515                value &= FAT12_MASK;
     516        }
     517
     518        byte1 = byte1 | (value & 0xff);
     519        byte2 = byte2 | (value >> 8);
     520
     521        ((uint8_t*) b->data)[(offset % BPS(bs))] = byte1;
     522        if (border) {
     523                ((uint8_t*) b1->data)[0] = byte2;
     524
     525                b1->dirty = true;
     526                rc = block_put(b1);
     527                if (rc != EOK) {
     528                        block_put(b);
     529                        return rc;
     530                }
     531        } else
     532                ((uint8_t*) b->data)[(offset % BPS(bs))+1] = byte2;
     533
     534        b->dirty = true;        /* need to sync block */
    321535        rc = block_put(b);
    322        
     536        return rc;
     537}
     538
     539/** Set cluster in one instance of FAT. FAT16 version.
     540 *
     541 * @param bs            Buffer holding the boot sector for the file system.
     542 * @param service_id    Service ID for the file system.
     543 * @param fatno         Number of the FAT instance where to make the change.
     544 * @param clst          Cluster which is to be set.
     545 * @param value         Value to set the cluster with.
     546 *
     547 * @return              EOK on success or a negative error code.
     548 */
     549int
     550fat_set_cluster_fat16(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     551    fat_cluster_t clst, fat_cluster_t value)
     552{
     553        block_t *b;
     554        aoff64_t offset;
     555        int rc;
     556
     557        offset = (clst * FAT16_CLST_SIZE);
     558
     559        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
     560            offset / BPS(bs), BLOCK_FLAGS_NONE);
     561        if (rc != EOK)
     562                return rc;
     563
     564        *(uint16_t *)(b->data + offset % BPS(bs)) = host2uint16_t_le(value);
     565
     566        b->dirty = true;        /* need to sync block */
     567        rc = block_put(b);
     568        return rc;
     569}
     570
     571/** Set cluster in one instance of FAT. FAT32 version.
     572 *
     573 * @param bs            Buffer holding the boot sector for the file system.
     574 * @param service_id    Service ID for the file system.
     575 * @param fatno         Number of the FAT instance where to make the change.
     576 * @param clst          Cluster which is to be set.
     577 * @param value         Value to set the cluster with.
     578 *
     579 * @return              EOK on success or a negative error code.
     580 */
     581int
     582fat_set_cluster_fat32(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     583    fat_cluster_t clst, fat_cluster_t value)
     584{
     585        block_t *b;
     586        aoff64_t offset;
     587        int rc;
     588        fat_cluster_t temp;
     589
     590        offset = (clst * FAT32_CLST_SIZE);
     591
     592        rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
     593            offset / BPS(bs), BLOCK_FLAGS_NONE);
     594        if (rc != EOK)
     595                return rc;
     596
     597        temp = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs)));
     598        temp &= 0xf0000000;
     599        temp |= (value & FAT32_MASK);
     600        *(uint32_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(temp);
     601
     602        b->dirty = true;        /* need to sync block */
     603        rc = block_put(b);
    323604        return rc;
    324605}
     
    338619    fat_cluster_t clst, fat_cluster_t value)
    339620{
    340         block_t *b;
    341         fat_cluster_t *cp;
    342621        int rc;
    343622
    344623        assert(fatno < FATCNT(bs));
    345         rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
    346             (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
    347         if (rc != EOK)
    348                 return rc;
    349         cp = (fat_cluster_t *)b->data +
    350             clst % (BPS(bs) / sizeof(fat_cluster_t));
    351         *cp = host2uint16_t_le(value);
    352         b->dirty = true;                /* need to sync block */
    353         rc = block_put(b);
     624
     625        if (FAT_IS_FAT12(bs))
     626                rc = fat_set_cluster_fat12(bs, service_id, fatno, clst, value);
     627        else if (FAT_IS_FAT32(bs))
     628                rc = fat_set_cluster_fat32(bs, service_id, fatno, clst, value);
     629        else
     630                rc = fat_set_cluster_fat16(bs, service_id, fatno, clst, value);
     631
    354632        return rc;
    355633}
     
    369647        uint8_t fatno;
    370648        unsigned c;
    371         int rc;
    372 
    373         for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
     649        fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs);
     650        int rc;
     651
     652        for (fatno = FAT1 + 1; fatno < FATCNT(bs); fatno++) {
    374653                for (c = 0; c < nclsts; c++) {
    375654                        rc = fat_set_cluster(bs, service_id, fatno, lifo[c],
    376                             c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
     655                            c == 0 ? clst_last1 : lifo[c - 1]);
    377656                        if (rc != EOK)
    378657                                return rc;
     
    404683    fat_cluster_t *mcl, fat_cluster_t *lcl)
    405684{
    406         block_t *blk;
    407         fat_cluster_t *lifo;    /* stack for storing free cluster numbers */
    408         unsigned found = 0;     /* top of the free cluster number stack */
    409         unsigned b, c, cl;
    410         int rc;
     685        fat_cluster_t *lifo;    /* stack for storing free cluster numbers */
     686        unsigned found = 0;     /* top of the free cluster number stack */
     687        fat_cluster_t clst, value, clst_last1 = FAT_CLST_LAST1(bs);
     688        int rc = EOK;
    411689
    412690        lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
    413691        if (!lifo)
    414692                return ENOMEM;
    415        
    416693        /*
    417694         * Search FAT1 for unused clusters.
    418695         */
    419696        fibril_mutex_lock(&fat_alloc_lock);
    420         for (b = 0, cl = 0; b < SF(bs); b++) {
    421                 rc = block_get(&blk, service_id, RSCNT(bs) + b,
    422                     BLOCK_FLAGS_NONE);
    423                 if (rc != EOK)
    424                         goto error;
    425                 for (c = 0; c < BPS(bs) / sizeof(fat_cluster_t); c++, cl++) {
    426                         /*
    427                          * Check if the entire cluster is physically there.
    428                          * This check becomes necessary when the file system is
    429                          * created with fewer total sectors than how many is
    430                          * inferred from the size of the file allocation table
    431                          * or when the last cluster ends beyond the end of the
    432                          * device.
    433                          */
    434                         if ((cl >= FAT_CLST_FIRST) &&
    435                             CLBN2PBN(bs, cl, SPC(bs) - 1) >= TS(bs)) {
    436                                 rc = block_put(blk);
    437                                 if (rc != EOK)
    438                                         goto error;
    439                                 goto out;
    440                         }
    441 
    442                         fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
    443                         if (uint16_t_le2host(*clst) == FAT_CLST_RES0) {
    444                                 /*
    445                                  * The cluster is free. Put it into our stack
    446                                  * of found clusters and mark it as non-free.
    447                                  */
    448                                 lifo[found] = cl;
    449                                 *clst = (found == 0) ?
    450                                     host2uint16_t_le(FAT_CLST_LAST1) :
    451                                     host2uint16_t_le(lifo[found - 1]);
    452                                 blk->dirty = true;      /* need to sync block */
    453                                 if (++found == nclsts) {
    454                                         /* we are almost done */
    455                                         rc = block_put(blk);
    456                                         if (rc != EOK)
    457                                                 goto error;
    458                                         /* update the shadow copies of FAT */
    459                                         rc = fat_alloc_shadow_clusters(bs,
    460                                             service_id, lifo, nclsts);
    461                                         if (rc != EOK)
    462                                                 goto error;
    463                                         *mcl = lifo[found - 1];
    464                                         *lcl = lifo[0];
    465                                         free(lifo);
    466                                         fibril_mutex_unlock(&fat_alloc_lock);
    467                                         return EOK;
    468                                 }
    469                         }
    470                 }
    471                 rc = block_put(blk);
    472                 if (rc != EOK) {
    473 error:
     697        for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) {
     698                rc = fat_get_cluster(bs, service_id, FAT1, clst, &value);
     699                if (rc != EOK)
     700                break;
     701
     702                if (value == FAT_CLST_RES0) {
     703                /*
     704                 * The cluster is free. Put it into our stack
     705                 * of found clusters and mark it as non-free.
     706                 */
     707                lifo[found] = clst;
     708                rc = fat_set_cluster(bs, service_id, FAT1, clst,
     709                    (found == 0) ?  clst_last1 : lifo[found - 1]);
     710                if (rc != EOK)
     711                        break;
     712
     713                found++;
     714                }
     715        }
     716
     717        if (rc == EOK && found == nclsts) {
     718                rc = fat_alloc_shadow_clusters(bs, service_id, lifo, nclsts);
     719                if (rc == EOK) {
     720                        *mcl = lifo[found - 1];
     721                        *lcl = lifo[0];
     722                        free(lifo);
    474723                        fibril_mutex_unlock(&fat_alloc_lock);
    475                         free(lifo);
    476                         return rc;
    477                 }
    478         }
    479 out:
    480         fibril_mutex_unlock(&fat_alloc_lock);
    481 
    482         /*
    483          * We could not find enough clusters. Now we need to free the clusters
    484          * we have allocated so far.
    485          */
    486         while (found--) {
     724                        return EOK;
     725                }
     726        }
     727
     728        /* If something wrong - free the clusters */
     729        if (found > 0) {
     730                while (found--) {
    487731                rc = fat_set_cluster(bs, service_id, FAT1, lifo[found],
    488732                    FAT_CLST_RES0);
    489                 if (rc != EOK) {
    490                         free(lifo);
    491                         return rc;
    492                 }
    493         }
    494        
     733                }
     734        }
     735
    495736        free(lifo);
     737        fibril_mutex_unlock(&fat_alloc_lock);
    496738        return ENOSPC;
    497739}
     
    509751{
    510752        unsigned fatno;
    511         fat_cluster_t nextc;
     753        fat_cluster_t nextc, clst_bad = FAT_CLST_BAD(bs);
    512754        int rc;
    513755
    514756        /* Mark all clusters in the chain as free in all copies of FAT. */
    515         while (firstc < FAT_CLST_LAST1) {
    516                 assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD);
     757        while (firstc < FAT_CLST_LAST1(bs)) {
     758                assert(firstc >= FAT_CLST_FIRST && firstc < clst_bad);
    517759                rc = fat_get_cluster(bs, service_id, FAT1, firstc, &nextc);
    518760                if (rc != EOK)
    519761                        return rc;
    520                 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
     762                for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
    521763                        rc = fat_set_cluster(bs, service_id, fatno, firstc,
    522764                            FAT_CLST_RES0);
     
    564806                }
    565807
    566                 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
    567                         rc = fat_set_cluster(bs, nodep->idx->service_id, fatno,
    568                             lastc, mcl);
     808                for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
     809                        rc = fat_set_cluster(bs, nodep->idx->service_id,
     810                            fatno, lastc, mcl);
    569811                        if (rc != EOK)
    570812                                return rc;
     
    590832int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lcl)
    591833{
     834        fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs);
    592835        int rc;
    593836        service_id_t service_id = nodep->idx->service_id;
     
    616859
    617860                /* Terminate the cluster chain in all copies of FAT. */
    618                 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
     861                for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
    619862                        rc = fat_set_cluster(bs, service_id, fatno, lcl,
    620                             FAT_CLST_LAST1);
     863                            clst_last1);
    621864                        if (rc != EOK)
    622865                                return rc;
     
    673916
    674917        /* Check number of FATs. */
    675         if (bs->fatcnt == 0)
     918        if (FATCNT(bs) == 0)
    676919                return ENOTSUP;
    677920
    678921        /* Check total number of sectors. */
    679 
    680         if (bs->totsec16 == 0 && bs->totsec32 == 0)
     922        if (TS(bs) == 0)
    681923                return ENOTSUP;
    682924
    683925        if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
    684             bs->totsec16 != bs->totsec32) 
     926            bs->totsec16 != bs->totsec32)
    685927                return ENOTSUP;
    686928
     
    690932
    691933        /* Check number of sectors per FAT. */
    692         if (bs->sec_per_fat == 0)
     934        if (SF(bs) == 0)
    693935                return ENOTSUP;
    694936
     
    700942         * sanitized to support file systems with this property.
    701943         */
    702         if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
    703             uint16_t_le2host(bs->bps) != 0)
     944        if (!FAT_IS_FAT32(bs) && (RDE(bs) * sizeof(fat_dentry_t)) % BPS(bs) != 0)
    704945                return ENOTSUP;
    705946
    706947        /* Check signature of each FAT. */
    707 
    708         for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
     948        for (fat_no = 0; fat_no < FATCNT(bs); fat_no++) {
    709949                rc = fat_get_cluster(bs, service_id, fat_no, 0, &e0);
    710950                if (rc != EOK)
     
    723963                 * set to one.
    724964                 */
    725                 if ((e0 >> 8) != 0xff || e1 != 0xffff)
     965                if (!FAT_IS_FAT12(bs) &&
     966                        ((e0 >> 8) != (FAT_MASK(bs) >> 8) || e1 != FAT_MASK(bs)))
    726967                        return ENOTSUP;
    727968        }
     
    732973/**
    733974 * @}
    734  */ 
     975 */
Note: See TracChangeset for help on using the changeset viewer.