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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user