Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ffee7bf in mainline


Ignore:
Timestamp:
2012-02-18T15:44:21Z (8 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
master
Children:
6b3cda3
Parents:
e872326
Message:

mkexfat: compute the cluster size needed to index the entire device, fix syntax errors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/mkexfat/mkexfat.c

    re872326 rffee7bf  
    3939#include <stdio.h>
    4040#include <libblock.h>
     41#include <assert.h>
     42#include <errno.h>
     43#include <byteorder.h>
     44#include <sys/types.h>
     45#include <sys/typefmt.h>
     46#include "exfat.h"
    4147
    4248#define NAME    "mkexfat"
     
    4854#define div_round_up(a, b) (((a) + (b) - 1) / (b))
    4955
     56/** The default size of each cluster is 4096 byte */
     57#define DEFAULT_CLUSTER_SIZE 4096
     58
     59static unsigned log2(unsigned n);
     60
    5061typedef struct exfat_cfg {
    51         uint64_t volume_start;
    52         uint64_t volume_count;
     62        aoff64_t volume_start;
     63        aoff64_t volume_count;
    5364        uint32_t fat_sector_count;
    5465        uint32_t data_start_sector;
    5566        uint32_t data_cluster;
    5667        uint32_t rootdir_cluster;
    57         unsigned bytes_per_sector;
    58         unsigned sec_per_cluster;
     68        size_t   sector_size;
     69        size_t   cluster_size;
     70        unsigned long total_clusters;
    5971} exfat_cfg_t;
    6072
     
    7183cfg_params_initialize(exfat_cfg_t *cfg)
    7284{
     85        aoff64_t const volume_bytes = cfg->volume_count * cfg->sector_size;
     86
     87        /** Number of clusters required to index the entire device, it must
     88         * be less then UINT32_MAX.
     89         */
     90        aoff64_t n_req_clusters = volume_bytes / DEFAULT_CLUSTER_SIZE;
     91        cfg->cluster_size = DEFAULT_CLUSTER_SIZE;
     92
     93        /* Compute the required cluster size to index
     94         * the entire storage device.
     95         */
     96        while (n_req_clusters > UINT32_MAX &&
     97            (cfg->cluster_size < 32 * 1024 * 1024)) {
     98
     99                cfg->cluster_size <<= 1;
     100                n_req_clusters = volume_bytes / cfg->cluster_size;
     101        }
    73102}
    74103
     
    99128        vbr->version.minor = 0;
    100129        vbr->volume_flags = host2uint16_t_le(0);
    101         vbr->bytes_per_sector = cfg->bytes_per_sectors;
    102         vbr->sec_per_cluster = cfg->sec_per_cluster;
     130        vbr->bytes_per_sector = log2(cfg->sector_size);
     131        vbr->sec_per_cluster = log2(cfg->cluster_size / cfg->sector_size);
     132
     133        /* Maximum cluster size is 32 Mb */
     134        assert((vbr->bytes_per_sector + vbr->sec_per_cluster) <= 25);
     135
    103136        vbr->fat_count = 1;
    104137        vbr->drive_no = 0x80;
     
    107140}
    108141
     142/** Given a power-of-two number (n), returns the result of log2(n).
     143 *
     144 * It works only if n is a power of two.
     145 */
     146static unsigned log2(unsigned n)
     147{
     148        unsigned r;
     149
     150        for (r = 0;n >> r != 1; ++r);
     151
     152        return r;
     153}
     154
    109155int main (int argc, char **argv)
    110156{
    111157        exfat_cfg_t cfg;
    112         aoff64_t dev_nblocks;
     158        exfat_bs_t  vbr;
    113159        char *dev_path;
    114160        service_id_t service_id;
    115         size_t sector_size;
    116161        int rc;
    117162
     
    134179        rc = loc_service_get_id(dev_path, &service_id, 0);
    135180        if (rc != EOK) {
    136                 printf(NAME ": Error resolving device `%s'.\n");
     181                printf(NAME ": Error resolving device `%s'.\n", dev_path);
    137182                return 2;
    138183        }
     
    144189        }
    145190
    146         rc = block_get_bsize(service_id, &sector_size);
     191        rc = block_get_bsize(service_id, &cfg.sector_size);
    147192        if (rc != EOK) {
    148193                printf(NAME ": Error determining device block size.\n");
     
    150195        }
    151196
    152         rc = block_get_nblocks(service_id, &dev_nblocks);
     197        if (cfg.sector_size > 4096) {
     198                printf(NAME ":Error, sector size can't be greater" \
     199                    " than 4096 bytes.\n");
     200                return 2;
     201        }
     202
     203        rc = block_get_nblocks(service_id, &cfg.volume_count);
    153204        if (rc != EOK) {
    154205                printf(NAME ": Warning, failed to obtain device block size.\n");
     
    157208        } else {
    158209                printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n",
    159                     dev_nblocks);
    160 
    161                 cfg.volume_count = dev_nblocks;
     210                    cfg.volume_count);
    162211        }
    163212
    164213        cfg_params_initialize(&cfg);
     214        vbr_initialize(&vbr, &cfg);
    165215
    166216
Note: See TracChangeset for help on using the changeset viewer.