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:
parent
5920582bde
commit
bd30f2a988
|
@ -40,9 +40,7 @@
|
||||||
#include "../../servers/mfs/super.h"
|
#include "../../servers/mfs/super.h"
|
||||||
|
|
||||||
_PROTOTYPE(int main, (int argc, char **argv));
|
_PROTOTYPE(int main, (int argc, char **argv));
|
||||||
_PROTOTYPE(void rw_super, (int flag));
|
|
||||||
_PROTOTYPE(void get_super, (void));
|
_PROTOTYPE(void get_super, (void));
|
||||||
_PROTOTYPE(void put_super, (void));
|
|
||||||
_PROTOTYPE(void rw_inode, (struct stat * stat_ptr, int rw_mode));
|
_PROTOTYPE(void rw_inode, (struct stat * stat_ptr, int rw_mode));
|
||||||
_PROTOTYPE(void get_inode, (struct stat * stat_ptr));
|
_PROTOTYPE(void get_inode, (struct stat * stat_ptr));
|
||||||
_PROTOTYPE(void put_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
|
#define V_SMALLER V1_NR_DZONES
|
||||||
#endif
|
#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 ======= */
|
/* ====== globals ======= */
|
||||||
|
|
||||||
|
@ -142,30 +126,19 @@ d2_inode *ip2;
|
||||||
|
|
||||||
/* ====== super block routines ======= */
|
/* ====== 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()
|
void get_super()
|
||||||
/* Get super_block. global pointer sp is used */
|
/* 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) {
|
if (sp->s_magic == SUPER_MAGIC) {
|
||||||
/* This is a V1 file system. */
|
/* This is a V1 file system. */
|
||||||
|
@ -184,11 +157,6 @@ void get_super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void put_super()
|
|
||||||
{
|
|
||||||
rw_super(WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========== inode routines =========== */
|
/* ========== inode routines =========== */
|
||||||
|
|
||||||
void rw_inode(stat_ptr, rw_mode)
|
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) ((i_num - 1) % inodes_per_block);
|
||||||
offset *= (block_t) (inode_size); /* and this offset */
|
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 */
|
lseek(fd, (off_t) (blk + offset), SEEK_SET); /* seek */
|
||||||
|
|
||||||
/* Pointer is at the inode */
|
/* Pointer is at the inode */
|
||||||
|
@ -449,7 +416,6 @@ int nr_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_inode(&stat_buf); /* save the inode on disk */
|
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 */
|
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 */
|
lseek(fd, (off_t) blk_offset, SEEK_SET); /* set pointer at word */
|
||||||
|
|
||||||
rd = read(fd, (char *) &tst_word, SIZE_OF_INT);
|
rd = read(fd, (char *) &tst_word, SIZE_OF_INT);
|
||||||
|
@ -560,7 +525,6 @@ zone_t num;
|
||||||
blk_offset += (long) (words * SIZE_OF_INT);
|
blk_offset += (long) (words * SIZE_OF_INT);
|
||||||
|
|
||||||
|
|
||||||
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
|
|
||||||
lseek(fd, (off_t) blk_offset, SEEK_SET);
|
lseek(fd, (off_t) blk_offset, SEEK_SET);
|
||||||
|
|
||||||
rwd = read(fd, (char *) &tst_word, SIZE_OF_INT);
|
rwd = read(fd, (char *) &tst_word, SIZE_OF_INT);
|
||||||
|
@ -570,7 +534,6 @@ zone_t num;
|
||||||
}
|
}
|
||||||
bit = offset % INT_BITS;
|
bit = offset % INT_BITS;
|
||||||
if (((tst_word >> bit) & 01) == 0) { /* free */
|
if (((tst_word >> bit) & 01) == 0) { /* free */
|
||||||
lseek(fd, 0L, SEEK_SET);/* rewind */
|
|
||||||
lseek(fd, (off_t) blk_offset, SEEK_SET);
|
lseek(fd, (off_t) blk_offset, SEEK_SET);
|
||||||
tst_word |= (1 << bit); /* not free anymore */
|
tst_word |= (1 << bit); /* not free anymore */
|
||||||
rwd = write(fd, (char *) &tst_word, SIZE_OF_INT);
|
rwd = write(fd, (char *) &tst_word, SIZE_OF_INT);
|
||||||
|
|
|
@ -116,9 +116,7 @@ static struct super_block sb;
|
||||||
#define ZONE_SIZE ((int) ztob(block_size))
|
#define ZONE_SIZE ((int) ztob(block_size))
|
||||||
#define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1)
|
#define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1)
|
||||||
|
|
||||||
/* Byte address of a zone/of an inode */
|
/* Byte address of a zone */
|
||||||
#define cinoblock(i) (((i - 1)*INODE_SIZE) / block_size + BLK_ILIST)
|
|
||||||
#define cinooff(i) (((i - 1)*INODE_SIZE) % block_size)
|
|
||||||
#define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE))
|
#define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE))
|
||||||
#define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_SIZE))
|
#define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_SIZE))
|
||||||
|
|
||||||
|
@ -629,16 +627,12 @@ void chksuper()
|
||||||
|
|
||||||
int inoblock(int inn)
|
int inoblock(int inn)
|
||||||
{
|
{
|
||||||
int a;
|
return div64u(mul64u(inn - 1, INODE_SIZE), block_size) + BLK_ILIST;
|
||||||
a = cinoblock(inn);
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int inooff(int inn)
|
int inooff(int inn)
|
||||||
{
|
{
|
||||||
int a;
|
return rem64u(mul64u(inn - 1, INODE_SIZE), block_size);
|
||||||
a = cinooff(inn);
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a listing of the inodes given by `clist'. If `repair' is set, ask
|
/* Make a listing of the inodes given by `clist'. If `repair' is set, ask
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
/* Authors: Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans
|
/* Authors: Andy Tanenbaum, Paul Ogilvie, Frans Meulenbroeks, Bruce Evans
|
||||||
*
|
*
|
||||||
* This program can make both version 1 and version 2 file systems, as follows:
|
* This program can make version 1, 2 and 3 file systems, as follows:
|
||||||
* mkfs /dev/fd0 1200 # Version 2 (default)
|
* mkfs /dev/fd0 1200 # Version 3 (default)
|
||||||
* mkfs -1 /dev/fd0 360 # Version 1
|
* 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>
|
#include <sys/types.h>
|
||||||
|
@ -185,6 +187,8 @@ char *argv[];
|
||||||
default: usage();
|
default: usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc == optind) usage();
|
||||||
|
|
||||||
if(fs_version == 3) {
|
if(fs_version == 3) {
|
||||||
if(!block_size) block_size = _MAX_BLOCK_SIZE; /* V3 default block size */
|
if(!block_size) block_size = _MAX_BLOCK_SIZE; /* V3 default block size */
|
||||||
if(block_size%SECTOR_SIZE || block_size < _MIN_BLOCK_SIZE) {
|
if(block_size%SECTOR_SIZE || block_size < _MIN_BLOCK_SIZE) {
|
||||||
|
@ -428,8 +432,7 @@ ino_t inodes;
|
||||||
int inodeblks;
|
int inodeblks;
|
||||||
int initblks;
|
int initblks;
|
||||||
u32_t nb;
|
u32_t nb;
|
||||||
|
zone_t v1sq, v2sq;
|
||||||
zone_t initzones, nrzones, v1sq, v2sq;
|
|
||||||
zone_t zo;
|
zone_t zo;
|
||||||
struct super_block *sup;
|
struct super_block *sup;
|
||||||
char *buf, *cp;
|
char *buf, *cp;
|
||||||
|
@ -442,6 +445,7 @@ ino_t inodes;
|
||||||
sup->s_ninodes = inodes;
|
sup->s_ninodes = inodes;
|
||||||
if (fs_version == 1) {
|
if (fs_version == 1) {
|
||||||
sup->s_nzones = zones;
|
sup->s_nzones = zones;
|
||||||
|
if (sup->s_nzones != zones) pexit("too many zones");
|
||||||
} else {
|
} else {
|
||||||
sup->s_nzones = 0; /* not used in V2 - 0 forces errors early */
|
sup->s_nzones = 0; /* not used in V2 - 0 forces errors early */
|
||||||
sup->s_zones = zones;
|
sup->s_zones = zones;
|
||||||
|
@ -461,9 +465,8 @@ ino_t inodes;
|
||||||
inode_offset = sup->s_imap_blocks + sup->s_zmap_blocks + 2;
|
inode_offset = sup->s_imap_blocks + sup->s_zmap_blocks + 2;
|
||||||
inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block;
|
inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block;
|
||||||
initblks = inode_offset + inodeblks;
|
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;
|
sup->s_firstdatazone = nb = (initblks + (1 << zone_shift) - 1) >> zone_shift;
|
||||||
|
if(nb >= zones) pexit("bit maps too large");
|
||||||
if(nb != sup->s_firstdatazone) {
|
if(nb != sup->s_firstdatazone) {
|
||||||
fprintf(stderr, "mkfs: too much bitmap and inode data.\n" BIGGERBLOCKS);
|
fprintf(stderr, "mkfs: too much bitmap and inode data.\n" BIGGERBLOCKS);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -37,6 +37,7 @@ int
|
||||||
main(argc,argv) register char ** argv; {
|
main(argc,argv) register char ** argv; {
|
||||||
|
|
||||||
register char ** av;
|
register char ** av;
|
||||||
|
char *empty_envp[] = { (char *) 0 };
|
||||||
|
|
||||||
if (! isatty(1)) {
|
if (! isatty(1)) {
|
||||||
no_tty = 1;
|
no_tty = 1;
|
||||||
|
@ -58,7 +59,7 @@ main(argc,argv) register char ** argv; {
|
||||||
}
|
}
|
||||||
if (no_tty) {
|
if (no_tty) {
|
||||||
*--av = "cat";
|
*--av = "cat";
|
||||||
execve("/bin/cat", av, (char *) 0);
|
execve("/bin/cat", av, &empty_envp);
|
||||||
}
|
}
|
||||||
else processfiles(argc-(av-argv), av);
|
else processfiles(argc-(av-argv), av);
|
||||||
(VOID) quit();
|
(VOID) quit();
|
||||||
|
|
|
@ -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. */
|
/* Make a few basic checks to see if super block looks reasonable. */
|
||||||
if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
|
if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
|
||||||
|| sp->s_ninodes < 1 || sp->s_zones < 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) {
|
|| (unsigned) sp->s_log_zone_size > 4) {
|
||||||
printf("not enough imap or zone map blocks, \n");
|
printf("not enough imap or zone map blocks, \n");
|
||||||
printf("or not enough inodes, or not enough zones, "
|
printf("or not enough inodes, or not enough zones, \n"
|
||||||
"or zone size too large\n");
|
"or invalid first data zone, or zone size too large\n");
|
||||||
return(EINVAL);
|
return(EINVAL);
|
||||||
}
|
}
|
||||||
sp->s_dev = dev; /* restore device number */
|
sp->s_dev = dev; /* restore device number */
|
||||||
|
|
Loading…
Reference in a new issue