Changeset 59e670e in mainline for uspace/app/mkminix/mkminix.c


Ignore:
Timestamp:
2011-03-08T15:38:55Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
410a065
Parents:
f5cbd4f
Message:

Rewrite mkminix to improve readability

File:
1 edited

Legend:

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

    rf5cbd4f r59e670e  
    6262} help_level_t;
    6363
    64 typedef struct mfs_params {
    65         int             fs_version;
    66         devmap_handle_t handle;
    67         uint16_t        fs_magic;
    68         uint32_t        block_size;
    69         size_t          devblock_size;
    70         unsigned long   n_inodes;
    71         aoff64_t        dev_nblocks;
    72         bool            fs_longnames;
    73 } mfs_params_t;
     64/*Generic MFS superblock*/
     65struct mfs_sb_info {
     66        devmap_handle_t handle;
     67        uint64_t n_inodes;
     68        uint64_t n_zones;
     69        aoff64_t dev_nblocks;
     70        aoff64_t devblock_size;
     71        unsigned long ibmap_blocks;
     72        unsigned long zbmap_blocks;
     73        unsigned long first_data_zone;
     74        int log2_zone_size;
     75        int ino_per_block;
     76        uint32_t max_file_size;
     77        uint16_t magic;
     78        uint32_t block_size;
     79        int fs_version;
     80        bool longnames;
     81};
    7482
    7583static void     help_cmd_mkminix(help_level_t level);
    7684static int      num_of_set_bits(uint32_t n);
    77 static void     init_superblock(struct mfs_superblock *sb, mfs_params_t *opt);
    78 static void     init_superblock_v3(struct mfs3_superblock *sb,
    79                                         mfs_params_t *opt);
    80 static void     init_bitmaps(uint32_t ninodes,  uint32_t nzones,
    81                                 int bsize, mfs_params_t *opt);
    82 static void     mark_bmap(uint8_t *bmap, int idx, int v);
     85static void     init_superblock(struct mfs_sb_info *sb);
     86static void     write_superblock(struct mfs_sb_info *sbi);
     87static void     write_superblock3(struct mfs_sb_info *sbi);
     88static void     init_bitmaps(struct mfs_sb_info *sb);
     89static void     mark_bmap(uint32_t *bmap, int idx, int v);
    8390
    8491static struct option const long_options[] = {
     
    97104        int rc, c, opt_ind;
    98105        char *device_name;
    99        
    100         struct mfs_superblock *sb;
    101         struct mfs3_superblock *sb3;
    102 
    103         mfs_params_t opt;
     106
     107        struct mfs_sb_info sb;
    104108
    105109        /*Default is MinixFS V3*/
    106         opt.fs_magic = MFS_MAGIC_V3;
     110        sb.magic = MFS_MAGIC_V3;
    107111
    108112        /*Default block size is 4Kb*/
    109         opt.block_size = MFS_MAX_BLOCKSIZE;
    110         opt.n_inodes = 0;
    111         opt.fs_longnames = false;
     113        sb.block_size = MFS_MAX_BLOCKSIZE;
     114        sb.n_inodes = 0;
     115        sb.longnames = false;
     116        sb.ino_per_block = V3_INODES_PER_BLOCK(MFS_MAX_BLOCKSIZE);
    112117
    113118        if (argc == 1) {
     
    124129                        exit(0);
    125130                case '1':
    126                         opt.fs_magic = MFS_MAGIC_V1;
    127                         opt.block_size = MFS_BLOCKSIZE;
    128                         opt.fs_version = 1;
     131                        sb.magic = MFS_MAGIC_V1;
     132                        sb.block_size = MFS_BLOCKSIZE;
     133                        sb.fs_version = 1;
     134                        sb.ino_per_block = V1_INODES_PER_BLOCK;
    129135                        break;
    130136                case '2':
    131                         opt.fs_magic = MFS_MAGIC_V2;
    132                         opt.block_size = MFS_BLOCKSIZE;
    133                         opt.fs_version = 2;
     137                        sb.magic = MFS_MAGIC_V2;
     138                        sb.block_size = MFS_BLOCKSIZE;
     139                        sb.fs_version = 2;
     140                        sb.ino_per_block = V2_INODES_PER_BLOCK;
    134141                        break;
    135142                case '3':
    136                         opt.fs_magic = MFS_MAGIC_V3;
    137                         opt.fs_version = 3;
     143                        sb.magic = MFS_MAGIC_V3;
     144                        sb.fs_version = 3;
     145                        sb.block_size = MFS_MAX_BLOCKSIZE;
    138146                        break;
    139147                case 'b':
    140                         opt.block_size = (uint32_t) strtol(optarg, NULL, 10);
     148                        sb.block_size = (uint32_t) strtol(optarg, NULL, 10);
    141149                        break;
    142150                case 'i':
    143                         opt.n_inodes = (unsigned long) strtol(optarg, NULL, 10);
     151                        sb.n_inodes = (unsigned long) strtol(optarg, NULL, 10);
    144152                        break;
    145153                case 'l':
    146                         opt.fs_longnames = true;
     154                        sb.longnames = true;
    147155                        break;
    148156                }
    149157        }
    150158
    151         if (opt.block_size < MFS_MIN_BLOCKSIZE ||
    152                                 opt.block_size > MFS_MAX_BLOCKSIZE) {
     159        if (sb.block_size < MFS_MIN_BLOCKSIZE ||
     160                                sb.block_size > MFS_MAX_BLOCKSIZE) {
    153161                printf(NAME ":Error! Invalid block size.\n");
    154162                exit(0);
    155         } else if (num_of_set_bits(opt.block_size) != 1) {
     163        } else if (num_of_set_bits(sb.block_size) != 1) {
    156164                /*Block size must be a power of 2.*/
    157165                printf(NAME ":Error! Invalid block size.\n");
    158166                exit(0);
    159         } else if (opt.block_size > MFS_BLOCKSIZE &&
    160                         opt.fs_magic != MFS_MAGIC_V3) {
     167        } else if (sb.block_size > MFS_BLOCKSIZE &&
     168                        sb.fs_version != 3) {
    161169                printf(NAME ":Error! Block size > 1024 is supported by V3 filesystem only.\n");
    162170                exit(0);
    163         } else if (opt.fs_magic == MFS_MAGIC_V3 && opt.fs_longnames) {
     171        } else if (sb.fs_version == 3 && sb.longnames) {
    164172                printf(NAME ":Error! Long filenames are supported by V1/V2 filesystem only.\n");
    165173                exit(0);
     
    175183        }
    176184
    177         rc = devmap_device_get_handle(device_name, &opt.handle, 0);
     185        rc = devmap_device_get_handle(device_name, &sb.handle, 0);
    178186        if (rc != EOK) {
    179187                printf(NAME ": Error resolving device `%s'.\n", device_name);
     
    181189        }
    182190
    183         rc = block_init(opt.handle, MFS_MIN_BLOCKSIZE);
     191        rc = block_init(sb.handle, MFS_MIN_BLOCKSIZE);
    184192        if (rc != EOK)  {
    185193                printf(NAME ": Error initializing libblock.\n");
     
    187195        }
    188196
    189         rc = block_get_bsize(opt.handle, &opt.devblock_size);
     197        rc = block_get_bsize(sb.handle, &sb.devblock_size);
    190198        if (rc != EOK) {
    191199                printf(NAME ": Error determining device block size.\n");
     
    193201        }
    194202
    195         rc = block_get_nblocks(opt.handle, &opt.dev_nblocks);
     203        rc = block_get_nblocks(sb.handle, &sb.dev_nblocks);
    196204        if (rc != EOK) {
    197205                printf(NAME ": Warning, failed to obtain block device size.\n");
    198206        } else {
    199207                printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n",
    200                     opt.dev_nblocks);
    201         }
    202 
    203         if (opt.devblock_size != 512) {
     208                    sb.dev_nblocks);
     209        }
     210
     211        if (sb.devblock_size != 512) {
    204212                printf(NAME ": Error. Device block size is not 512 bytes.\n");
    205213                return 2;
     
    207215
    208216        /*Minimum block size is 1 Kb*/
    209         opt.dev_nblocks /= 2;
     217        sb.dev_nblocks /= 2;
    210218
    211219        printf(NAME ": Creating Minix file system on device\n");
    212220
    213         /*Setting up superblock*/
    214 
    215         if (opt.fs_magic == MFS_MAGIC_V3) {
    216                 sb3 = (struct mfs3_superblock *) malloc(sizeof(struct mfs3_superblock));
    217                 if (!sb3) {
    218                         printf(NAME ": Error, not enough memory");
    219                         return 2;
     221        /*Initialize superblock*/
     222        init_superblock(&sb);
     223
     224        /*Initialize bitmaps*/
     225        init_bitmaps(&sb);
     226
     227        return 0;
     228}
     229
     230static void init_superblock(struct mfs_sb_info *sb)
     231{
     232        aoff64_t inodes;
     233
     234        if (sb->longnames)
     235                sb->magic = sb->fs_version == 1 ? MFS_MAGIC_V1L : MFS_MAGIC_V2L;
     236
     237        /*Compute the number of zones on disk*/
     238
     239        if (sb->fs_version == 1) {
     240                /*Valid only for MFS V1*/
     241                sb->n_zones = sb->dev_nblocks > UINT16_MAX ?
     242                        UINT16_MAX : sb->dev_nblocks;
     243        } else {
     244                /*Valid for MFS V2/V3*/
     245                sb->n_zones = sb->dev_nblocks > UINT32_MAX ?
     246                        UINT32_MAX : sb->dev_nblocks;
     247
     248                if (sb->fs_version == 3) {
     249                        sb->ino_per_block = V3_INODES_PER_BLOCK(sb->block_size);
     250                        sb->n_zones /= (sb->block_size / MFS_MIN_BLOCKSIZE);
    220251                }
    221                 init_superblock_v3(sb3, &opt);
    222                 init_bitmaps(sb3->s_ninodes, sb3->s_nzones, sb3->s_block_size, &opt);
    223         } else {
    224                 sb = (struct mfs_superblock *) malloc(sizeof(struct mfs_superblock));
    225                 if (!sb) {
    226                         printf(NAME ": Error, not enough memory");
    227                         return 2;
    228                 }
    229                 init_superblock(sb, &opt);
    230                 init_bitmaps(sb->s_ninodes, sb->s_nzones, MFS_BLOCKSIZE, &opt);
    231         }
    232 
    233         return 0;
    234 }
    235 
    236 static void init_superblock(struct mfs_superblock *sb, mfs_params_t *opt)
    237 {
    238         int ino_per_block = 0;
    239         aoff64_t inodes;
    240 
    241         if (opt->fs_version == 1) {
    242                 ino_per_block = V1_INODES_PER_BLOCK;
    243                 if (opt->fs_longnames)
    244                         opt->fs_magic = MFS_MAGIC_V1L;
    245         } else {
    246                 ino_per_block = V2_INODES_PER_BLOCK;
    247                 if (opt->fs_longnames)
    248                         opt->fs_magic = MFS_MAGIC_V2L;
    249         }
    250 
    251         sb->s_magic = opt->fs_magic;
    252 
    253         /*Compute the number of zones on disk*/
    254 
    255         /*Valid only for MFS V1*/
    256         sb->s_nzones = opt->dev_nblocks > UINT16_MAX ?
    257                         UINT16_MAX : opt->dev_nblocks;
    258 
    259         /*Valid only for MFS V2*/
    260         sb->s_nzones2 = opt->dev_nblocks > UINT32_MAX ?
    261                         UINT32_MAX : opt->dev_nblocks;
     252        }
    262253
    263254        /*Round up the number of inodes to fill block size*/
    264         if (opt->n_inodes == 0)
    265                 inodes = opt->dev_nblocks / 3;         
     255        if (sb->n_inodes == 0)
     256                inodes = sb->dev_nblocks / 3;
     257
     258        if (inodes % sb->ino_per_block)
     259                inodes = ((inodes / sb->ino_per_block) + 1) * sb->ino_per_block;
     260       
     261        if (sb->fs_version < 3)
     262                sb->n_inodes = inodes > UINT16_MAX ? UINT16_MAX : inodes;
    266263        else
    267                 inodes = opt->n_inodes;
    268 
    269         if (inodes % ino_per_block)
    270                 inodes = ((inodes / ino_per_block) + 1) * ino_per_block;
    271         sb->s_ninodes = inodes > UINT16_MAX ? UINT16_MAX : inodes;
     264                sb->n_inodes = inodes > UINT32_MAX ? UINT32_MAX : inodes;
    272265
    273266        /*Compute inode bitmap size in blocks*/
    274         sb->s_ibmap_blocks = UPPER(sb->s_ninodes, MFS_BLOCKSIZE * 8);
     267        sb->ibmap_blocks = UPPER(sb->n_inodes, sb->block_size * 8);
    275268
    276269        /*Compute zone bitmap size in blocks*/
    277         if (opt->fs_version == 1)
    278                 sb->s_zbmap_blocks = UPPER(sb->s_nzones, MFS_BLOCKSIZE * 8);
     270        sb->zbmap_blocks = UPPER(sb->n_zones, sb->block_size * 8);
     271
     272        /*Compute inode table size*/
     273        unsigned long ninodes_blocks = sb->n_inodes / sb->ino_per_block;
     274
     275        /*Compute first data zone position*/
     276        sb->first_data_zone = 2 + ninodes_blocks +
     277                                sb->zbmap_blocks + sb->ibmap_blocks;
     278
     279        /*Set log2 of zone to block ratio to zero*/
     280        sb->log2_zone_size = 0;
     281
     282        /*Superblock is now ready to be written on disk*/
     283        printf(NAME ": %d inodes\n", (uint32_t) sb->n_inodes);
     284        printf(NAME ": %d zones\n", (uint32_t) sb->n_zones);
     285        printf(NAME ": inode table blocks = %ld\n", ninodes_blocks);
     286        printf(NAME ": first data zone = %d\n", (uint32_t) sb->first_data_zone);
     287        printf(NAME ": long fnames = %s\n", sb->longnames ? "Yes" : "No");
     288
     289        if (sb->fs_version == 3)
     290                write_superblock3(sb);
    279291        else
    280                 sb->s_zbmap_blocks = UPPER(sb->s_nzones2, MFS_BLOCKSIZE * 8);
    281 
    282         /*Compute inode table size*/
    283         unsigned long ninodes_blocks = sb->s_ninodes / ino_per_block;
    284 
    285         /*Compute first data zone position*/
    286         sb->s_first_data_zone = 2 + ninodes_blocks +
    287                                 sb->s_zbmap_blocks + sb->s_ibmap_blocks;
    288 
    289         /*Set log2 of zone to block ratio to zero*/
    290         sb->s_log2_zone_size = 0;
    291 
    292         /*Superblock is now ready to be written on disk*/
    293         printf(NAME ": %d inodes\n", sb->s_ninodes);
    294         printf(NAME ": %d zones\n", sb->s_nzones2);
    295         printf(NAME ": inode table blocks = %ld\n", ninodes_blocks);
    296         printf(NAME ": first data zone = %d\n", sb->s_first_data_zone);
    297         printf(NAME ": long fnames = %s\n", opt->fs_longnames ? "Yes" : "No");
    298 
    299         block_write_direct(opt->handle, MFS_SUPERBLOCK, 1, sb);
    300 }
    301 
    302 static void init_superblock_v3(struct mfs3_superblock *sb, mfs_params_t *opt)
    303 {
    304         int ino_per_block;
    305         int bs;
    306         aoff64_t inodes;
    307 
    308         sb->s_magic = opt->fs_magic;
    309         bs = opt->block_size;
    310 
    311         if (opt->n_inodes == 0)
    312                 inodes = opt->dev_nblocks / 3;         
     292                write_superblock(sb);
     293}
     294
     295static void write_superblock(struct mfs_sb_info *sbi)
     296{
     297        struct mfs_superblock *sb;
     298        uint8_t *superblock_buf;
     299
     300        superblock_buf = malloc(1024);
     301
     302        sb = (struct mfs_superblock *) superblock_buf;
     303
     304        sb->s_ninodes = (uint16_t) sbi->n_inodes;
     305        sb->s_nzones = (uint16_t) sbi->n_zones;
     306        sb->s_nzones2 = (uint32_t) sbi->n_zones;
     307        sb->s_ibmap_blocks = (uint16_t) sbi->ibmap_blocks;
     308        sb->s_zbmap_blocks = (uint16_t) sbi->zbmap_blocks;
     309        sb->s_first_data_zone = (uint16_t) sbi->first_data_zone;
     310        sb->s_log2_zone_size = sbi->log2_zone_size;
     311        sb->s_max_file_size = UINT32_MAX;
     312        sb->s_magic = sbi->magic;
     313        sb->s_state = MFS_VALID_FS;
     314
     315        block_write_direct(sbi->handle, MFS_SUPERBLOCK, 1, sb);
     316        free(superblock_buf);
     317}
     318
     319static void write_superblock3(struct mfs_sb_info *sbi)
     320{
     321        struct mfs3_superblock *sb;
     322        uint8_t *superblock_buf;
     323
     324        superblock_buf = malloc(1024);
     325
     326        sb = (struct mfs3_superblock *) superblock_buf;
     327
     328        sb->s_ninodes = (uint32_t) sbi->n_inodes;
     329        sb->s_nzones = (uint32_t) sbi->n_zones;
     330        sb->s_ibmap_blocks = (uint16_t) sbi->ibmap_blocks;
     331        sb->s_zbmap_blocks = (uint16_t) sbi->zbmap_blocks;
     332        sb->s_first_data_zone = (uint16_t) sbi->first_data_zone;
     333        sb->s_log2_zone_size = sbi->log2_zone_size;
     334        sb->s_max_file_size = UINT32_MAX;
     335        sb->s_magic = sbi->magic;
     336        sb->s_block_size = sbi->block_size;
     337        sb->s_disk_version = 3;
     338
     339        block_write_direct(sbi->handle, MFS_SUPERBLOCK, 1, sb);
     340        free(superblock_buf);
     341}
     342
     343static void init_bitmaps(struct mfs_sb_info *sb)
     344{
     345        uint32_t *ibmap_buf, *zbmap_buf;
     346        int ibmap_nblocks = 1 + (sb->n_inodes / 8) / sb->block_size;
     347        int zbmap_nblocks = 1 + (sb->n_zones / 8) / sb->block_size;
     348        unsigned int i;
     349
     350        ibmap_buf = (uint32_t *) malloc(ibmap_nblocks * sb->block_size);
     351        zbmap_buf = (uint32_t *) malloc(zbmap_nblocks * sb->block_size);
     352
     353        memset(ibmap_buf, 0xFF, ibmap_nblocks * sb->block_size);
     354        memset(zbmap_buf, 0xFF, zbmap_nblocks * sb->block_size);
     355
     356        for (i = 2; i < sb->n_inodes; ++i)
     357                mark_bmap(ibmap_buf, i, FREE);
     358
     359        for (i = 2; i < sb->n_zones; ++i)
     360                mark_bmap(zbmap_buf, i, FREE);
     361
     362        ibmap_nblocks *= sb->block_size / MFS_BLOCKSIZE;
     363        zbmap_nblocks *= sb->block_size / MFS_BLOCKSIZE;
     364
     365        block_write_direct(sb->handle, 2, ibmap_nblocks, ibmap_buf);
     366        block_write_direct(sb->handle, 2 + ibmap_nblocks, zbmap_nblocks, zbmap_buf);
     367}
     368
     369static void mark_bmap(uint32_t *bmap, int idx, int v)
     370{
     371        if (v == FREE)
     372                bmap[idx / 32] &= ~(1 << (idx % 32));
    313373        else
    314                 inodes = opt->n_inodes;
    315 
    316         /*Round up the number of inodes to fill block size*/
    317         ino_per_block = V3_INODES_PER_BLOCK(bs);
    318         if (inodes % ino_per_block)
    319                 inodes = ((inodes / ino_per_block) + 1) * ino_per_block;
    320         sb->s_ninodes = inodes > UINT32_MAX ? UINT32_MAX : inodes;
    321 
    322         /*Compute the number of zones on disk*/
    323         sb->s_nzones = opt->dev_nblocks > UINT32_MAX ?
    324                         UINT32_MAX : opt->dev_nblocks;
    325         sb->s_nzones /= (bs / MFS_MIN_BLOCKSIZE);
    326 
    327         /*Compute inode bitmap size in blocks*/
    328         sb->s_ibmap_blocks = UPPER(sb->s_ninodes, bs * 8);
    329 
    330         /*Compute zone bitmap size in blocks*/
    331         sb->s_zbmap_blocks = UPPER(sb->s_nzones, bs * 8);
    332 
    333         /*Compute inode table size*/
    334         unsigned long ninodes_blocks = sb->s_ninodes / ino_per_block;
    335 
    336         /*Compute first data zone position*/
    337         sb->s_first_data_zone = 2 + ninodes_blocks +
    338                                 sb->s_zbmap_blocks + sb->s_ibmap_blocks;
    339 
    340         /*Set log2 of zone to block ratio to zero*/
    341         sb->s_log2_zone_size = 0;
    342         sb->s_disk_version = 3;
    343         sb->s_block_size = bs;
    344 
    345         /*Superblock is now ready to be written on disk*/
    346         printf(NAME ": %d inodes\n", sb->s_ninodes);
    347         printf(NAME ": %d zones\n", sb->s_nzones);
    348         printf(NAME ": block size = %d\n", sb->s_block_size);
    349         printf(NAME ": inode table blocks = %ld\n", ninodes_blocks);
    350         printf(NAME ": first data zone = %d\n", sb->s_first_data_zone);
    351 
    352         block_write_direct(opt->handle, MFS_SUPERBLOCK, 1, sb);
    353 }
    354 
    355 static void init_bitmaps(uint32_t ninodes, uint32_t nzones,
    356                                 int bsize, mfs_params_t *opt)
    357 {
    358         uint8_t *ibmap_buf, *zbmap_buf;
    359         int ibmap_nblocks = 1 + (ninodes / 8) / bsize;
    360         int zbmap_nblocks = 1 + (nzones / 8) / bsize;
    361         unsigned int i;
    362 
    363         ibmap_buf = (uint8_t *) malloc(ibmap_nblocks * bsize);
    364         zbmap_buf = (uint8_t *) malloc(zbmap_nblocks * bsize);
    365 
    366         memset(ibmap_buf, 0xFF, ibmap_nblocks * bsize);
    367         memset(zbmap_buf, 0xFF, zbmap_nblocks * bsize);
    368 
    369         for (i = 2; i < ninodes; ++i)
    370                 mark_bmap(ibmap_buf, i, FREE);
    371 
    372         for (i = 2; i < nzones; ++i)
    373                 mark_bmap(zbmap_buf, i, FREE);
    374 
    375         ibmap_nblocks *= bsize / MFS_BLOCKSIZE;
    376         zbmap_nblocks *= bsize / MFS_BLOCKSIZE;
    377 
    378         block_write_direct(opt->handle, 2, ibmap_nblocks, ibmap_buf);
    379         block_write_direct(opt->handle, 2 + ibmap_nblocks, zbmap_nblocks, zbmap_buf);
    380 }
    381 
    382 static void mark_bmap(uint8_t *bmap, int idx, int v)
    383 {
    384         if (v == FREE)
    385                 bmap[idx / 8] &= ~(1 << (idx % 8));
    386         else
    387                 bmap[idx / 8] |= 1 << (idx % 8);
     374                bmap[idx / 32] |= 1 << (idx % 32);
    388375}
    389376
Note: See TracChangeset for help on using the changeset viewer.