aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-11-29 22:33:47 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-11-29 22:33:47 +0000
commitb26e9c535562bdb3bbf0e0b5c4705393f9abe5cb (patch)
treea013b9826f7079ad7aaf1a884dc063df5821cf05
parent9d8812e459a9e88f0fbc903180a48e2fae0e65af (diff)
downloadbusybox-w32-b26e9c535562bdb3bbf0e0b5c4705393f9abe5cb.tar.gz
busybox-w32-b26e9c535562bdb3bbf0e0b5c4705393f9abe5cb.tar.bz2
busybox-w32-b26e9c535562bdb3bbf0e0b5c4705393f9abe5cb.zip
mkfs.minix: more cleanups, -~300 bytes of code.
Added debugging support. git-svn-id: svn://busybox.net/trunk/busybox@16734 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--util-linux/mkfs_minix.c406
1 files changed, 204 insertions, 202 deletions
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c
index e9ba50046..687cf675f 100644
--- a/util-linux/mkfs_minix.c
+++ b/util-linux/mkfs_minix.c
@@ -33,8 +33,8 @@
33 * 03.01.94 - Added support for file system valid flag. 33 * 03.01.94 - Added support for file system valid flag.
34 * (Dr. Wettstein, greg%wind.uucp@plains.nodak.edu) 34 * (Dr. Wettstein, greg%wind.uucp@plains.nodak.edu)
35 * 35 *
36 * 30.10.94 - added support for v2 filesystem 36 * 30.10.94 - added support for v2 filesystem
37 * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) 37 * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
38 * 38 *
39 * 09.11.94 - Added test to prevent overwrite of mounted fs adapted 39 * 09.11.94 - Added test to prevent overwrite of mounted fs adapted
40 * from Theodore Ts'o's (tytso@athena.mit.edu) mke2fs 40 * from Theodore Ts'o's (tytso@athena.mit.edu) mke2fs
@@ -65,32 +65,24 @@
65#include "busybox.h" 65#include "busybox.h"
66#include <mntent.h> 66#include <mntent.h>
67 67
68#define MINIX_ROOT_INO 1 68#define DEBUG 0
69#define MINIX_LINK_MAX 250
70#define MINIX2_LINK_MAX 65530
71 69
72#define MINIX_I_MAP_SLOTS 8 70/* If debugging, store the very same times/uids/gids for image consistency */
73#define MINIX_Z_MAP_SLOTS 64 71#if DEBUG
74#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ 72# define CUR_TIME 0
75#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ 73# define GETUID 0
76#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ 74# define GETGID 0
77#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ 75#else
78#define MINIX_VALID_FS 0x0001 /* Clean fs. */ 76# define CUR_TIME time(NULL)
79#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ 77# define GETUID getuid()
80 78# define GETGID getgid()
81#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) 79#endif
82#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
83
84#define MINIX_V1 0x0001 /* original minix fs */
85#define MINIX_V2 0x0002 /* minix V2 fs */
86
87#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version
88 80
89/* 81/*
90 * This is the original minix inode layout on disk. 82 * This is the original minix inode layout on disk.
91 * Note the 8-bit gid and atime and ctime. 83 * Note the 8-bit gid and atime and ctime.
92 */ 84 */
93struct minix_inode { 85struct minix1_inode {
94 uint16_t i_mode; 86 uint16_t i_mode;
95 uint16_t i_uid; 87 uint16_t i_uid;
96 uint32_t i_size; 88 uint32_t i_size;
@@ -139,107 +131,106 @@ struct minix_dir_entry {
139 char name[0]; 131 char name[0];
140}; 132};
141 133
142#define NAME_MAX 255 /* # chars in a file name */ 134/* Believe it or not, but mount.h has this one */
143 135#undef BLOCK_SIZE
144#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) 136enum {
145 137 BLOCK_SIZE = 1024,
146#define MINIX_VALID_FS 0x0001 /* Clean fs. */ 138 BITS_PER_BLOCK = BLOCK_SIZE << 3,
147#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ 139
148 140 MINIX_ROOT_INO = 1,
149#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ 141 MINIX_BAD_INO = 2,
150#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ 142 MAX_GOOD_BLOCKS = 512,
151 143
152#ifndef BLKGETSIZE 144 MINIX1_SUPER_MAGIC = 0x137F, /* original minix fs */
153#define BLKGETSIZE _IO(0x12,96) /* return device size */ 145 MINIX1_SUPER_MAGIC2 = 0x138F, /* minix fs, 30 char names */
154#endif 146 MINIX2_SUPER_MAGIC = 0x2468, /* minix V2 fs */
155 147 MINIX2_SUPER_MAGIC2 = 0x2478, /* minix V2 fs, 30 char names */
156 148 MINIX_VALID_FS = 0x0001, /* clean fs */
157#ifndef __linux__ 149 MINIX_ERROR_FS = 0x0002, /* fs has errors */
158#define volatile 150
159#endif 151 INODE_SIZE1 = sizeof(struct minix1_inode),
160 152 INODE_SIZE2 = sizeof(struct minix2_inode),
161#define MINIX_ROOT_INO 1 153 MINIX1_INODES_PER_BLOCK = BLOCK_SIZE / sizeof(struct minix1_inode),
162#define MINIX_BAD_INO 2 154 MINIX2_INODES_PER_BLOCK = BLOCK_SIZE / sizeof(struct minix2_inode),
163 155
164#define TEST_BUFFER_BLOCKS 16 156 TEST_BUFFER_BLOCKS = 16,
165#define MAX_GOOD_BLOCKS 512 157};
166
167#define UPPER(size,n) (((size)+((n)-1))/(n))
168#define INODE_SIZE (sizeof(struct minix_inode))
169 158
170#if ENABLE_FEATURE_MINIX2 159#if ENABLE_FEATURE_MINIX2
171# define INODE_SIZE2 (sizeof(struct minix2_inode)) 160static int version2;
172# define INODE_BLOCKS UPPER(INODES, (version2 ? MINIX2_INODES_PER_BLOCK \
173 : MINIX_INODES_PER_BLOCK))
174#else 161#else
175# define INODE_BLOCKS UPPER(INODES, (MINIX_INODES_PER_BLOCK)) 162enum { version2 = 0 };
176#endif 163#endif
177 164
178#define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE)
179
180#define BITS_PER_BLOCK (BLOCK_SIZE<<3)
181
182static char *device_name; 165static char *device_name;
183static int DEV = -1; 166static int dev_fd = -1;
184static uint32_t BLOCKS; 167static uint32_t total_blocks;
185static int badblocks; 168static int badblocks;
186/* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */ 169/* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */
187static int namelen = 30; 170static int namelen = 30;
188static int dirsize = 32; 171static int dirsize = 32;
189static int magic = MINIX_SUPER_MAGIC2; 172static int magic = MINIX1_SUPER_MAGIC2;
190#if ENABLE_FEATURE_MINIX2
191static int version2;
192#else
193enum { version2 = 0 };
194#endif
195 173
196static char root_block[BLOCK_SIZE]; 174static char root_block[BLOCK_SIZE];
197
198static char *inode_buffer;
199
200#define Inode (((struct minix_inode *) inode_buffer)-1)
201#if ENABLE_FEATURE_MINIX2
202#define Inode2 (((struct minix2_inode *) inode_buffer)-1)
203#endif
204static char super_block_buffer[BLOCK_SIZE]; 175static char super_block_buffer[BLOCK_SIZE];
205static char boot_block_buffer[512]; 176static char boot_block_buffer[512];
206 177static char *inode_buffer;
207#define Super (*(struct minix_super_block *)super_block_buffer)
208
209#define INODES (Super.s_ninodes)
210#if ENABLE_FEATURE_MINIX2
211# define ZONES (version2 ? Super.s_zones : Super.s_nzones)
212#else
213# define ZONES (Super.s_nzones)
214#endif
215
216#define IMAPS (Super.s_imap_blocks)
217#define ZMAPS (Super.s_zmap_blocks)
218#define FIRSTZONE (Super.s_firstdatazone)
219#define ZONESIZE (Super.s_log_zone_size)
220#define MAXSIZE (Super.s_max_size)
221#define MAGIC (Super.s_magic)
222#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)
223 178
224static char *inode_map; 179static char *inode_map;
225static char *zone_map; 180static char *zone_map;
226 181
227static unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
228static int used_good_blocks; 182static int used_good_blocks;
183static unsigned short good_blocks_table[MAX_GOOD_BLOCKS];
229static unsigned long req_nr_inodes; 184static unsigned long req_nr_inodes;
230 185
231static int bit(char* a, unsigned i) 186extern inline unsigned div_roundup(unsigned size, unsigned n)
187{
188 return (size + n-1) / n;
189}
190
191#define INODE_BUF1 (((struct minix1_inode*)inode_buffer) - 1)
192#define INODE_BUF2 (((struct minix2_inode*)inode_buffer) - 1)
193
194#define SB (*(struct minix_super_block*)super_block_buffer)
195
196#define SB_INODES (SB.s_ninodes)
197#define SB_IMAPS (SB.s_imap_blocks)
198#define SB_ZMAPS (SB.s_zmap_blocks)
199#define SB_FIRSTZONE (SB.s_firstdatazone)
200#define SB_ZONE_SIZE (SB.s_log_zone_size)
201#define SB_MAXSIZE (SB.s_max_size)
202#define SB_MAGIC (SB.s_magic)
203
204#if !ENABLE_FEATURE_MINIX2
205# define SB_ZONES (SB.s_nzones)
206# define INODE_BLOCKS div_roundup(SB_INODES, MINIX1_INODES_PER_BLOCK)
207#else
208# define SB_ZONES (version2 ? SB.s_zones : SB.s_nzones)
209# define INODE_BLOCKS div_roundup(SB_INODES, \
210 version2 ? MINIX2_INODES_PER_BLOCK : MINIX1_INODES_PER_BLOCK)
211#endif
212
213#define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE)
214#define NORM_FIRSTZONE (2 + SB_IMAPS + SB_ZMAPS + INODE_BLOCKS)
215
216static int bit(const char* a, unsigned i)
232{ 217{
233 return (a[i >> 3] & (1<<(i & 7))) != 0; 218 return a[i >> 3] & (1<<(i & 7));
234} 219}
235#define inode_in_use(x) (bit(inode_map,(x)))
236#define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1))
237 220
238#define mark_inode(x) (setbit(inode_map,(x))) 221/* Note: do not assume 0/1, it is 0/nonzero */
239#define unmark_inode(x) (clrbit(inode_map,(x))) 222#define inode_in_use(x) bit(inode_map,(x))
223#define zone_in_use(x) bit(zone_map,(x)-SB_FIRSTZONE+1)
224
225#define mark_inode(x) setbit(inode_map,(x))
226#define unmark_inode(x) clrbit(inode_map,(x))
227#define mark_zone(x) setbit(zone_map,(x)-SB_FIRSTZONE+1)
228#define unmark_zone(x) clrbit(zone_map,(x)-SB_FIRSTZONE+1)
229
230#ifndef BLKGETSIZE
231# define BLKGETSIZE _IO(0x12,96) /* return device size */
232#endif
240 233
241#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1))
242#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1))
243 234
244static long valid_offset(int fd, int offset) 235static long valid_offset(int fd, int offset)
245{ 236{
@@ -291,37 +282,37 @@ static int get_size(const char *file)
291static void write_tables(void) 282static void write_tables(void)
292{ 283{
293 /* Mark the super block valid. */ 284 /* Mark the super block valid. */
294 Super.s_state |= MINIX_VALID_FS; 285 SB.s_state |= MINIX_VALID_FS;
295 Super.s_state &= ~MINIX_ERROR_FS; 286 SB.s_state &= ~MINIX_ERROR_FS;
296 287
297 msg_eol = "seek to 0 failed"; 288 msg_eol = "seek to 0 failed";
298 xlseek(DEV, 0, SEEK_SET); 289 xlseek(dev_fd, 0, SEEK_SET);
299 290
300 msg_eol = "cannot clear boot sector"; 291 msg_eol = "cannot clear boot sector";
301 xwrite(DEV, boot_block_buffer, 512); 292 xwrite(dev_fd, boot_block_buffer, 512);
302 293
303 msg_eol = "seek to BLOCK_SIZE failed"; 294 msg_eol = "seek to BLOCK_SIZE failed";
304 xlseek(DEV, BLOCK_SIZE, SEEK_SET); 295 xlseek(dev_fd, BLOCK_SIZE, SEEK_SET);
305 296
306 msg_eol = "cannot write superblock"; 297 msg_eol = "cannot write superblock";
307 xwrite(DEV, super_block_buffer, BLOCK_SIZE); 298 xwrite(dev_fd, super_block_buffer, BLOCK_SIZE);
308 299
309 msg_eol = "cannot write inode map"; 300 msg_eol = "cannot write inode map";
310 xwrite(DEV, inode_map, IMAPS * BLOCK_SIZE); 301 xwrite(dev_fd, inode_map, SB_IMAPS * BLOCK_SIZE);
311 302
312 msg_eol = "cannot write zone map"; 303 msg_eol = "cannot write zone map";
313 xwrite(DEV, zone_map, ZMAPS * BLOCK_SIZE); 304 xwrite(dev_fd, zone_map, SB_ZMAPS * BLOCK_SIZE);
314 305
315 msg_eol = "cannot write inodes"; 306 msg_eol = "cannot write inodes";
316 xwrite(DEV, inode_buffer, INODE_BUFFER_SIZE); 307 xwrite(dev_fd, inode_buffer, INODE_BUFFER_SIZE);
317 308
318 msg_eol = "\n"; 309 msg_eol = "\n";
319} 310}
320 311
321static void write_block(int blk, char *buffer) 312static void write_block(int blk, char *buffer)
322{ 313{
323 xlseek(DEV, blk * BLOCK_SIZE, SEEK_SET); 314 xlseek(dev_fd, blk * BLOCK_SIZE, SEEK_SET);
324 xwrite(DEV, buffer, BLOCK_SIZE); 315 xwrite(dev_fd, buffer, BLOCK_SIZE);
325} 316}
326 317
327static int get_free_block(void) 318static int get_free_block(void)
@@ -333,10 +324,10 @@ static int get_free_block(void)
333 if (used_good_blocks) 324 if (used_good_blocks)
334 blk = good_blocks_table[used_good_blocks - 1] + 1; 325 blk = good_blocks_table[used_good_blocks - 1] + 1;
335 else 326 else
336 blk = FIRSTZONE; 327 blk = SB_FIRSTZONE;
337 while (blk < ZONES && zone_in_use(blk)) 328 while (blk < SB_ZONES && zone_in_use(blk))
338 blk++; 329 blk++;
339 if (blk >= ZONES) 330 if (blk >= SB_ZONES)
340 bb_error_msg_and_die("not enough good blocks"); 331 bb_error_msg_and_die("not enough good blocks");
341 good_blocks_table[used_good_blocks] = blk; 332 good_blocks_table[used_good_blocks] = blk;
342 used_good_blocks++; 333 used_good_blocks++;
@@ -354,8 +345,8 @@ static void mark_good_blocks(void)
354static int next(int zone) 345static int next(int zone)
355{ 346{
356 if (!zone) 347 if (!zone)
357 zone = FIRSTZONE - 1; 348 zone = SB_FIRSTZONE - 1;
358 while (++zone < ZONES) 349 while (++zone < SB_ZONES)
359 if (zone_in_use(zone)) 350 if (zone_in_use(zone))
360 return zone; 351 return zone;
361 return 0; 352 return 0;
@@ -363,7 +354,7 @@ static int next(int zone)
363 354
364static void make_bad_inode(void) 355static void make_bad_inode(void)
365{ 356{
366 struct minix_inode *inode = &Inode[MINIX_BAD_INO]; 357 struct minix1_inode *inode = &INODE_BUF1[MINIX_BAD_INO];
367 int i, j, zone; 358 int i, j, zone;
368 int ind = 0, dind = 0; 359 int ind = 0, dind = 0;
369 unsigned short ind_block[BLOCK_SIZE >> 1]; 360 unsigned short ind_block[BLOCK_SIZE >> 1];
@@ -377,7 +368,7 @@ static void make_bad_inode(void)
377 inode->i_nlinks = 1; 368 inode->i_nlinks = 1;
378 /* BTW, setting this makes all images different */ 369 /* BTW, setting this makes all images different */
379 /* it's harder to check for bugs then - diff isn't helpful :(... */ 370 /* it's harder to check for bugs then - diff isn't helpful :(... */
380 inode->i_time = time(NULL); 371 inode->i_time = CUR_TIME;
381 inode->i_mode = S_IFREG + 0000; 372 inode->i_mode = S_IFREG + 0000;
382 inode->i_size = badblocks * BLOCK_SIZE; 373 inode->i_size = badblocks * BLOCK_SIZE;
383 zone = next(0); 374 zone = next(0);
@@ -406,7 +397,7 @@ static void make_bad_inode(void)
406 } 397 }
407 } 398 }
408 bb_error_msg_and_die("too many bad blocks"); 399 bb_error_msg_and_die("too many bad blocks");
409 end_bad: 400 end_bad:
410 if (ind) 401 if (ind)
411 write_block(ind, (char *) ind_block); 402 write_block(ind, (char *) ind_block);
412 if (dind) 403 if (dind)
@@ -416,7 +407,7 @@ static void make_bad_inode(void)
416#if ENABLE_FEATURE_MINIX2 407#if ENABLE_FEATURE_MINIX2
417static void make_bad_inode2(void) 408static void make_bad_inode2(void)
418{ 409{
419 struct minix2_inode *inode = &Inode2[MINIX_BAD_INO]; 410 struct minix2_inode *inode = &INODE_BUF2[MINIX_BAD_INO];
420 int i, j, zone; 411 int i, j, zone;
421 int ind = 0, dind = 0; 412 int ind = 0, dind = 0;
422 unsigned long ind_block[BLOCK_SIZE >> 2]; 413 unsigned long ind_block[BLOCK_SIZE >> 2];
@@ -426,7 +417,7 @@ static void make_bad_inode2(void)
426 return; 417 return;
427 mark_inode(MINIX_BAD_INO); 418 mark_inode(MINIX_BAD_INO);
428 inode->i_nlinks = 1; 419 inode->i_nlinks = 1;
429 inode->i_atime = inode->i_mtime = inode->i_ctime = time(NULL); 420 inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME;
430 inode->i_mode = S_IFREG + 0000; 421 inode->i_mode = S_IFREG + 0000;
431 inode->i_size = badblocks * BLOCK_SIZE; 422 inode->i_size = badblocks * BLOCK_SIZE;
432 zone = next(0); 423 zone = next(0);
@@ -456,7 +447,7 @@ static void make_bad_inode2(void)
456 } 447 }
457 /* Could make triple indirect block here */ 448 /* Could make triple indirect block here */
458 bb_error_msg_and_die("too many bad blocks"); 449 bb_error_msg_and_die("too many bad blocks");
459 end_bad: 450 end_bad:
460 if (ind) 451 if (ind)
461 write_block(ind, (char *) ind_block); 452 write_block(ind, (char *) ind_block);
462 if (dind) 453 if (dind)
@@ -466,12 +457,12 @@ static void make_bad_inode2(void)
466 457
467static void make_root_inode(void) 458static void make_root_inode(void)
468{ 459{
469 struct minix_inode *inode = &Inode[MINIX_ROOT_INO]; 460 struct minix1_inode *inode = &INODE_BUF1[MINIX_ROOT_INO];
470 461
471 mark_inode(MINIX_ROOT_INO); 462 mark_inode(MINIX_ROOT_INO);
472 inode->i_zone[0] = get_free_block(); 463 inode->i_zone[0] = get_free_block();
473 inode->i_nlinks = 2; 464 inode->i_nlinks = 2;
474 inode->i_time = time(NULL); 465 inode->i_time = CUR_TIME;
475 if (badblocks) 466 if (badblocks)
476 inode->i_size = 3 * dirsize; 467 inode->i_size = 3 * dirsize;
477 else { 468 else {
@@ -480,21 +471,21 @@ static void make_root_inode(void)
480 inode->i_size = 2 * dirsize; 471 inode->i_size = 2 * dirsize;
481 } 472 }
482 inode->i_mode = S_IFDIR + 0755; 473 inode->i_mode = S_IFDIR + 0755;
483 inode->i_uid = getuid(); 474 inode->i_uid = GETUID;
484 if (inode->i_uid) 475 if (inode->i_uid)
485 inode->i_gid = getgid(); 476 inode->i_gid = GETGID;
486 write_block(inode->i_zone[0], root_block); 477 write_block(inode->i_zone[0], root_block);
487} 478}
488 479
489#if ENABLE_FEATURE_MINIX2 480#if ENABLE_FEATURE_MINIX2
490static void make_root_inode2(void) 481static void make_root_inode2(void)
491{ 482{
492 struct minix2_inode *inode = &Inode2[MINIX_ROOT_INO]; 483 struct minix2_inode *inode = &INODE_BUF2[MINIX_ROOT_INO];
493 484
494 mark_inode(MINIX_ROOT_INO); 485 mark_inode(MINIX_ROOT_INO);
495 inode->i_zone[0] = get_free_block(); 486 inode->i_zone[0] = get_free_block();
496 inode->i_nlinks = 2; 487 inode->i_nlinks = 2;
497 inode->i_atime = inode->i_mtime = inode->i_ctime = time(NULL); 488 inode->i_atime = inode->i_mtime = inode->i_ctime = CUR_TIME;
498 if (badblocks) 489 if (badblocks)
499 inode->i_size = 3 * dirsize; 490 inode->i_size = 3 * dirsize;
500 else { 491 else {
@@ -503,9 +494,9 @@ static void make_root_inode2(void)
503 inode->i_size = 2 * dirsize; 494 inode->i_size = 2 * dirsize;
504 } 495 }
505 inode->i_mode = S_IFDIR + 0755; 496 inode->i_mode = S_IFDIR + 0755;
506 inode->i_uid = getuid(); 497 inode->i_uid = GETUID;
507 if (inode->i_uid) 498 if (inode->i_uid)
508 inode->i_gid = getgid(); 499 inode->i_gid = GETGID;
509 write_block(inode->i_zone[0], root_block); 500 write_block(inode->i_zone[0], root_block);
510} 501}
511#endif 502#endif
@@ -517,65 +508,64 @@ static void setup_tables(void)
517 508
518 memset(super_block_buffer, 0, BLOCK_SIZE); 509 memset(super_block_buffer, 0, BLOCK_SIZE);
519 memset(boot_block_buffer, 0, 512); 510 memset(boot_block_buffer, 0, 512);
520 MAGIC = magic; 511 SB_MAGIC = magic;
521 ZONESIZE = 0; 512 SB_ZONE_SIZE = 0;
522 MAXSIZE = version2 ? 0x7fffffff : (7 + 512 + 512 * 512) * 1024; 513 SB_MAXSIZE = version2 ? 0x7fffffff : (7 + 512 + 512 * 512) * 1024;
523 if (version2) { 514 if (version2)
524 Super.s_zones = BLOCKS; 515 SB.s_zones = total_blocks;
525 } else 516 else
526 Super.s_nzones = BLOCKS; 517 SB.s_nzones = total_blocks;
527 518
528/* some magic nrs: 1 inode / 3 blocks */ 519 /* some magic nrs: 1 inode / 3 blocks */
529 if (req_nr_inodes == 0) 520 if (req_nr_inodes == 0)
530 inodes = BLOCKS / 3; 521 inodes = total_blocks / 3;
531 else 522 else
532 inodes = req_nr_inodes; 523 inodes = req_nr_inodes;
533 /* Round up inode count to fill block size */ 524 /* Round up inode count to fill block size */
534 if (version2) 525 if (version2)
535 inodes = ((inodes + MINIX2_INODES_PER_BLOCK - 1) & 526 inodes = (inodes + MINIX2_INODES_PER_BLOCK - 1) &
536 ~(MINIX2_INODES_PER_BLOCK - 1)); 527 ~(MINIX2_INODES_PER_BLOCK - 1);
537 else 528 else
538 inodes = ((inodes + MINIX_INODES_PER_BLOCK - 1) & 529 inodes = (inodes + MINIX1_INODES_PER_BLOCK - 1) &
539 ~(MINIX_INODES_PER_BLOCK - 1)); 530 ~(MINIX1_INODES_PER_BLOCK - 1);
540 if (inodes > 65535) 531 if (inodes > 65535)
541 inodes = 65535; 532 inodes = 65535;
542 INODES = inodes; 533 SB_INODES = inodes;
543 IMAPS = UPPER(INODES + 1, BITS_PER_BLOCK); 534 SB_IMAPS = div_roundup(SB_INODES + 1, BITS_PER_BLOCK);
544 ZMAPS = 0; 535
545 i = 0;
546 while (ZMAPS !=
547 UPPER(BLOCKS - (2 + IMAPS + ZMAPS + INODE_BLOCKS) + 1,
548 BITS_PER_BLOCK) && i < 1000) {
549 ZMAPS =
550 UPPER(BLOCKS - (2 + IMAPS + ZMAPS + INODE_BLOCKS) + 1,
551 BITS_PER_BLOCK);
552 i++;
553 }
554 /* Real bad hack but overwise mkfs.minix can be thrown 536 /* Real bad hack but overwise mkfs.minix can be thrown
555 * in infinite loop... 537 * in infinite loop...
556 * try: 538 * try:
557 * dd if=/dev/zero of=test.fs count=10 bs=1024 539 * dd if=/dev/zero of=test.fs count=10 bs=1024
558 * /sbin/mkfs.minix -i 200 test.fs 540 * mkfs.minix -i 200 test.fs
559 * */ 541 */
560 if (i >= 999) { 542 /* This code is not insane: NORM_FIRSTZONE is not a constant, */
561 bb_error_msg_and_die("cannot allocate buffers for maps"); 543 /* it uses previous value of SB_ZMAPS inside */
562 } 544 i = 999;
563 FIRSTZONE = NORM_FIRSTZONE; 545 SB_ZMAPS = 0;
564 inode_map = xmalloc(IMAPS * BLOCK_SIZE); 546 do {
565 zone_map = xmalloc(ZMAPS * BLOCK_SIZE); 547 uint16_t t = div_roundup(total_blocks - NORM_FIRSTZONE + 1, BITS_PER_BLOCK);
566 memset(inode_map, 0xff, IMAPS * BLOCK_SIZE); 548 if (SB_ZMAPS == t) goto got_it;
567 memset(zone_map, 0xff, ZMAPS * BLOCK_SIZE); 549 SB_ZMAPS = t;
568 for (i = FIRSTZONE; i < ZONES; i++) 550 } while (--i);
551 bb_error_msg_and_die("incompatible size/inode count, try different -i N");
552 got_it:
553
554 SB_FIRSTZONE = NORM_FIRSTZONE;
555 inode_map = xmalloc(SB_IMAPS * BLOCK_SIZE);
556 zone_map = xmalloc(SB_ZMAPS * BLOCK_SIZE);
557 memset(inode_map, 0xff, SB_IMAPS * BLOCK_SIZE);
558 memset(zone_map, 0xff, SB_ZMAPS * BLOCK_SIZE);
559 for (i = SB_FIRSTZONE; i < SB_ZONES; i++)
569 unmark_zone(i); 560 unmark_zone(i);
570 for (i = MINIX_ROOT_INO; i <= INODES; i++) 561 for (i = MINIX_ROOT_INO; i <= SB_INODES; i++)
571 unmark_inode(i); 562 unmark_inode(i);
572 inode_buffer = xmalloc(INODE_BUFFER_SIZE); 563 inode_buffer = xzalloc(INODE_BUFFER_SIZE);
573 memset(inode_buffer, 0, INODE_BUFFER_SIZE); 564 printf("%ld inodes\n", (long)SB_INODES);
574 printf("%ld inodes\n", (long)INODES); 565 printf("%ld blocks\n", (long)SB_ZONES);
575 printf("%ld blocks\n", (long)ZONES); 566 printf("Firstdatazone=%ld (%ld)\n", (long)SB_FIRSTZONE, (long)NORM_FIRSTZONE);
576 printf("Firstdatazone=%ld (%ld)\n", (long)FIRSTZONE, (long)NORM_FIRSTZONE); 567 printf("Zonesize=%d\n", BLOCK_SIZE << SB_ZONE_SIZE);
577 printf("Zonesize=%d\n", BLOCK_SIZE << ZONESIZE); 568 printf("Maxsize=%ld\n", (long)SB_MAXSIZE);
578 printf("Maxsize=%ld\n\n", (long)MAXSIZE);
579} 569}
580 570
581/* 571/*
@@ -588,11 +578,11 @@ static long do_check(char *buffer, int try, unsigned current_block)
588 578
589 /* Seek to the correct loc. */ 579 /* Seek to the correct loc. */
590 msg_eol = "seek failed during testing of blocks"; 580 msg_eol = "seek failed during testing of blocks";
591 xlseek(DEV, current_block * BLOCK_SIZE, SEEK_SET); 581 xlseek(dev_fd, current_block * BLOCK_SIZE, SEEK_SET);
592 msg_eol = "\n"; 582 msg_eol = "\n";
593 583
594 /* Try the read */ 584 /* Try the read */
595 got = read(DEV, buffer, try * BLOCK_SIZE); 585 got = read(dev_fd, buffer, try * BLOCK_SIZE);
596 if (got < 0) 586 if (got < 0)
597 got = 0; 587 got = 0;
598 if (got & (BLOCK_SIZE - 1)) { 588 if (got & (BLOCK_SIZE - 1)) {
@@ -606,7 +596,7 @@ static unsigned currently_testing;
606 596
607static void alarm_intr(int alnum) 597static void alarm_intr(int alnum)
608{ 598{
609 if (currently_testing >= ZONES) 599 if (currently_testing >= SB_ZONES)
610 return; 600 return;
611 signal(SIGALRM, alarm_intr); 601 signal(SIGALRM, alarm_intr);
612 alarm(5); 602 alarm(5);
@@ -624,18 +614,18 @@ static void check_blocks(void)
624 currently_testing = 0; 614 currently_testing = 0;
625 signal(SIGALRM, alarm_intr); 615 signal(SIGALRM, alarm_intr);
626 alarm(5); 616 alarm(5);
627 while (currently_testing < ZONES) { 617 while (currently_testing < SB_ZONES) {
628 msg_eol = "seek failed in check_blocks"; 618 msg_eol = "seek failed in check_blocks";
629 xlseek(DEV, currently_testing * BLOCK_SIZE, SEEK_SET); 619 xlseek(dev_fd, currently_testing * BLOCK_SIZE, SEEK_SET);
630 msg_eol = "\n"; 620 msg_eol = "\n";
631 try = TEST_BUFFER_BLOCKS; 621 try = TEST_BUFFER_BLOCKS;
632 if (currently_testing + try > ZONES) 622 if (currently_testing + try > SB_ZONES)
633 try = ZONES - currently_testing; 623 try = SB_ZONES - currently_testing;
634 got = do_check(buffer, try, currently_testing); 624 got = do_check(buffer, try, currently_testing);
635 currently_testing += got; 625 currently_testing += got;
636 if (got == try) 626 if (got == try)
637 continue; 627 continue;
638 if (currently_testing < FIRSTZONE) 628 if (currently_testing < SB_FIRSTZONE)
639 bb_error_msg_and_die("bad blocks before data-area: cannot make fs"); 629 bb_error_msg_and_die("bad blocks before data-area: cannot make fs");
640 mark_zone(currently_testing); 630 mark_zone(currently_testing);
641 badblocks++; 631 badblocks++;
@@ -660,13 +650,14 @@ static void get_list_blocks(char *filename)
660 650
661int mkfs_minix_main(int argc, char **argv) 651int mkfs_minix_main(int argc, char **argv)
662{ 652{
653 struct mntent *mp;
663 unsigned opt; 654 unsigned opt;
664 char *tmp; 655 char *tmp;
665 struct stat statbuf; 656 struct stat statbuf;
666 char *str_i, *str_n; 657 char *str_i, *str_n;
667 char *listfile = NULL; 658 char *listfile = NULL;
668 659
669 if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE) 660 if (INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE)
670 bb_error_msg_and_die("bad inode size"); 661 bb_error_msg_and_die("bad inode size");
671#if ENABLE_FEATURE_MINIX2 662#if ENABLE_FEATURE_MINIX2
672 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) 663 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
@@ -680,8 +671,8 @@ int mkfs_minix_main(int argc, char **argv)
680 //if (opt & 4) -l 671 //if (opt & 4) -l
681 if (opt & 8) { // -n 672 if (opt & 8) { // -n
682 namelen = xatoi_u(str_n); 673 namelen = xatoi_u(str_n);
683 if (namelen == 14) magic = MINIX_SUPER_MAGIC; 674 if (namelen == 14) magic = MINIX1_SUPER_MAGIC;
684 else if (namelen == 30) magic = MINIX_SUPER_MAGIC2; 675 else if (namelen == 30) magic = MINIX1_SUPER_MAGIC2;
685 else bb_show_usage(); 676 else bb_show_usage();
686 dirsize = namelen + 2; 677 dirsize = namelen + 2;
687 } 678 }
@@ -697,23 +688,42 @@ int mkfs_minix_main(int argc, char **argv)
697 device_name = *argv++; 688 device_name = *argv++;
698 if (!device_name) 689 if (!device_name)
699 bb_show_usage(); 690 bb_show_usage();
700 if (*argv) { 691 if (*argv)
701 BLOCKS = xatou32(*argv); 692 total_blocks = xatou32(*argv);
702 if (BLOCKS < 10) 693 else
703 bb_show_usage(); 694 total_blocks = get_size(device_name) / 1024;
704 } else 695
705 BLOCKS = get_size(device_name) / 1024; 696 if (total_blocks < 10)
697 bb_error_msg_and_die("must have at least 10 blocks");
706 698
707 if (version2) { 699 if (version2) {
708 magic = MINIX2_SUPER_MAGIC2; 700 magic = MINIX2_SUPER_MAGIC2;
709 if (namelen == 14) 701 if (namelen == 14)
710 magic = MINIX2_SUPER_MAGIC; 702 magic = MINIX2_SUPER_MAGIC;
711 } else if (BLOCKS > 65535) 703 } else if (total_blocks > 65535)
712 BLOCKS = 65535; 704 total_blocks = 65535;
705
706 /* Check if it is mounted */
707 mp = find_mount_point(device_name, NULL);
708 if (mp && strcmp(device_name, mp->mnt_fsname) == 0)
709 bb_error_msg_and_die("%s is mounted on %s; "
710 "refusing to make a filesystem",
711 device_name, mp->mnt_dir);
712
713 dev_fd = xopen(device_name, O_RDWR);
714 if (fstat(dev_fd, &statbuf) < 0)
715 bb_error_msg_and_die("cannot stat %s", device_name);
716 if (!S_ISBLK(statbuf.st_mode))
717 opt &= ~1; // clear -c (check)
713 718
714 if (find_mount_point(device_name, NULL)) 719/* I don't know why someone has special code to prevent mkfs.minix
715 bb_error_msg_and_die("%s is mounted; refusing to make " 720 * on IDE devices. Why IDE but not SCSI, etc?... */
716 "a filesystem", device_name); 721#if 0
722 else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
723 /* what is this? */
724 bb_error_msg_and_die("will not try "
725 "to make filesystem on '%s'", device_name);
726#endif
717 727
718 tmp = root_block; 728 tmp = root_block;
719 *(short *) tmp = 1; 729 *(short *) tmp = 1;
@@ -725,14 +735,6 @@ int mkfs_minix_main(int argc, char **argv)
725 *(short *) tmp = 2; 735 *(short *) tmp = 2;
726 strcpy(tmp + 2, ".badblocks"); 736 strcpy(tmp + 2, ".badblocks");
727 737
728 DEV = xopen(device_name, O_RDWR);
729 if (fstat(DEV, &statbuf) < 0)
730 bb_error_msg_and_die("cannot stat %s", device_name);
731 if (!S_ISBLK(statbuf.st_mode))
732 opt &= ~1; // clear -c (check)
733 else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
734 bb_error_msg_and_die("will not try to make filesystem on '%s'", device_name);
735
736 setup_tables(); 738 setup_tables();
737 739
738 if (opt & 1) // -c ? 740 if (opt & 1) // -c ?