Changeset 4f1c0b4 in mainline


Ignore:
Timestamp:
2008-11-05T22:28:54Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9d20ea8
Parents:
8334a427
Message:

Extend _fat_blcks_get() to fat_cluster_walk(). Use fat_cluster_walk() to
implement fat_clusters_get() and _fat_block_get().

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

Legend:

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

    r8334a427 r4f1c0b4  
    5555static futex_t fat_alloc_lock = FUTEX_INITIALIZER;
    5656
    57 /** Read block from file located on a FAT file system.
    58  *
    59  * @param bs            Buffer holding the boot sector of the file system.
    60  * @param dev_handle    Device handle of the file system.
    61  * @param firstc        First cluster used by the file. Can be zero if the file
    62  *                      is empty.
    63  * @param offset        Offset in blocks.
    64  *
    65  * @return              Block structure holding the requested block.
    66  */
    67 block_t *
    68 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
    69     off_t offset)
     57/** Walk the cluster chain.
     58 *
     59 * @param bs            Buffer holding the boot sector for the file.
     60 * @param dev_handle    Device handle of the device with the file.
     61 * @param firstc        First cluster to start the walk with.
     62 * @param penult        If non-NULL, output argument hodling the
     63 *                      the penultimate cluster visited.
     64 * @param ult           If non-NULL, output argument holding the
     65 *                      ultimate cluster visited.
     66 * @param max_clusters  Maximum number of clusters to visit.   
     67 *
     68 * @return              Number of clusters seen during the walk.
     69 */
     70uint16_t
     71fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
     72    fat_cluster_t *penult, fat_cluster_t *ult, uint16_t max_clusters)
    7073{
    7174        block_t *b;
    7275        unsigned bps;
    73         unsigned spc;
    7476        unsigned rscnt;         /* block address of the first FAT */
    75         unsigned fatcnt;
    76         unsigned rde;
    77         unsigned rds;           /* root directory size */
    78         unsigned sf;
    79         unsigned ssa;           /* size of the system area */
    80         unsigned clusters;
     77        uint16_t clusters = 0;
    8178        fat_cluster_t clst = firstc;
    82         unsigned i;
    83 
    84         bps = uint16_t_le2host(bs->bps);
    85         spc = bs->spc;
     79
     80        bps = uint16_t_le2host(bs->bps);
    8681        rscnt = uint16_t_le2host(bs->rscnt);
    87         fatcnt = bs->fatcnt;
    88         rde = uint16_t_le2host(bs->root_ent_max);
    89         sf = uint16_t_le2host(bs->sec_per_fat);
    90 
    91         rds = (sizeof(fat_dentry_t) * rde) / bps;
    92         rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
    93         ssa = rscnt + fatcnt * sf + rds;
    94 
    95         if (firstc == FAT_CLST_ROOT) {
    96                 /* root directory special case */
    97                 assert(offset < rds);
    98                 b = block_get(dev_handle, rscnt + fatcnt * sf + offset);
    99                 return b;
    100         }
    101 
    102         clusters = offset / spc;
    103         for (i = 0; i < clusters; i++) {
     82
     83        if (firstc == FAT_CLST_RES0) {
     84                /* No space allocated to the file. */
     85                if (ult)
     86                        *ult = firstc;
     87                return 0;
     88        }
     89
     90        /* At this point, the meaning of penult is not well-defined. */
     91        if (penult)
     92                *penult = FAT_CLST_RES0;
     93
     94        while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
    10495                unsigned fsec;  /* sector offset relative to FAT1 */
    10596                unsigned fidx;  /* FAT1 entry index */
    10697
    107                 assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
    108                 fsec = (clst * sizeof(fat_cluster_t)) / bps;
    109                 fidx = clst % (bps / sizeof(fat_cluster_t));
    110                 /* read FAT1 */
    111                 b = block_get(dev_handle, rscnt + fsec);
    112                 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
    113                 assert(clst != FAT_CLST_BAD);
    114                 assert(clst < FAT_CLST_LAST1);
    115                 block_put(b);
    116         }
    117 
    118         b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
    119             offset % spc);
    120 
    121         return b;
    122 }
    123 
    124 /** Return number of blocks allocated to a file.
    125  *
    126  * @param bs            Buffer holding the boot sector for the file.
    127  * @param dev_handle    Device handle of the device with the file.
    128  * @param firstc        First cluster of the file.
    129  * @param lastc         If non-NULL, output argument holding the
    130  *                      last cluster.
    131  *
    132  * @return              Number of blocks allocated to the file.
    133  */
    134 uint16_t
    135 _fat_blcks_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
    136     fat_cluster_t *lastc)
    137 {
    138         block_t *b;
    139         unsigned bps;
    140         unsigned spc;
    141         unsigned rscnt;         /* block address of the first FAT */
    142         unsigned clusters = 0;
    143         fat_cluster_t clst = firstc;
    144 
    145         bps = uint16_t_le2host(bs->bps);
    146         spc = bs->spc;
    147         rscnt = uint16_t_le2host(bs->rscnt);
    148 
    149         if (firstc == FAT_CLST_RES0) {
    150                 /* No space allocated to the file. */
    151                 if (lastc)
    152                         *lastc = firstc;
    153                 return 0;
    154         }
    155 
    156         while (clst < FAT_CLST_LAST1) {
    157                 unsigned fsec;  /* sector offset relative to FAT1 */
    158                 unsigned fidx;  /* FAT1 entry index */
    159 
    16098                assert(clst >= FAT_CLST_FIRST);
    161                 if (lastc)
    162                         *lastc = clst;          /* remember the last cluster */
     99                if (penult)
     100                        *penult = clst; /* remember the penultimate cluster */
    163101                fsec = (clst * sizeof(fat_cluster_t)) / bps;
    164102                fidx = clst % (bps / sizeof(fat_cluster_t));
     
    171109        }
    172110
    173         if (lastc)
    174                 *lastc = clst;
    175         return clusters * spc;
    176 }
     111        if (ult)
     112                *ult = clst;
     113
     114        return clusters;
     115}
     116
     117/** Read block from file located on a FAT file system.
     118 *
     119 * @param bs            Buffer holding the boot sector of the file system.
     120 * @param dev_handle    Device handle of the file system.
     121 * @param firstc        First cluster used by the file. Can be zero if the file
     122 *                      is empty.
     123 * @param offset        Offset in blocks.
     124 *
     125 * @return              Block structure holding the requested block.
     126 */
     127block_t *
     128_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
     129    off_t offset)
     130{
     131        block_t *b;
     132        unsigned bps;
     133        unsigned rscnt;         /* block address of the first FAT */
     134        unsigned rde;
     135        unsigned rds;           /* root directory size */
     136        unsigned sf;
     137        unsigned ssa;           /* size of the system area */
     138        unsigned clusters, max_clusters;
     139        fat_cluster_t lastc, clst = firstc;
     140
     141        bps = uint16_t_le2host(bs->bps);
     142        rscnt = uint16_t_le2host(bs->rscnt);
     143        rde = uint16_t_le2host(bs->root_ent_max);
     144        sf = uint16_t_le2host(bs->sec_per_fat);
     145
     146        rds = (sizeof(fat_dentry_t) * rde) / bps;
     147        rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
     148        ssa = rscnt + bs->fatcnt * sf + rds;
     149
     150        if (firstc == FAT_CLST_ROOT) {
     151                /* root directory special case */
     152                assert(offset < rds);
     153                b = block_get(dev_handle, rscnt + bs->fatcnt * sf + offset);
     154                return b;
     155        }
     156
     157        max_clusters = offset / bs->spc;
     158        clusters = fat_cluster_walk(bs, dev_handle, firstc, NULL, &lastc,
     159            max_clusters);
     160        assert(clusters == max_clusters);
     161
     162        b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
     163            offset % bs->spc);
     164
     165        return b;
     166}
     167
    177168
    178169/** Fill the gap between EOF and a new file position.
     
    370361        uint8_t fatno;
    371362
    372         if (_fat_blcks_get(bs, dev_handle, nodep->firstc, &lcl) == 0) {
     363        if (fat_clusters_get(bs, nodep->idx->dev_handle, nodep->firstc) == 0) {
     364                /* No clusters allocated to the node yet. */
    373365                nodep->firstc = host2uint16_t_le(mcl);
    374366                nodep->dirty = true;            /* need to sync node */
  • uspace/srv/fs/fat/fat_fat.h

    r8334a427 r4f1c0b4  
    5858typedef uint16_t fat_cluster_t;
    5959
     60#define fat_clusters_get(bs, dh, fc) \
     61    fat_cluster_walk((bs), (dh), (fc), NULL, NULL, (uint16_t) -1)
    6062#define fat_block_get(bs, np, off) \
    6163    _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (off))
    62    
     64
    6365extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
    6466    fat_cluster_t, off_t);
    65 extern uint16_t _fat_blcks_get(struct fat_bs *, dev_handle_t, fat_cluster_t,
    66     fat_cluster_t *);
     67extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
     68    fat_cluster_t *, fat_cluster_t *, uint16_t);
    6769 
    6870extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
  • uspace/srv/fs/fat/fat_ops.c

    r8334a427 r4f1c0b4  
    114114        fat_node_t *nodep = NULL;
    115115        unsigned bps;
     116        unsigned spc;
    116117        unsigned dps;
    117118
     
    165166        bs = block_bb_get(idxp->dev_handle);
    166167        bps = uint16_t_le2host(bs->bps);
     168        spc = bs->spc;
    167169        dps = bps / sizeof(fat_dentry_t);
    168170
     
    185187                 * size of the directory by walking the FAT.
    186188                 */
    187                 nodep->size = bps * _fat_blcks_get(bs, idxp->dev_handle,
    188                     uint16_t_le2host(d->firstc), NULL);
     189                nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle,
     190                    uint16_t_le2host(d->firstc));
    189191        } else {
    190192                nodep->type = FAT_FILE;
Note: See TracChangeset for help on using the changeset viewer.