Changeset 913a821c in mainline


Ignore:
Timestamp:
2008-11-09T17:23:53Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ac49f5d1
Parents:
6c8d267
Message:

Finish implementation of fat_truncate() and fix several warnings.

Location:
uspace/srv/fs/fat
Files:
3 edited

Legend:

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

    r6c8d267 r913a821c  
    130130        unsigned ssa;           /* size of the system area */
    131131        unsigned clusters, max_clusters;
    132         fat_cluster_t lastc, clst = firstc;
     132        fat_cluster_t lastc;
    133133
    134134        bps = uint16_t_le2host(bs->bps);
     
    158158        return b;
    159159}
    160 
    161160
    162161/** Fill the gap between EOF and a new file position.
     
    204203}
    205204
    206 /** Mark cluster in one instance of FAT.
     205/** Get cluster from the first FAT.
     206 *
     207 * @param bs            Buffer holding the boot sector for the file system.
     208 * @param dev_handle    Device handle for the file system.
     209 * @param clst          Cluster which to get.
     210 *
     211 * @return              Value found in the cluster.
     212 */
     213fat_cluster_t
     214fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst)
     215{
     216        block_t *b;
     217        uint16_t bps;
     218        uint16_t rscnt;
     219        fat_cluster_t *cp, value;
     220
     221        bps = uint16_t_le2host(bs->bps);
     222        rscnt = uint16_t_le2host(bs->rscnt);
     223
     224        b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps);
     225        cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
     226        value = uint16_t_le2host(*cp);
     227        block_put(b);
     228       
     229        return value;
     230}
     231
     232/** Set cluster in one instance of FAT.
    207233 *
    208234 * @param bs            Buffer holding the boot sector for the file system.
    209235 * @param dev_handle    Device handle for the file system.
    210236 * @param fatno         Number of the FAT instance where to make the change.
    211  * @param clst          Cluster which is to be marked.
    212  * @param value         Value mark the cluster with.
     237 * @param clst          Cluster which is to be set.
     238 * @param value         Value to set the cluster with.
    213239 */
    214240void
    215 fat_mark_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
     241fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
    216242    fat_cluster_t clst, fat_cluster_t value)
    217243{
     
    250276        for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
    251277                for (c = 0; c < nclsts; c++) {
    252                         fat_mark_cluster(bs, dev_handle, fatno, lifo[c],
     278                        fat_set_cluster(bs, dev_handle, fatno, lifo[c],
    253279                            c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
    254280                }
     
    334360         */
    335361        while (found--) {
    336                 fat_mark_cluster(bs, dev_handle, FAT1, lifo[found],
     362                fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
    337363                    FAT_CLST_RES0);
    338364        }
     
    342368}
    343369
     370/** Free clusters forming a cluster chain in all copies of FAT.
     371 *
     372 * @param bs            Buffer hodling the boot sector of the file system.
     373 * @param dev_handle    Device handle of the file system.
     374 * @param firstc        First cluster in the chain which is to be freed.
     375 */
     376void
     377fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc)
     378{
     379        unsigned fatno;
     380        fat_cluster_t nextc;
     381
     382        /* Mark all clusters in the chain as free in all copies of FAT. */
     383        while (firstc < FAT_CLST_LAST1) {
     384                nextc = fat_get_cluster(bs, dev_handle, firstc);
     385                assert(nextc >= FAT_CLST_FIRST && nextc < FAT_CLST_BAD);
     386                for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
     387                        fat_set_cluster(bs, dev_handle, fatno, firstc,
     388                            FAT_CLST_RES0);
     389                firstc = nextc;
     390        }
     391}
     392
    344393/** Append a cluster chain to the last file cluster in all FATs.
    345394 *
    346  * @param bs            Buffer holding boot sector of the file system.
     395 * @param bs            Buffer holding the boot sector of the file system.
    347396 * @param nodep         Node representing the file.
    348397 * @param mcl           First cluster of the cluster chain to append.
     
    354403        uint8_t fatno;
    355404
    356         if (fat_cluster_walk(bs, nodep->idx->dev_handle, nodep->firstc, &lcl,
     405        if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
    357406            (uint16_t) -1) == 0) {
    358407                /* No clusters allocated to the node yet. */
     
    363412
    364413        for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
    365                 fat_mark_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
     414                fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
     415}
     416
     417/** Chop off node clusters in all copies of FAT.
     418 *
     419 * @param bs            Buffer holding the boot sector of the file system.
     420 * @param nodep         FAT node where the chopping will take place.
     421 * @param lastc         Last cluster which will remain in the node. If this
     422 *                      argument is FAT_CLST_RES0, then all clusters will
     423 *                      be choped off.
     424 */
     425void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
     426{
     427        dev_handle_t dev_handle = nodep->idx->dev_handle;
     428        if (lastc == FAT_CLST_RES0) {
     429                /* The node will have zero size and no clusters allocated. */
     430                fat_free_clusters(bs, dev_handle, nodep->firstc);
     431                nodep->firstc = FAT_CLST_RES0;
     432                nodep->dirty = true;            /* need to sync node */
     433        } else {
     434                fat_cluster_t nextc;
     435                unsigned fatno;
     436
     437                nextc = fat_get_cluster(bs, dev_handle, lastc);
     438
     439                /* Terminate the cluster chain in all copies of FAT. */
     440                for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
     441                        fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1);
     442
     443                /* Free all following clusters. */
     444                fat_free_clusters(bs, dev_handle, nextc);
     445        }
    366446}
    367447
  • uspace/srv/fs/fat/fat_fat.h

    r6c8d267 r913a821c  
    7272extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
    7373    fat_cluster_t);
     74extern void fat_chop_clusters(struct fat_bs *, struct fat_node *,
     75    fat_cluster_t);
    7476extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned,
    7577    fat_cluster_t *, fat_cluster_t *);
     78extern void fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);
    7679extern void fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,
    7780    fat_cluster_t *, unsigned);
    78 extern void fat_mark_cluster(struct fat_bs *, dev_handle_t, unsigned,
     81extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
     82extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned,
    7983    fat_cluster_t, fat_cluster_t);
    8084extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
  • uspace/srv/fs/fat/fat_ops.c

    r6c8d267 r913a821c  
    635635        uint16_t bps;
    636636        unsigned spc;
     637        unsigned bpc;           /* bytes per cluster */
    637638        off_t boundary;
    638639       
     
    650651                return;
    651652        }
     653
     654        bs = block_bb_get(dev_handle);
     655        bps = uint16_t_le2host(bs->bps);
     656        spc = bs->spc;
     657        bpc = bps * spc;
    652658
    653659        /*
     
    659665         */
    660666        bytes = min(len, bps - pos % bps);
    661 
    662         bs = block_bb_get(dev_handle);
    663         bps = uint16_t_le2host(bs->bps);
    664         spc = bs->spc;
    665        
    666         boundary = ROUND_UP(nodep->size, bps * spc);
     667       
     668        boundary = ROUND_UP(nodep->size, bpc);
    667669        if (pos < boundary) {
    668670                /*
     
    694696                fat_cluster_t mcl, lcl;
    695697 
    696                 nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) /
    697                     bps * spc;
     698                nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
    698699                /* create an independent chain of nclsts clusters in all FATs */
    699                 status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl,
    700                     &lcl);
     700                status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
    701701                if (status != EOK) {
    702702                        /* could not allocate a chain of nclsts clusters */
     
    732732        size_t size = (off_t)IPC_GET_ARG3(*request);
    733733        fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
     734        fat_bs_t *bs;
     735        uint16_t bps;
     736        uint8_t spc;
     737        unsigned bpc;   /* bytes per cluster */
    734738        int rc;
    735739
     
    738742                return;
    739743        }
     744
     745        bs = block_bb_get(dev_handle);
     746        bps = uint16_t_le2host(bs->bps);
     747        spc = bs->spc;
     748        bpc = bps * spc;
    740749
    741750        if (nodep->size == size) {
     
    743752        } else if (nodep->size < size) {
    744753                /*
    745                  * TODO: the standard says we have the freedom to grow the file.
     754                 * The standard says we have the freedom to grow the node.
    746755                 * For now, we simply return an error.
    747756                 */
    748757                rc = EINVAL;
     758        } else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
     759                /*
     760                 * The node will be shrunk, but no clusters will be deallocated.
     761                 */
     762                nodep->size = size;
     763                nodep->dirty = true;            /* need to sync node */
     764                rc = EOK;       
    749765        } else {
    750766                /*
    751                  * The file is to be shrunk.
    752                  */
    753                 rc = ENOTSUP;   /* XXX */
     767                 * The node will be shrunk, clusters will be deallocated.
     768                 */
     769                if (size == 0) {
     770                        fat_chop_clusters(bs, nodep, FAT_CLST_RES0);
     771                } else {
     772                        fat_cluster_t lastc;
     773                        (void) fat_cluster_walk(bs, dev_handle, nodep->firstc,
     774                            &lastc, (size - 1) / bpc);
     775                        fat_chop_clusters(bs, nodep, lastc);
     776                }
     777                nodep->size = size;
     778                nodep->dirty = true;            /* need to sync node */
     779                rc = EOK;       
    754780        }
    755781        fat_node_put(nodep);
    756782        ipc_answer_0(rid, rc);
    757783        return;
    758 
    759784}
    760785
Note: See TracChangeset for help on using the changeset viewer.