Ground work for larger file systems, and miscellaneous fixes:

- MFS and mkfs(1) now perform extra sanity checks
- fsck(1) can now deal with inode tables extending beyond the file
  system's first 4GB
- badblocks(8) no longer writes out the superblock for no reason
- mkfs(1) no longer crashes when given no parameters
- more(1) no longer crashes when standard output is redirected
This commit is contained in:
David van Moolenbroek 2009-10-26 13:35:39 +00:00
parent 5920582bde
commit bd30f2a988
5 changed files with 28 additions and 65 deletions

View file

@ -40,9 +40,7 @@
#include "../../servers/mfs/super.h"
_PROTOTYPE(int main, (int argc, char **argv));
_PROTOTYPE(void rw_super, (int flag));
_PROTOTYPE(void get_super, (void));
_PROTOTYPE(void put_super, (void));
_PROTOTYPE(void rw_inode, (struct stat * stat_ptr, int rw_mode));
_PROTOTYPE(void get_inode, (struct stat * stat_ptr));
_PROTOTYPE(void put_inode, (struct stat * stat_ptr));
@ -99,20 +97,6 @@ _PROTOTYPE(void done, (int nr));
#define V_SMALLER V1_NR_DZONES
#endif
#if 0
struct super_block {
ino_t s_ninodes; /* # usable inodes on the minor device */
zone1_t s_nzones; /* total device size, including bit maps etc */
short s_imap_blocks; /* # of blocks used by inode bit map */
short s_zmap_blocks; /* # of blocks used by zone bit map */
zone1_t s_firstdatazone; /* number of first data zone */
short s_log_zone_size; /* log2 of blocks/zone */
off_t s_max_size; /* maximum file size on this device */
short s_magic; /* magic number to recognize super-blocks */
short s_pad; /* try to avoid compiler-dependent padding */
zone_t s_zones; /* number of zones (replaces s_nzones in V2) */
} super_block;
#endif
/* ====== globals ======= */
@ -142,30 +126,19 @@ d2_inode *ip2;
/* ====== super block routines ======= */
void rw_super(flag)
int flag;
{ /* read or write a superblock */
int rwd;
lseek(fd, 0L, SEEK_SET); /* rewind */
lseek(fd, (long) BLOCK_SIZE, SEEK_SET); /* seek */
if (flag == READ)
rwd = read(fd, (char *) sp, SUPER_SIZE);
else
rwd = write(fd, (char *) sp, SUPER_SIZE);
if (rwd != SUPER_SIZE) { /* ok ? */
printf("Bad %s in get_super() (should be %u is %d)\n",
flag == READ ? "read" : "write",
(unsigned) SUPER_SIZE, rwd);
done(DIR_CREATED);
}
}
void get_super()
/* Get super_block. global pointer sp is used */
{
rw_super(READ);
int rd;
lseek(fd, (long) BLOCK_SIZE, SEEK_SET); /* seek */
rd = read(fd, (char *) sp, SUPER_SIZE);
if (rd != SUPER_SIZE) { /* ok ? */
printf("Bad read in get_super() (should be %u is %d)\n",
(unsigned) SUPER_SIZE, rd);
done(DIR_CREATED);
}
if (sp->s_magic == SUPER_MAGIC) {
/* This is a V1 file system. */
@ -184,11 +157,6 @@ void get_super()
}
void put_super()
{
rw_super(WRITE);
}
/* ========== inode routines =========== */
void rw_inode(stat_ptr, rw_mode)
@ -209,7 +177,6 @@ int rw_mode;
offset = (block_t) ((i_num - 1) % inodes_per_block);
offset *= (block_t) (inode_size); /* and this offset */
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
lseek(fd, (off_t) (blk + offset), SEEK_SET); /* seek */
/* Pointer is at the inode */
@ -449,7 +416,6 @@ int nr_blocks;
}
put_inode(&stat_buf); /* save the inode on disk */
put_super(); /* bit_maps too */
}
@ -520,7 +486,6 @@ block_t num;
blk_offset += (block_t) (words * SIZE_OF_INT); /* offset */
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
lseek(fd, (off_t) blk_offset, SEEK_SET); /* set pointer at word */
rd = read(fd, (char *) &tst_word, SIZE_OF_INT);
@ -560,7 +525,6 @@ zone_t num;
blk_offset += (long) (words * SIZE_OF_INT);
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
lseek(fd, (off_t) blk_offset, SEEK_SET);
rwd = read(fd, (char *) &tst_word, SIZE_OF_INT);
@ -570,7 +534,6 @@ zone_t num;
}
bit = offset % INT_BITS;
if (((tst_word >> bit) & 01) == 0) { /* free */
lseek(fd, 0L, SEEK_SET);/* rewind */
lseek(fd, (off_t) blk_offset, SEEK_SET);
tst_word |= (1 << bit); /* not free anymore */
rwd = write(fd, (char *) &tst_word, SIZE_OF_INT);

View file

@ -116,9 +116,7 @@ static struct super_block sb;
#define ZONE_SIZE ((int) ztob(block_size))
#define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1)
/* Byte address of a zone/of an inode */
#define cinoblock(i) (((i - 1)*INODE_SIZE) / block_size + BLK_ILIST)
#define cinooff(i) (((i - 1)*INODE_SIZE) % block_size)
/* Byte address of a zone */
#define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE))
#define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_SIZE))
@ -629,16 +627,12 @@ void chksuper()
int inoblock(int inn)
{
int a;
a = cinoblock(inn);
return a;
return div64u(mul64u(inn - 1, INODE_SIZE), block_size) + BLK_ILIST;
}
int inooff(int inn)
{
int a;
a = cinooff(inn);
return a;
return rem64u(mul64u(inn - 1, INODE_SIZE), block_size);
}
/* Make a listing of the inodes given by `clist'. If `repair' is set, ask

View file

@ -2,10 +2,12 @@
/* Authors: Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans
*
* This program can make both version 1 and version 2 file systems, as follows:
* mkfs /dev/fd0 1200 # Version 2 (default)
* This program can make version 1, 2 and 3 file systems, as follows:
* mkfs /dev/fd0 1200 # Version 3 (default)
* mkfs -1 /dev/fd0 360 # Version 1
*
* Note that the version 1 and 2 file systems produced by this program are not
* compatible with the original version 1 and 2 file system layout.
*/
#include <sys/types.h>
@ -185,6 +187,8 @@ char *argv[];
default: usage();
}
if (argc == optind) usage();
if(fs_version == 3) {
if(!block_size) block_size = _MAX_BLOCK_SIZE; /* V3 default block size */
if(block_size%SECTOR_SIZE || block_size < _MIN_BLOCK_SIZE) {
@ -428,8 +432,7 @@ ino_t inodes;
int inodeblks;
int initblks;
u32_t nb;
zone_t initzones, nrzones, v1sq, v2sq;
zone_t v1sq, v2sq;
zone_t zo;
struct super_block *sup;
char *buf, *cp;
@ -442,6 +445,7 @@ ino_t inodes;
sup->s_ninodes = inodes;
if (fs_version == 1) {
sup->s_nzones = zones;
if (sup->s_nzones != zones) pexit("too many zones");
} else {
sup->s_nzones = 0; /* not used in V2 - 0 forces errors early */
sup->s_zones = zones;
@ -461,9 +465,8 @@ ino_t inodes;
inode_offset = sup->s_imap_blocks + sup->s_zmap_blocks + 2;
inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block;
initblks = inode_offset + inodeblks;
initzones = (initblks + (1 << zone_shift) - 1) >> zone_shift;
nrzones = nrblocks >> zone_shift;
sup->s_firstdatazone = nb = (initblks + (1 << zone_shift) - 1) >> zone_shift;
if(nb >= zones) pexit("bit maps too large");
if(nb != sup->s_firstdatazone) {
fprintf(stderr, "mkfs: too much bitmap and inode data.\n" BIGGERBLOCKS);
exit(1);

View file

@ -37,6 +37,7 @@ int
main(argc,argv) register char ** argv; {
register char ** av;
char *empty_envp[] = { (char *) 0 };
if (! isatty(1)) {
no_tty = 1;
@ -58,7 +59,7 @@ main(argc,argv) register char ** argv; {
}
if (no_tty) {
*--av = "cat";
execve("/bin/cat", av, (char *) 0);
execve("/bin/cat", av, &empty_envp);
}
else processfiles(argc-(av-argv), av);
(VOID) quit();

View file

@ -311,10 +311,12 @@ register struct super_block *sp; /* pointer to a superblock */
/* Make a few basic checks to see if super block looks reasonable. */
if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
|| sp->s_ninodes < 1 || sp->s_zones < 1
|| sp->s_firstdatazone <= 4
|| sp->s_firstdatazone >= sp->s_zones
|| (unsigned) sp->s_log_zone_size > 4) {
printf("not enough imap or zone map blocks, \n");
printf("or not enough inodes, or not enough zones, "
"or zone size too large\n");
printf("or not enough inodes, or not enough zones, \n"
"or invalid first data zone, or zone size too large\n");
return(EINVAL);
}
sp->s_dev = dev; /* restore device number */