Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (13 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod? silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian? keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René? Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/util-linux/mkfs_minix.c

    r821 r1770  
    3434 *      (Dr. Wettstein, greg%wind.uucp@plains.nodak.edu)
    3535 *
    36  * 30.10.94 - added support for v2 filesystem
    37  *        (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
     36 * 30.10.94  - added support for v2 filesystem
     37 *          (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
    3838 *
    3939 * 09.11.94  -  Added test to prevent overwrite of mounted fs adapted
     
    6363 */
    6464
    65 #include <stdio.h>
    66 #include <time.h>
    67 #include <unistd.h>
    68 #include <string.h>
    69 #include <signal.h>
    70 #include <fcntl.h>
    71 #include <ctype.h>
    72 #include <stdlib.h>
    73 #include <stdint.h>
    74 #include <termios.h>
    75 #include <sys/ioctl.h>
    76 #include <sys/param.h>
     65#include "libbb.h"
    7766#include <mntent.h>
    78 #include "busybox.h"
    79 
    80 #define MINIX_ROOT_INO 1
    81 #define MINIX_LINK_MAX  250
    82 #define MINIX2_LINK_MAX 65530
    83 
    84 #define MINIX_I_MAP_SLOTS   8
    85 #define MINIX_Z_MAP_SLOTS   64
    86 #define MINIX_SUPER_MAGIC   0x137F      /* original minix fs */
    87 #define MINIX_SUPER_MAGIC2  0x138F      /* minix fs, 30 char names */
    88 #define MINIX2_SUPER_MAGIC  0x2468      /* minix V2 fs */
    89 #define MINIX2_SUPER_MAGIC2 0x2478      /* minix V2 fs, 30 char names */
    90 #define MINIX_VALID_FS      0x0001      /* Clean fs. */
    91 #define MINIX_ERROR_FS      0x0002      /* fs has errors. */
    92 
    93 #define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
    94 #define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
    95 
    96 #define MINIX_V1        0x0001      /* original minix fs */
    97 #define MINIX_V2        0x0002      /* minix V2 fs */
    98 
    99 #define INODE_VERSION(inode)    inode->i_sb->u.minix_sb.s_version
    100 
    101 /*
    102  * This is the original minix inode layout on disk.
    103  * Note the 8-bit gid and atime and ctime.
    104  */
    105 struct minix_inode {
    106     uint16_t i_mode;
    107     uint16_t i_uid;
    108     uint32_t i_size;
    109     uint32_t i_time;
    110     uint8_t  i_gid;
    111     uint8_t  i_nlinks;
    112     uint16_t i_zone[9];
     67
     68#include "minix.h"
     69
     70#define DEBUG 0
     71
     72/* If debugging, store the very same times/uids/gids for image consistency */
     73#if DEBUG
     74# define CUR_TIME 0
     75# define GETUID 0
     76# define GETGID 0
     77#else
     78# define CUR_TIME time(NULL)
     79# define GETUID getuid()
     80# define GETGID getgid()
     81#endif
     82
     83enum {
     84    MAX_GOOD_BLOCKS         = 512,
     85    TEST_BUFFER_BLOCKS      = 16,
    11386};
    11487
    115 /*
    116  * The new minix inode has all the time entries, as well as
    117  * long block numbers and a third indirect block (7+1+1+1
    118  * instead of 7+1+1). Also, some previously 8-bit values are
    119  * now 16-bit. The inode is now 64 bytes instead of 32.
    120  */
    121 struct minix2_inode {
    122     uint16_t i_mode;
    123     uint16_t i_nlinks;
    124     uint16_t i_uid;
    125     uint16_t i_gid;
    126     uint32_t i_size;
    127     uint32_t i_atime;
    128     uint32_t i_mtime;
    129     uint32_t i_ctime;
    130     uint32_t i_zone[10];
     88#if !ENABLE_FEATURE_MINIX2
     89enum { version2 = 0 };
     90#endif
     91
     92struct globals {
     93    int dev_fd;
     94
     95#if ENABLE_FEATURE_MINIX2
     96    smallint version2;
     97#define version2 G.version2
     98#endif
     99    char *device_name;
     100    uint32_t total_blocks;
     101    int badblocks;
     102    int namelen;
     103    int dirsize;
     104    int magic;
     105    char *inode_buffer;
     106    char *inode_map;
     107    char *zone_map;
     108    int used_good_blocks;
     109    unsigned long req_nr_inodes;
     110    unsigned currently_testing;
     111
     112
     113    char root_block[BLOCK_SIZE];
     114    char super_block_buffer[BLOCK_SIZE];
     115    char boot_block_buffer[512];
     116    unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
     117    /* check_blocks(): buffer[] was the biggest static in entire bbox */
     118    char check_blocks_buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
    131119};
    132120
    133 /*
    134  * minix super-block data on disk
    135  */
    136 struct minix_super_block {
    137     uint16_t s_ninodes;
    138     uint16_t s_nzones;
    139     uint16_t s_imap_blocks;
    140     uint16_t s_zmap_blocks;
    141     uint16_t s_firstdatazone;
    142     uint16_t s_log_zone_size;
    143     uint32_t s_max_size;
    144     uint16_t s_magic;
    145     uint16_t s_state;
    146     uint32_t s_zones;
    147 };
    148 
    149 struct minix_dir_entry {
    150     uint16_t inode;
    151     char name[0];
    152 };
    153 
    154 #define NAME_MAX         255   /* # chars in a file name */
    155 
    156 #define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
    157 
    158 #define MINIX_VALID_FS               0x0001          /* Clean fs. */
    159 #define MINIX_ERROR_FS               0x0002          /* fs has errors. */
    160 
    161 #define MINIX_SUPER_MAGIC    0x137F          /* original minix fs */
    162 #define MINIX_SUPER_MAGIC2   0x138F          /* minix fs, 30 char names */
     121#define G (*ptr_to_globals)
     122
     123static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n)
     124{
     125    return (size + n-1) / n;
     126}
     127
     128#define INODE_BUF1              (((struct minix1_inode*)G.inode_buffer) - 1)
     129#define INODE_BUF2              (((struct minix2_inode*)G.inode_buffer) - 1)
     130
     131#define SB                      (*(struct minix_super_block*)G.super_block_buffer)
     132
     133#define SB_INODES               (SB.s_ninodes)
     134#define SB_IMAPS                (SB.s_imap_blocks)
     135#define SB_ZMAPS                (SB.s_zmap_blocks)
     136#define SB_FIRSTZONE            (SB.s_firstdatazone)
     137#define SB_ZONE_SIZE            (SB.s_log_zone_size)
     138#define SB_MAXSIZE              (SB.s_max_size)
     139#define SB_MAGIC                (SB.s_magic)
     140
     141#if !ENABLE_FEATURE_MINIX2
     142# define SB_ZONES               (SB.s_nzones)
     143# define INODE_BLOCKS           div_roundup(SB_INODES, MINIX1_INODES_PER_BLOCK)
     144#else
     145# define SB_ZONES               (version2 ? SB.s_zones : SB.s_nzones)
     146# define INODE_BLOCKS           div_roundup(SB_INODES, \
     147                                version2 ? MINIX2_INODES_PER_BLOCK : MINIX1_INODES_PER_BLOCK)
     148#endif
     149
     150#define INODE_BUFFER_SIZE       (INODE_BLOCKS * BLOCK_SIZE)
     151#define NORM_FIRSTZONE          (2 + SB_IMAPS + SB_ZMAPS + INODE_BLOCKS)
     152
     153/* Before you ask "where they come from?": */
     154/* setbit/clrbit are supplied by sys/param.h */
     155
     156static int minix_bit(const char* a, unsigned i)
     157{
     158      return a[i >> 3] & (1<<(i & 7));
     159}
     160
     161static void minix_setbit(char *a, unsigned i)
     162{
     163    setbit(a, i);
     164}
     165static void minix_clrbit(char *a, unsigned i)
     166{
     167    clrbit(a, i);
     168}
     169
     170/* Note: do not assume 0/1, it is 0/nonzero */
     171#define zone_in_use(x)  minix_bit(G.zone_map,(x)-SB_FIRSTZONE+1)
     172/*#define inode_in_use(x) minix_bit(G.inode_map,(x))*/
     173
     174#define mark_inode(x)   minix_setbit(G.inode_map,(x))
     175#define unmark_inode(x) minix_clrbit(G.inode_map,(x))
     176#define mark_zone(x)    minix_setbit(G.zone_map,(x)-SB_FIRSTZONE+1)
     177#define unmark_zone(x)  minix_clrbit(G.zone_map,(x)-SB_FIRSTZONE+1)
    163178
    164179#ifndef BLKGETSIZE
    165 #define BLKGETSIZE _IO(0x12,96)    /* return device size */
    166 #endif
    167 
    168 
    169 #ifndef __linux__
    170 #define volatile
    171 #endif
    172 
    173 #define MINIX_ROOT_INO 1
    174 #define MINIX_BAD_INO 2
    175 
    176 #define TEST_BUFFER_BLOCKS 16
    177 #define MAX_GOOD_BLOCKS 512
    178 
    179 #define UPPER(size,n) (((size)+((n)-1))/(n))
    180 #define INODE_SIZE (sizeof(struct minix_inode))
    181 #ifdef CONFIG_FEATURE_MINIX2
    182 #define INODE_SIZE2 (sizeof(struct minix2_inode))
    183 #define INODE_BLOCKS UPPER(INODES, (version2 ? MINIX2_INODES_PER_BLOCK \
    184                     : MINIX_INODES_PER_BLOCK))
    185 #else
    186 #define INODE_BLOCKS UPPER(INODES, (MINIX_INODES_PER_BLOCK))
    187 #endif
    188 #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE)
    189 
    190 #define BITS_PER_BLOCK (BLOCK_SIZE<<3)
    191 
    192 static char *device_name;
    193 static int DEV = -1;
    194 static uint32_t BLOCKS;
    195 static int check;
    196 static int badblocks;
    197 static int namelen = 30;        /* default (changed to 30, per Linus's
    198 
    199                                    suggestion, Sun Nov 21 08:05:07 1993) */
    200 static int dirsize = 32;
    201 static int magic = MINIX_SUPER_MAGIC2;
    202 static int version2;
    203 
    204 static char root_block[BLOCK_SIZE];
    205 
    206 static char *inode_buffer;
    207 
    208 #define Inode (((struct minix_inode *) inode_buffer)-1)
    209 #ifdef CONFIG_FEATURE_MINIX2
    210 #define Inode2 (((struct minix2_inode *) inode_buffer)-1)
    211 #endif
    212 static char super_block_buffer[BLOCK_SIZE];
    213 static char boot_block_buffer[512];
    214 
    215 #define Super (*(struct minix_super_block *)super_block_buffer)
    216 #define INODES (Super.s_ninodes)
    217 #ifdef CONFIG_FEATURE_MINIX2
    218 #define ZONES (version2 ? Super.s_zones : Super.s_nzones)
    219 #else
    220 #define ZONES (Super.s_nzones)
    221 #endif
    222 #define IMAPS (Super.s_imap_blocks)
    223 #define ZMAPS (Super.s_zmap_blocks)
    224 #define FIRSTZONE (Super.s_firstdatazone)
    225 #define ZONESIZE (Super.s_log_zone_size)
    226 #define MAXSIZE (Super.s_max_size)
    227 #define MAGIC (Super.s_magic)
    228 #define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)
    229 
    230 static char *inode_map;
    231 static char *zone_map;
    232 
    233 static unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
    234 static int used_good_blocks;
    235 static unsigned long req_nr_inodes;
    236 
    237 static inline int bit(char * a,unsigned int i)
    238 {
    239       return (a[i >> 3] & (1<<(i & 7))) != 0;
    240 }
    241 #define inode_in_use(x) (bit(inode_map,(x)))
    242 #define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1))
    243 
    244 #define mark_inode(x) (setbit(inode_map,(x)))
    245 #define unmark_inode(x) (clrbit(inode_map,(x)))
    246 
    247 #define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1))
    248 #define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1))
    249 
    250 /*
    251  * Check to make certain that our new filesystem won't be created on
    252  * an already mounted partition.  Code adapted from mke2fs, Copyright
    253  * (C) 1994 Theodore Ts'o.  Also licensed under GPL.
    254  */
    255 static inline void check_mount(void)
    256 {
    257     FILE *f;
    258     struct mntent *mnt;
    259 
    260     if ((f = setmntent(MOUNTED, "r")) == NULL)
    261         return;
    262     while ((mnt = getmntent(f)) != NULL)
    263         if (strcmp(device_name, mnt->mnt_fsname) == 0)
    264             break;
    265     endmntent(f);
    266     if (!mnt)
    267         return;
    268 
    269     bb_error_msg_and_die("%s is mounted; will not make a filesystem here!", device_name);
    270 }
     180# define BLKGETSIZE     _IO(0x12,96)    /* return device size */
     181#endif
     182
    271183
    272184static long valid_offset(int fd, int offset)
     
    274186    char ch;
    275187
    276     if (lseek(fd, offset, 0) < 0)
     188    if (lseek(fd, offset, SEEK_SET) < 0)
    277189        return 0;
    278190    if (read(fd, &ch, 1) < 1)
     
    281193}
    282194
    283 static inline int count_blocks(int fd)
     195static int count_blocks(int fd)
    284196{
    285197    int high, low;
     
    288200    for (high = 1; valid_offset(fd, high); high *= 2)
    289201        low = high;
     202
    290203    while (low < high - 1) {
    291204        const int mid = (low + high) / 2;
     
    300213}
    301214
    302 static inline int get_size(const char *file)
     215static int get_size(const char *file)
    303216{
    304217    int fd;
    305218    long size;
    306219
    307     fd = bb_xopen3(file, O_RDWR, 0);
     220    fd = xopen(file, O_RDWR);
    308221    if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
    309222        close(fd);
     
    316229}
    317230
    318 static inline void write_tables(void)
     231static void write_tables(void)
    319232{
    320233    /* Mark the super block valid. */
    321     Super.s_state |= MINIX_VALID_FS;
    322     Super.s_state &= ~MINIX_ERROR_FS;
    323 
    324     if (lseek(DEV, 0, SEEK_SET))
    325         bb_error_msg_and_die("seek to boot block failed in write_tables");
    326     if (512 != write(DEV, boot_block_buffer, 512))
    327         bb_error_msg_and_die("unable to clear boot sector");
    328     if (BLOCK_SIZE != lseek(DEV, BLOCK_SIZE, SEEK_SET))
    329         bb_error_msg_and_die("seek failed in write_tables");
    330     if (BLOCK_SIZE != write(DEV, super_block_buffer, BLOCK_SIZE))
    331         bb_error_msg_and_die("unable to write super-block");
    332     if (IMAPS * BLOCK_SIZE != write(DEV, inode_map, IMAPS * BLOCK_SIZE))
    333         bb_error_msg_and_die("unable to write inode map");
    334     if (ZMAPS * BLOCK_SIZE != write(DEV, zone_map, ZMAPS * BLOCK_SIZE))
    335         bb_error_msg_and_die("unable to write zone map");
    336     if (INODE_BUFFER_SIZE != write(DEV, inode_buffer, INODE_BUFFER_SIZE))
    337         bb_error_msg_and_die("unable to write inodes");
    338 
     234    SB.s_state |= MINIX_VALID_FS;
     235    SB.s_state &= ~MINIX_ERROR_FS;
     236
     237    msg_eol = "seek to 0 failed";
     238    xlseek(G.dev_fd, 0, SEEK_SET);
     239
     240    msg_eol = "cannot clear boot sector";
     241    xwrite(G.dev_fd, G.boot_block_buffer, 512);
     242
     243    msg_eol = "seek to BLOCK_SIZE failed";
     244    xlseek(G.dev_fd, BLOCK_SIZE, SEEK_SET);
     245
     246    msg_eol = "cannot write superblock";
     247    xwrite(G.dev_fd, G.super_block_buffer, BLOCK_SIZE);
     248
     249    msg_eol = "cannot write inode map";
     250    xwrite(G.dev_fd, G.inode_map, SB_IMAPS * BLOCK_SIZE);
     251
     252    msg_eol = "cannot write zone map";
     253    xwrite(G.dev_fd, G.zone_map, SB_ZMAPS * BLOCK_SIZE);
     254
     255    msg_eol = "cannot write inodes";
     256    xwrite(G.dev_fd, G.inode_buffer, INODE_BUFFER_SIZE);
     257
     258    msg_eol = "\n";
    339259}
    340260
    341261static void write_block(int blk, char *buffer)
    342262{
    343     if (blk * BLOCK_SIZE != lseek(DEV, blk * BLOCK_SIZE, SEEK_SET))
    344         bb_error_msg_and_die("seek failed in write_block");
    345     if (BLOCK_SIZE != write(DEV, buffer, BLOCK_SIZE))
    346         bb_error_msg_and_die("write failed in write_block");
     263    xlseek(G.dev_fd, blk * BLOCK_SIZE, SEEK_SET);
     264    xwrite(G.dev_fd, buffer, BLOCK_SIZE);
    347265}
    348266
     
    351269    int blk;
    352270
    353     if (used_good_blocks + 1 >= MAX_GOOD_BLOCKS)
     271    if (G.used_good_blocks + 1 >= MAX_GOOD_BLOCKS)
    354272        bb_error_msg_and_die("too many bad blocks");
    355     if (used_good_blocks)
    356         blk = good_blocks_table[used_good_blocks - 1] + 1;
     273    if (G.used_good_blocks)
     274        blk = G.good_blocks_table[G.used_good_blocks - 1] + 1;
    357275    else
    358         blk = FIRSTZONE;
    359     while (blk < ZONES && zone_in_use(blk))
     276        blk = SB_FIRSTZONE;
     277    while (blk < SB_ZONES && zone_in_use(blk))
    360278        blk++;
    361     if (blk >= ZONES)
     279    if (blk >= SB_ZONES)
    362280        bb_error_msg_and_die("not enough good blocks");
    363     good_blocks_table[used_good_blocks] = blk;
    364     used_good_blocks++;
     281    G.good_blocks_table[G.used_good_blocks] = blk;
     282    G.used_good_blocks++;
    365283    return blk;
    366284}
    367285
    368 static inline void mark_good_blocks(void)
     286static void mark_good_blocks(void)
    369287{
    370288    int blk;
    371289
    372     for (blk = 0; blk < used_good_blocks; blk++)
    373         mark_zone(good_blocks_table[blk]);
     290    for (blk = 0; blk < G.used_good_blocks; blk++)
     291        mark_zone(G.good_blocks_table[blk]);
    374292}
    375293
     
    377295{
    378296    if (!zone)
    379         zone = FIRSTZONE - 1;
    380     while (++zone < ZONES)
     297        zone = SB_FIRSTZONE - 1;
     298    while (++zone < SB_ZONES)
    381299        if (zone_in_use(zone))
    382300            return zone;
     
    384302}
    385303
    386 static inline void make_bad_inode(void)
    387 {
    388     struct minix_inode *inode = &Inode[MINIX_BAD_INO];
     304static void make_bad_inode(void)
     305{
     306    struct minix1_inode *inode = &INODE_BUF1[MINIX_BAD_INO];
    389307    int i, j, zone;
    390308    int ind = 0, dind = 0;
     
    394312#define NEXT_BAD (zone = next(zone))
    395313
    396     if (!badblocks)
     314    if (!G.badblocks)
    397315        return;
    398316    mark_inode(MINIX_BAD_INO);
    399317    inode->i_nlinks = 1;
    400     inode->i_time = time(NULL);
     318    /* BTW, setting this makes all images different */
     319    /* it's harder to check for bugs then - diff isn't helpful :(... */
     320    inode->i_time = CUR_TIME;
    401321    inode->i_mode = S_IFREG + 0000;
    402     inode->i_size = badblocks * BLOCK_SIZE;
     322    inode->i_size = G.badblocks * BLOCK_SIZE;
    403323    zone = next(0);
    404324    for (i = 0; i < 7; i++) {
     
    427347    }
    428348    bb_error_msg_and_die("too many bad blocks");
    429   end_bad:
     349 end_bad:
    430350    if (ind)
    431351        write_block(ind, (char *) ind_block);
     
    434354}
    435355
    436 #ifdef CONFIG_FEATURE_MINIX2
    437 static inline void make_bad_inode2(void)
    438 {
    439     struct minix2_inode *inode = &Inode2[MINIX_BAD_INO];
     356#if ENABLE_FEATURE_MINIX2
     357static void make_bad_inode2(void)
     358{
     359    struct minix2_inode *inode = &INODE_BUF2[MINIX_BAD_INO];
    440360    int i, j, zone;
    441361    int ind = 0, dind = 0;
     
    443363    unsigned long dind_block[BLOCK_SIZE >> 2];
    444364
    445     if (!badblocks)
     365    if (!G.badblocks)
    446366        return;
    447367    mark_inode(MINIX_BAD_INO);
    448368    inode->i_nlinks = 1;
    449     inode->i_atime = inode->i_mtime = inode->i_ctime = time(NULL);
     369    inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME;
    450370    inode->i_mode = S_IFREG + 0000;
    451     inode->i_size = badblocks * BLOCK_SIZE;
     371    inode->i_size = G.badblocks * BLOCK_SIZE;
    452372    zone = next(0);
    453373    for (i = 0; i < 7; i++) {
     
    477397    /* Could make triple indirect block here */
    478398    bb_error_msg_and_die("too many bad blocks");
    479   end_bad:
     399 end_bad:
    480400    if (ind)
    481401        write_block(ind, (char *) ind_block);
     
    483403        write_block(dind, (char *) dind_block);
    484404}
    485 #endif
    486 
    487 static inline void make_root_inode(void)
    488 {
    489     struct minix_inode *inode = &Inode[MINIX_ROOT_INO];
     405#else
     406void make_bad_inode2(void);
     407#endif
     408
     409static void make_root_inode(void)
     410{
     411    struct minix1_inode *inode = &INODE_BUF1[MINIX_ROOT_INO];
    490412
    491413    mark_inode(MINIX_ROOT_INO);
    492414    inode->i_zone[0] = get_free_block();
    493415    inode->i_nlinks = 2;
    494     inode->i_time = time(NULL);
    495     if (badblocks)
    496         inode->i_size = 3 * dirsize;
     416    inode->i_time = CUR_TIME;
     417    if (G.badblocks)
     418        inode->i_size = 3 * G.dirsize;
    497419    else {
    498         root_block[2 * dirsize] = '\0';
    499         root_block[2 * dirsize + 1] = '\0';
    500         inode->i_size = 2 * dirsize;
     420        G.root_block[2 * G.dirsize] = '\0';
     421        G.root_block[2 * G.dirsize + 1] = '\0';
     422        inode->i_size = 2 * G.dirsize;
    501423    }
    502424    inode->i_mode = S_IFDIR + 0755;
    503     inode->i_uid = getuid();
     425    inode->i_uid = GETUID;
    504426    if (inode->i_uid)
    505         inode->i_gid = getgid();
    506     write_block(inode->i_zone[0], root_block);
    507 }
    508 
    509 #ifdef CONFIG_FEATURE_MINIX2
    510 static inline void make_root_inode2(void)
    511 {
    512     struct minix2_inode *inode = &Inode2[MINIX_ROOT_INO];
     427        inode->i_gid = GETGID;
     428    write_block(inode->i_zone[0], G.root_block);
     429}
     430
     431#if ENABLE_FEATURE_MINIX2
     432static void make_root_inode2(void)
     433{
     434    struct minix2_inode *inode = &INODE_BUF2[MINIX_ROOT_INO];
    513435
    514436    mark_inode(MINIX_ROOT_INO);
    515437    inode->i_zone[0] = get_free_block();
    516438    inode->i_nlinks = 2;
    517     inode->i_atime = inode->i_mtime = inode->i_ctime = time(NULL);
    518     if (badblocks)
    519         inode->i_size = 3 * dirsize;
     439    inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME;
     440    if (G.badblocks)
     441        inode->i_size = 3 * G.dirsize;
    520442    else {
    521         root_block[2 * dirsize] = '\0';
    522         root_block[2 * dirsize + 1] = '\0';
    523         inode->i_size = 2 * dirsize;
     443        G.root_block[2 * G.dirsize] = '\0';
     444        G.root_block[2 * G.dirsize + 1] = '\0';
     445        inode->i_size = 2 * G.dirsize;
    524446    }
    525447    inode->i_mode = S_IFDIR + 0755;
    526     inode->i_uid = getuid();
     448    inode->i_uid = GETUID;
    527449    if (inode->i_uid)
    528         inode->i_gid = getgid();
    529     write_block(inode->i_zone[0], root_block);
    530 }
    531 #endif
    532 
    533 static inline void setup_tables(void)
    534 {
    535     int i;
     450        inode->i_gid = GETGID;
     451    write_block(inode->i_zone[0], G.root_block);
     452}
     453#else
     454void make_root_inode2(void);
     455#endif
     456
     457/*
     458 * Perform a test of a block; return the number of
     459 * blocks readable.
     460 */
     461static size_t do_check(char *buffer, size_t try, unsigned current_block)
     462{
     463    ssize_t got;
     464
     465    /* Seek to the correct loc. */
     466    msg_eol = "seek failed during testing of blocks";
     467    xlseek(G.dev_fd, current_block * BLOCK_SIZE, SEEK_SET);
     468    msg_eol = "\n";
     469
     470    /* Try the read */
     471    got = read(G.dev_fd, buffer, try * BLOCK_SIZE);
     472    if (got < 0)
     473        got = 0;
     474    try = ((size_t)got) / BLOCK_SIZE;
     475
     476    if (got & (BLOCK_SIZE - 1))
     477        fprintf(stderr, "Short read at block %u\n", (unsigned)(current_block + try));
     478    return try;
     479}
     480
     481static void alarm_intr(int alnum)
     482{
     483    if (G.currently_testing >= SB_ZONES)
     484        return;
     485    signal(SIGALRM, alarm_intr);
     486    alarm(5);
     487    if (!G.currently_testing)
     488        return;
     489    printf("%d ...", G.currently_testing);
     490    fflush(stdout);
     491}
     492
     493static void check_blocks(void)
     494{
     495    size_t try, got;
     496
     497    G.currently_testing = 0;
     498    signal(SIGALRM, alarm_intr);
     499    alarm(5);
     500    while (G.currently_testing < SB_ZONES) {
     501        msg_eol = "seek failed in check_blocks";
     502        xlseek(G.dev_fd, G.currently_testing * BLOCK_SIZE, SEEK_SET);
     503        msg_eol = "\n";
     504        try = TEST_BUFFER_BLOCKS;
     505        if (G.currently_testing + try > SB_ZONES)
     506            try = SB_ZONES - G.currently_testing;
     507        got = do_check(G.check_blocks_buffer, try, G.currently_testing);
     508        G.currently_testing += got;
     509        if (got == try)
     510            continue;
     511        if (G.currently_testing < SB_FIRSTZONE)
     512            bb_error_msg_and_die("bad blocks before data-area: cannot make fs");
     513        mark_zone(G.currently_testing);
     514        G.badblocks++;
     515        G.currently_testing++;
     516    }
     517    alarm(0);
     518    printf("%d bad block(s)\n", G.badblocks);
     519}
     520
     521static void get_list_blocks(char *filename)
     522{
     523    FILE *listfile;
     524    unsigned long blockno;
     525
     526    listfile = xfopen(filename, "r");
     527    while (!feof(listfile)) {
     528        fscanf(listfile, "%ld\n", &blockno);
     529        mark_zone(blockno);
     530        G.badblocks++;
     531    }
     532    printf("%d bad block(s)\n", G.badblocks);
     533}
     534
     535static void setup_tables(void)
     536{
    536537    unsigned long inodes;
    537 
    538     memset(super_block_buffer, 0, BLOCK_SIZE);
    539     memset(boot_block_buffer, 0, 512);
    540     MAGIC = magic;
    541     ZONESIZE = 0;
    542     MAXSIZE = version2 ? 0x7fffffff : (7 + 512 + 512 * 512) * 1024;
    543 #ifdef CONFIG_FEATURE_MINIX2
    544     if (version2) {
    545         Super.s_zones =  BLOCKS;
    546     } else
    547 #endif
    548         Super.s_nzones = BLOCKS;
    549 
    550 /* some magic nrs: 1 inode / 3 blocks */
    551     if (req_nr_inodes == 0)
    552         inodes = BLOCKS / 3;
     538    unsigned norm_firstzone;
     539    unsigned sb_zmaps;
     540    unsigned i;
     541
     542    /* memset(G.super_block_buffer, 0, BLOCK_SIZE); */
     543    /* memset(G.boot_block_buffer, 0, 512); */
     544    SB_MAGIC = G.magic;
     545    SB_ZONE_SIZE = 0;
     546    SB_MAXSIZE = version2 ? 0x7fffffff : (7 + 512 + 512 * 512) * 1024;
     547    if (version2)
     548        SB.s_zones = G.total_blocks;
    553549    else
    554         inodes = req_nr_inodes;
     550        SB.s_nzones = G.total_blocks;
     551
     552    /* some magic nrs: 1 inode / 3 blocks */
     553    if (G.req_nr_inodes == 0)
     554        inodes = G.total_blocks / 3;
     555    else
     556        inodes = G.req_nr_inodes;
    555557    /* Round up inode count to fill block size */
    556 #ifdef CONFIG_FEATURE_MINIX2
    557558    if (version2)
    558         inodes = ((inodes + MINIX2_INODES_PER_BLOCK - 1) &
    559                   ~(MINIX2_INODES_PER_BLOCK - 1));
     559        inodes = (inodes + MINIX2_INODES_PER_BLOCK - 1) &
     560                         ~(MINIX2_INODES_PER_BLOCK - 1);
    560561    else
    561 #endif
    562         inodes = ((inodes + MINIX_INODES_PER_BLOCK - 1) &
    563                   ~(MINIX_INODES_PER_BLOCK - 1));
     562        inodes = (inodes + MINIX1_INODES_PER_BLOCK - 1) &
     563                         ~(MINIX1_INODES_PER_BLOCK - 1);
    564564    if (inodes > 65535)
    565565        inodes = 65535;
    566     INODES = inodes;
    567     IMAPS = UPPER(INODES + 1, BITS_PER_BLOCK);
    568     ZMAPS = 0;
    569     i = 0;
    570     while (ZMAPS !=
    571            UPPER(BLOCKS - (2 + IMAPS + ZMAPS + INODE_BLOCKS) + 1,
    572                  BITS_PER_BLOCK) && i < 1000) {
    573         ZMAPS =
    574             UPPER(BLOCKS - (2 + IMAPS + ZMAPS + INODE_BLOCKS) + 1,
    575                   BITS_PER_BLOCK);
    576         i++;
    577     }
     566    SB_INODES = inodes;
     567    SB_IMAPS = div_roundup(SB_INODES + 1, BITS_PER_BLOCK);
     568
    578569    /* Real bad hack but overwise mkfs.minix can be thrown
    579570     * in infinite loop...
    580571     * try:
    581572     * dd if=/dev/zero of=test.fs count=10 bs=1024
    582      * /sbin/mkfs.minix -i 200 test.fs
    583      * */
    584     if (i >= 999) {
    585         bb_error_msg_and_die("unable to allocate buffers for maps");
    586     }
    587     FIRSTZONE = NORM_FIRSTZONE;
    588     inode_map = xmalloc(IMAPS * BLOCK_SIZE);
    589     zone_map = xmalloc(ZMAPS * BLOCK_SIZE);
    590     memset(inode_map, 0xff, IMAPS * BLOCK_SIZE);
    591     memset(zone_map, 0xff, ZMAPS * BLOCK_SIZE);
    592     for (i = FIRSTZONE; i < ZONES; i++)
     573     * mkfs.minix -i 200 test.fs
     574     */
     575    /* This code is not insane: NORM_FIRSTZONE is not a constant,
     576     * it is calculated from SB_INODES, SB_IMAPS and SB_ZMAPS */
     577    i = 999;
     578    SB_ZMAPS = 0;
     579    do {
     580        norm_firstzone = NORM_FIRSTZONE;
     581        sb_zmaps = div_roundup(G.total_blocks - norm_firstzone + 1, BITS_PER_BLOCK);
     582        if (SB_ZMAPS == sb_zmaps) goto got_it;
     583        SB_ZMAPS = sb_zmaps;
     584        /* new SB_ZMAPS, need to recalc NORM_FIRSTZONE */
     585    } while (--i);
     586    bb_error_msg_and_die("incompatible size/inode count, try different -i N");
     587 got_it:
     588
     589    SB_FIRSTZONE = norm_firstzone;
     590    G.inode_map = xmalloc(SB_IMAPS * BLOCK_SIZE);
     591    G.zone_map = xmalloc(SB_ZMAPS * BLOCK_SIZE);
     592    memset(G.inode_map, 0xff, SB_IMAPS * BLOCK_SIZE);
     593    memset(G.zone_map, 0xff, SB_ZMAPS * BLOCK_SIZE);
     594    for (i = SB_FIRSTZONE; i < SB_ZONES; i++)
    593595        unmark_zone(i);
    594     for (i = MINIX_ROOT_INO; i <= INODES; i++)
     596    for (i = MINIX_ROOT_INO; i <= SB_INODES; i++)
    595597        unmark_inode(i);
    596     inode_buffer = xmalloc(INODE_BUFFER_SIZE);
    597     memset(inode_buffer, 0, INODE_BUFFER_SIZE);
    598     printf("%ld inodes\n", (long)INODES);
    599     printf("%ld blocks\n", (long)ZONES);
    600     printf("Firstdatazone=%ld (%ld)\n", (long)FIRSTZONE, (long)NORM_FIRSTZONE);
    601     printf("Zonesize=%d\n", BLOCK_SIZE << ZONESIZE);
    602     printf("Maxsize=%ld\n\n", (long)MAXSIZE);
    603 }
    604 
    605 /*
    606  * Perform a test of a block; return the number of
    607  * blocks readable/writable.
    608  */
    609 static inline long do_check(char *buffer, int try, unsigned int current_block)
    610 {
    611     long got;
    612 
    613     /* Seek to the correct loc. */
    614     if (lseek(DEV, current_block * BLOCK_SIZE, SEEK_SET) !=
    615         current_block * BLOCK_SIZE) {
    616         bb_error_msg_and_die("seek failed during testing of blocks");
    617     }
    618 
    619 
    620     /* Try the read */
    621     got = read(DEV, buffer, try * BLOCK_SIZE);
    622     if (got < 0)
    623         got = 0;
    624     if (got & (BLOCK_SIZE - 1)) {
    625         printf("Weird values in do_check: probably bugs\n");
    626     }
    627     got /= BLOCK_SIZE;
    628     return got;
    629 }
    630 
    631 static unsigned int currently_testing;
    632 
    633 static void alarm_intr(int alnum)
    634 {
    635     if (currently_testing >= ZONES)
    636         return;
    637     signal(SIGALRM, alarm_intr);
    638     alarm(5);
    639     if (!currently_testing)
    640         return;
    641     printf("%d ...", currently_testing);
    642     fflush(stdout);
    643 }
    644 
    645 static void check_blocks(void)
    646 {
    647     int try, got;
    648     static char buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
    649 
    650     currently_testing = 0;
    651     signal(SIGALRM, alarm_intr);
    652     alarm(5);
    653     while (currently_testing < ZONES) {
    654         if (lseek(DEV, currently_testing * BLOCK_SIZE, SEEK_SET) !=
    655             currently_testing * BLOCK_SIZE)
    656             bb_error_msg_and_die("seek failed in check_blocks");
    657         try = TEST_BUFFER_BLOCKS;
    658         if (currently_testing + try > ZONES)
    659             try = ZONES - currently_testing;
    660         got = do_check(buffer, try, currently_testing);
    661         currently_testing += got;
    662         if (got == try)
    663             continue;
    664         if (currently_testing < FIRSTZONE)
    665             bb_error_msg_and_die("bad blocks before data-area: cannot make fs");
    666         mark_zone(currently_testing);
    667         badblocks++;
    668         currently_testing++;
    669     }
    670     if (badblocks > 1)
    671         printf("%d bad blocks\n", badblocks);
    672     else if (badblocks == 1)
    673         printf("one bad block\n");
    674 }
    675 
    676 static void get_list_blocks(char *filename)
    677 {
    678     FILE *listfile;
    679     unsigned long blockno;
    680 
    681     listfile = bb_xfopen(filename, "r");
    682     while (!feof(listfile)) {
    683         fscanf(listfile, "%ld\n", &blockno);
    684         mark_zone(blockno);
    685         badblocks++;
    686     }
    687     if (badblocks > 1)
    688         printf("%d bad blocks\n", badblocks);
    689     else if (badblocks == 1)
    690         printf("one bad block\n");
    691 }
    692 
     598    G.inode_buffer = xzalloc(INODE_BUFFER_SIZE);
     599    printf("%ld inodes\n", (long)SB_INODES);
     600    printf("%ld blocks\n", (long)SB_ZONES);
     601    printf("Firstdatazone=%ld (%ld)\n", (long)SB_FIRSTZONE, (long)norm_firstzone);
     602    printf("Zonesize=%d\n", BLOCK_SIZE << SB_ZONE_SIZE);
     603    printf("Maxsize=%ld\n", (long)SB_MAXSIZE);
     604}
     605
     606int mkfs_minix_main(int argc, char **argv);
    693607int mkfs_minix_main(int argc, char **argv)
    694608{
    695     int i=1;
     609    struct mntent *mp;
     610    unsigned opt;
    696611    char *tmp;
    697612    struct stat statbuf;
     613    char *str_i, *str_n;
    698614    char *listfile = NULL;
    699     int stopIt=FALSE;
    700 
    701     if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
     615
     616    PTR_TO_GLOBALS = xzalloc(sizeof(G));
     617/* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */
     618    G.namelen = 30;
     619    G.dirsize = 32;
     620    G.magic = MINIX1_SUPER_MAGIC2;
     621
     622    if (INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE)
    702623        bb_error_msg_and_die("bad inode size");
    703 #ifdef CONFIG_FEATURE_MINIX2
     624#if ENABLE_FEATURE_MINIX2
    704625    if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
    705626        bb_error_msg_and_die("bad inode size");
    706627#endif
    707628
    708     /* Parse options */
    709     argv++;
    710     while (--argc >= 0 && *argv && **argv) {
    711         if (**argv == '-') {
    712             stopIt=FALSE;
    713             while (i > 0 && *++(*argv) && stopIt==FALSE) {
    714                 switch (**argv) {
    715                     case 'c':
    716                         check = 1;
    717                         break;
    718                     case 'i':
    719                         {
    720                             char *cp=NULL;
    721                             if (*(*argv+1) != 0) {
    722                                 cp = ++(*argv);
    723                             } else {
    724                                 if (--argc == 0) {
    725                                     goto goodbye;
    726                                 }
    727                                 cp = *(++argv);
    728                             }
    729                             req_nr_inodes = strtoul(cp, &tmp, 0);
    730                             if (*tmp)
    731                                 bb_show_usage();
    732                             stopIt=TRUE;
    733                             break;
    734                         }
    735                     case 'l':
    736                         if (--argc == 0) {
    737                             goto goodbye;
    738                         }
    739                         listfile = *(++argv);
    740                         break;
    741                     case 'n':
    742                         {
    743                             char *cp=NULL;
    744 
    745                             if (*(*argv+1) != 0) {
    746                                 cp = ++(*argv);
    747                             } else {
    748                                 if (--argc == 0) {
    749                                     goto goodbye;
    750                                 }
    751                                 cp = *(++argv);
    752                             }
    753                             i = strtoul(cp, &tmp, 0);
    754                             if (*tmp)
    755                                 bb_show_usage();
    756                             if (i == 14)
    757                                 magic = MINIX_SUPER_MAGIC;
    758                             else if (i == 30)
    759                                 magic = MINIX_SUPER_MAGIC2;
    760                             else
    761                                 bb_show_usage();
    762                             namelen = i;
    763                             dirsize = i + 2;
    764                             stopIt=TRUE;
    765                             break;
    766                         }
    767                     case 'v':
    768 #ifdef CONFIG_FEATURE_MINIX2
    769                         version2 = 1;
     629    opt = getopt32(argv, "ci:l:n:v", &str_i, &listfile, &str_n);
     630    argv += optind;
     631    //if (opt & 1) -c
     632    if (opt & 2) G.req_nr_inodes = xatoul(str_i); // -i
     633    //if (opt & 4) -l
     634    if (opt & 8) { // -n
     635        G.namelen = xatoi_u(str_n);
     636        if (G.namelen == 14) G.magic = MINIX1_SUPER_MAGIC;
     637        else if (G.namelen == 30) G.magic = MINIX1_SUPER_MAGIC2;
     638        else bb_show_usage();
     639        G.dirsize = G.namelen + 2;
     640    }
     641    if (opt & 0x10) { // -v
     642#if ENABLE_FEATURE_MINIX2
     643        version2 = 1;
    770644#else
    771                         bb_error_msg("%s: not compiled with minix v2 support",
    772                                 device_name);
    773                         exit(-1);
    774 #endif
    775                         break;
    776                     case '-':
    777                     case 'h':
    778                     default:
    779 goodbye:
    780                         bb_show_usage();
    781                 }
    782             }
    783         } else {
    784             if (device_name == NULL)
    785                 device_name = *argv;
    786             else if (BLOCKS == 0)
    787                 BLOCKS = strtol(*argv, &tmp, 0);
    788             else {
    789                 goto goodbye;
    790             }
    791         }
    792         argv++;
    793     }
    794 
    795     if (device_name && !BLOCKS)
    796         BLOCKS = get_size(device_name) / 1024;
    797     if (!device_name || BLOCKS < 10) {
     645        bb_error_msg_and_die("not compiled with minix v2 support");
     646#endif
     647    }
     648
     649    G.device_name = *argv++;
     650    if (!G.device_name)
    798651        bb_show_usage();
    799     }
    800 #ifdef CONFIG_FEATURE_MINIX2
     652    if (*argv)
     653        G.total_blocks = xatou32(*argv);
     654    else
     655        G.total_blocks = get_size(G.device_name) / 1024;
     656
     657    if (G.total_blocks < 10)
     658        bb_error_msg_and_die("must have at least 10 blocks");
     659
    801660    if (version2) {
    802         if (namelen == 14)
    803             magic = MINIX2_SUPER_MAGIC;
    804         else
    805             magic = MINIX2_SUPER_MAGIC2;
    806     } else
    807 #endif
    808     if (BLOCKS > 65535)
    809         BLOCKS = 65535;
    810     check_mount();              /* is it already mounted? */
    811     tmp = root_block;
     661        G.magic = MINIX2_SUPER_MAGIC2;
     662        if (G.namelen == 14)
     663            G.magic = MINIX2_SUPER_MAGIC;
     664    } else if (G.total_blocks > 65535)
     665        G.total_blocks = 65535;
     666
     667    /* Check if it is mounted */
     668    mp = find_mount_point(G.device_name, NULL);
     669    if (mp && strcmp(G.device_name, mp->mnt_fsname) == 0)
     670        bb_error_msg_and_die("%s is mounted on %s; "
     671                "refusing to make a filesystem",
     672                G.device_name, mp->mnt_dir);
     673
     674    G.dev_fd = xopen(G.device_name, O_RDWR);
     675    if (fstat(G.dev_fd, &statbuf) < 0)
     676        bb_error_msg_and_die("cannot stat %s", G.device_name);
     677    if (!S_ISBLK(statbuf.st_mode))
     678        opt &= ~1; // clear -c (check)
     679
     680/* I don't know why someone has special code to prevent mkfs.minix
     681 * on IDE devices. Why IDE but not SCSI, etc?... */
     682#if 0
     683    else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
     684        /* what is this? */
     685        bb_error_msg_and_die("will not try "
     686            "to make filesystem on '%s'", G.device_name);
     687#endif
     688
     689    tmp = G.root_block;
    812690    *(short *) tmp = 1;
    813691    strcpy(tmp + 2, ".");
    814     tmp += dirsize;
     692    tmp += G.dirsize;
    815693    *(short *) tmp = 1;
    816694    strcpy(tmp + 2, "..");
    817     tmp += dirsize;
     695    tmp += G.dirsize;
    818696    *(short *) tmp = 2;
    819697    strcpy(tmp + 2, ".badblocks");
    820     DEV = bb_xopen3(device_name, O_RDWR, 0);
    821     if (fstat(DEV, &statbuf) < 0)
    822         bb_error_msg_and_die("unable to stat %s", device_name);
    823     if (!S_ISBLK(statbuf.st_mode))
    824         check = 0;
    825     else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
    826         bb_error_msg_and_die("will not try to make filesystem on '%s'", device_name);
     698
    827699    setup_tables();
    828     if (check)
     700
     701    if (opt & 1) // -c ?
    829702        check_blocks();
    830703    else if (listfile)
    831704        get_list_blocks(listfile);
    832 #ifdef CONFIG_FEATURE_MINIX2
     705
    833706    if (version2) {
    834707        make_root_inode2();
    835708        make_bad_inode2();
    836     } else
    837 #endif
    838     {
     709    } else {
    839710        make_root_inode();
    840711        make_bad_inode();
    841712    }
     713
    842714    mark_good_blocks();
    843715    write_tables();
    844716    return 0;
    845 
    846 }
     717}
Note: See TracChangeset for help on using the changeset viewer.