The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-02  1:36 Noel Chiappa
  2023-03-02  1:56 ` John Cowan
  2023-03-02  2:12 ` Bakul Shah
  0 siblings, 2 replies; 37+ messages in thread
From: Noel Chiappa @ 2023-03-02  1:36 UTC (permalink / raw)
  To: tuhs; +Cc: jnc

    > From: KenUnix

    > things are missing:

    > Undefined:
    > _setexit
    > _reset
    > _seek
    > _alloc
    > _end

    > Yes, I am trying to compile it on Unix v7.

Well, there's your answer. They are all in the V6 library. Here's
the source for setexit/reset:

  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/s5/reset.s

You do realize that if you got it compiled under V7 and ran it, it would
trash the disk, right? (The V6 and V7 filesystems are different; very
similar, but block nubers are 16 bits on V6, ans 32 bits on V7.)

    > Is there a makefile?

No. No 'make' in V6. Which is why you find those 'run' shell files:

  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/s4/run

everywhere.


    > From: John Cowan

    > It was an update/rewrite of the MIT version.

Which one? There were two: "MIT's AI Lab", by CSTACY, Alan Wecsler, and me;
which Rob Austein re-wrote into "Alice's PDP-10". I thought the original was
centered around ITS, but my memory was poor (hey, it has been ~40 years :-),
it seems to sort of be about LISP Machines. Rob's version was about TWENEX
(yech). The original was written in 926, MOON's office; I can't believe he
put up with me hanging out there!

    >> Although I like the old story about the person at their oral exam and
    >> the Coke bottle in the window.

    > Details?

So they're giving someone an oral exam. They can't make up their minds, or
something, and they ask the person to step out for a second. When the person
comes back in, they point to a Coke bottle sitting on a window-sill in the
sunlight, and ask them to examine it. The person notices that it's warm on
one side - the side facing the window. 'Why that side?', they ask. So the
person goes into a long explanation about how the curved glass must have
focused the light, yadda-yadda. WRONG! They turned it around while the
person was out of the room. I think that the person fails their oral. I
have no idea if it's a true story.

Steve Ward told another oral story which I'm pretty sure _is_ true, though.
They ask the candidate to design a state machine (or digital logic, I forget
which) which can tell if a number is divisible by three (I think I have the
details correct, but I'm not absolutely certain). So they describe one - and
then point out that you can feed the number in from either end (most or least
significant end first) - and proves that it will work either way! The
committee was blown away.

	Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  1:36 [TUHS] Re: Unix v7 icheck dup problem Noel Chiappa
@ 2023-03-02  1:56 ` John Cowan
  2023-03-02  6:41   ` Lars Brinkhoff
  2023-03-02  2:12 ` Bakul Shah
  1 sibling, 1 reply; 37+ messages in thread
From: John Cowan @ 2023-03-02  1:56 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

[-- Attachment #1: Type: text/plain, Size: 878 bytes --]

On Wed, Mar 1, 2023 at 8:36 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:


> Which one? There were two: "MIT's AI Lab", by CSTACY, Alan Wecsler, and me;


That one.  Mine should really be rewritten now.

> which Rob Austein re-wrote into "Alice's PDP-10".
>

I didn't know that one was done at MIT.

> I think that the person fails their oral. I
> have no idea if it's a true story.
>

That's vicious.  It reminds me of the medical oral exam where the last
question is "How many cranial nerves are there in Great Britain?"  Of
course the candidate tries to remember how many people there are and
multiplies it by 12, on the fly.  The answer is "One more than in the
U.S.", because one subdivided nerve is/was considered two distinct nerves
there.

"Mr. Asimov, what can you tell us about the endochronic properties of
resublimated thiotimoline?"

[-- Attachment #2: Type: text/html, Size: 2590 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  1:36 [TUHS] Re: Unix v7 icheck dup problem Noel Chiappa
  2023-03-02  1:56 ` John Cowan
@ 2023-03-02  2:12 ` Bakul Shah
  2023-03-02  2:46   ` Rich Salz
  1 sibling, 1 reply; 37+ messages in thread
From: Bakul Shah @ 2023-03-02  2:12 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Mar 1, 2023, at 5:36 PM, Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:
> 
> Steve Ward told another oral story which I'm pretty sure _is_ true, though.
> They ask the candidate to design a state machine (or digital logic, I forget
> which) which can tell if a number is divisible by three (I think I have the
> details correct, but I'm not absolutely certain). So they describe one - and
> then point out that you can feed the number in from either end (most or least
> significant end first) - and proves that it will work either way! The
> committee was blown away.

Doesn't everyone know that a number is divisible by 3 if the one digit
result after casting out 9s is divisible by 3?

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  2:12 ` Bakul Shah
@ 2023-03-02  2:46   ` Rich Salz
  0 siblings, 0 replies; 37+ messages in thread
From: Rich Salz @ 2023-03-02  2:46 UTC (permalink / raw)
  To: Bakul Shah; +Cc: Noel Chiappa, The Eunuchs Hysterical Society

[-- Attachment #1: Type: text/plain, Size: 385 bytes --]

>
>
> > then point out that you can feed the number in from either end (most or
> least
> > significant end first) - and proves that it will work either way! The
> > committee was blown away.
>
> Doesn't everyone know that a number is divisible by 3 if the one digit
> result after casting out 9s is divisible by 3?


Sure. But the amazing point was it worked regardless of bit order.

[-- Attachment #2: Type: text/html, Size: 672 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  1:56 ` John Cowan
@ 2023-03-02  6:41   ` Lars Brinkhoff
  0 siblings, 0 replies; 37+ messages in thread
From: Lars Brinkhoff @ 2023-03-02  6:41 UTC (permalink / raw)
  To: John Cowan; +Cc: Noel Chiappa, coff

John Cowan <cowan@ccil.org> writes:
>>  which Rob Austein re-wrote into "Alice's PDP-10". 
> I didn't know that one was done at MIT.

This spells out the details:
https://www.hactrn.net/sra/alice/alice.glossary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-06  8:58 ` Jonathan Gray
@ 2023-03-07  2:05   ` Kenneth Goodwin
  0 siblings, 0 replies; 37+ messages in thread
From: Kenneth Goodwin @ 2023-03-07  2:05 UTC (permalink / raw)
  To: Jonathan Gray; +Cc: Noel Chiappa, The Eunuchs Hysterical Society

[-- Attachment #1: Type: text/plain, Size: 1391 bytes --]

Anyone remember PFSCK,  aka parallel fsck that fired up multiple parallel
fsck instances, one per filesystem and used bidirectional pipes to pass
commands from the operator to each individual fsck stream.  Cut boot times
down quite a bit on healthy systems.

I believe the filesystem MOUNT table file on ROOT had fields related to
controlling PFSCK behavior

I remember hacking it for some reason related to performance,  But GOK
why......

On Mon, Mar 6, 2023, 3:59 AM Jonathan Gray <jsg@jsg.id.au> wrote:

> On Mon, Mar 06, 2023 at 03:14:27AM -0500, Noel Chiappa wrote:
> >
> > I've also been amusing myself trying to figure out who wrote:
> >
> >   http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c
>
> According to Guy Harris in
> https://groups.google.com/g/net.unix/c/-H9x36DMOBQ/m/4mcL76lKbmMJ
>
> 'they had to replace "icheck" and "dcheck" with a new program which
> would do most of the dirty work of file system repair for them -
> Hal wrote one called "fcheck", which cleaned V6 file systems, and
> which appeared in source-code form on the PWB/UNIX 1.0 distribution
> tape.  Unfortunately, PWB/UNIX 1.0 modified the V6 file system so
> that it didn't support "huge" files, and the eighth indirect pointer
> pointed directly to a block as the other seven did, so the "fcheck"
> there wouldn't fix a vanilla PWB/UNIX file system, but it worked
> just fine on a vanilla V6 FS.'
>

[-- Attachment #2: Type: text/html, Size: 2122 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-06  8:14 Noel Chiappa
@ 2023-03-06  8:58 ` Jonathan Gray
  2023-03-07  2:05   ` Kenneth Goodwin
  0 siblings, 1 reply; 37+ messages in thread
From: Jonathan Gray @ 2023-03-06  8:58 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Mon, Mar 06, 2023 at 03:14:27AM -0500, Noel Chiappa wrote:
> 
> I've also been amusing myself trying to figure out who wrote:
> 
>   http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c

According to Guy Harris in
https://groups.google.com/g/net.unix/c/-H9x36DMOBQ/m/4mcL76lKbmMJ

'they had to replace "icheck" and "dcheck" with a new program which
would do most of the dirty work of file system repair for them -
Hal wrote one called "fcheck", which cleaned V6 file systems, and
which appeared in source-code form on the PWB/UNIX 1.0 distribution
tape.  Unfortunately, PWB/UNIX 1.0 modified the V6 file system so
that it didn't support "huge" files, and the eighth indirect pointer
pointed directly to a block as the other seven did, so the "fcheck"
there wouldn't fix a vanilla PWB/UNIX file system, but it worked
just fine on a vanilla V6 FS.'

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-06  8:14 Noel Chiappa
  2023-03-06  8:58 ` Jonathan Gray
  0 siblings, 1 reply; 37+ messages in thread
From: Noel Chiappa @ 2023-03-06  8:14 UTC (permalink / raw)
  To: tuhs; +Cc: jnc

    > I'll turn this into a 'Fixing damaged V5/V6 file systems' article on
    > the CHWiki.

Here'a a first crack at it:

  https://gunkies.org/wiki/Repairing_early_UNIX_file_systems

Any suggestions for improvements/additions will be gratefully received!


I've also been amusing myself trying to figure out who wrote:

  http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c

and how it got to MIT - which might give us a clue as to who wrote it. (It's
clearly a distant ancestor to 'fsck'.) The fact that we've lost Ted Kowalski
is really hindering, alas. Interestingly, Dale DeJager, head of the CB-UNIX
group, earlier remembered Hal Pierson working on a file system checker early
on:

  "Hal also implemented the first file system check routine that was written
  in C. It replaced an .. assembler version from research"

but it's not clear if the thing Hal wrote, mentioned there, has any
relationship with the 'check' of V5:

  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V5/usr/source/s1/check.c

Maybe one of the Labs old-timers here remembers where the V5 thing came from?
(I.e. did Ken or Dennis write it, or did it come from Columbus?) If you do, it
would be a big help!

   Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-04 14:41 Noel Chiappa
@ 2023-03-04 14:49 ` KenUnix
  0 siblings, 0 replies; 37+ messages in thread
From: KenUnix @ 2023-03-04 14:49 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs


[-- Attachment #1.1: Type: text/plain, Size: 3025 bytes --]

Attached is the one I have been toying with. Ignore the 'v7' part I added.

Ken

On Sat, Mar 4, 2023 at 9:41 AM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:

>     > From: Clem Cole wrote:
>
>     > It had more colorful name originally - fsck (pronounced as fisk BTW)
>     > was finished. I suspect the fcheck name was a USG idea.
>
> I dunno. I don't think we at MIT wold have gratuitously changed the name to
> 'fcheck'; I rather think that was its original name - and we pretty
> definitely got it from CMU. 'fsck' was definitely descended from 'fcheck'
> (below).
>
>
>     > From: Jonathan Gray
>
>     >> (are 'fsck' and 'fcheck' the same program?)
>
>     > https://www.tuhs.org/cgi-bin/utree.pl?file=V7addenda/fsck
>
> Having looked the the source to both, it's quite clear that 'fcheck' is a
> distant ancestor of 'fsck' (see below for thoughts on the connection(s)).
> The
> latter has been _very_ extensively modified, but there are still some
> traces
> of 'fcheck' left.
>
> A lot of the changes are to increase the portability, and also to come into
> compliance with the latest 'C' (e.g. function prototypes); others are just
> to
> get rid of oddities in the original coding style. E.g.:
>
>   unsigned
>         dsize,
>         fmin,
>         fmax
>   ;
>
> Perfectly legal C, but nobody uses that style.
>
>
>     > From: Jonathan Gray
>
>     > fcheck is from Hal Pierson at Bell according to
>     > https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/readme.txt
>
> Hmm. "the major features that were added to UNIX by CB/UNIX ... Hal Person
> (or Pierson?) also rewrote the original check disk command into something
> that was useful by someone other than researchers."
>
> I poked around in CB/UNIX, and found 'check(1M)':
>
>
> https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/cbunix_man1_01.pdf
>
> (dated November 1979). Alas, the source isn't there, but it's clearly in
> the
> fheck/fsck family. (CB/UNIX also has chkold(1M), which looks to me like
> it's
> 'icheck'.)
>
> So now we have a question about the ancestry of 'check' and 'fcheck' - is
> one
> an ancestor of the other, and if so, which - or are they independent
> creations? Without the source, it's hard to be definitive, bur from the
> messages (as given in the manual), they do seem related.
>
> Clem's message of 3 Mar, 14:35 seems to indicate the the original was from
> CMU, authored by Ted Kowalski; he also:
>
>   https://wiki.tuhs.org/doku.php?id=anecdotes:clem_cole_student
>
> says "Ted Kowalski shows up for his OYOC year in the EE dept after his
> summer
> at Bell Labs ... He also brought his cool (but unfinished) program he had
> started to write originally at U Mich - fsck". So maybe the CB/UNIX
> 'check' is
> descended from a version that Ted left behind at Bell Labs?
>
> Is anyone in touch with Hal Pierson? He could surely clear up these
> questions.
>
>         Noel
>


-- 
End of line
JOB TERMINATED

[-- Attachment #1.2: Type: text/html, Size: 4351 bytes --]

[-- Attachment #2: v7fsck.c --]
[-- Type: text/x-csrc, Size: 33044 bytes --]

#include <stdio.h>
#include <ctype.h>
#include <sys/param.h>
#include <sys/filsys.h>
#include <sys/dir.h>
#include <sys/fblk.h>
#include <sys/ino.h>
#include <sys/inode.h>
#include <sys/stat.h>

typedef	int	(*SIG_TYP)();

#define NDIRECT	(BSIZE/sizeof(struct direct))
#define SPERB	(BSIZE/sizeof(short))

#define NO	0
#define YES	1

#define	MAXDUP	10		/* limit on dup blks (per inode) */
#define	MAXBAD	10		/* limit on bad blks (per inode) */

#define STEPSIZE	9	/* default step for freelist spacing */
#define CYLSIZE		400	/* default cyl size for spacing */
#define MAXCYL		500	/* maximum cylinder size */

#define BITSPB	8		/* number bits per byte */
#define BITSHIFT	3	/* log2(BITSPB) */
#define BITMASK	07		/* BITSPB-1 */
#define LSTATE	2		/* bits per inode state */
#define STATEPB	(BITSPB/LSTATE)	/* inode states per byte */
#define USTATE	0		/* inode not allocated */
#define FSTATE	01		/* inode is file */
#define DSTATE	02		/* inode is directory */
#define CLEAR	03		/* inode is to be cleared */
#define SMASK	03		/* mask for inode state */

typedef struct dinode	DINODE;
typedef struct direct	DIRECT;

#define ALLOC	((dp->di_mode & IFMT) != 0)
#define DIR	((dp->di_mode & IFMT) == IFDIR)
#define REG	((dp->di_mode & IFMT) == IFREG)
#define BLK	((dp->di_mode & IFMT) == IFBLK)
#define CHR	((dp->di_mode & IFMT) == IFCHR)
#define MPC	((dp->di_mode & IFMT) == IFMPC)
#define MPB	((dp->di_mode & IFMT) == IFMPB)
#define SPECIAL	(BLK || CHR || MPC || MPB)

#define NINOBLK	11		/* num blks for raw reading */
#define MAXRAW	110		/* largest raw read (in blks) */
daddr_t	startib;		/* blk num of first in raw area */
unsigned niblk;			/* num of blks in raw area */

struct bufarea {
	struct bufarea	*b_next;		/* must be first */
	daddr_t	b_bno;
	union {
		char	b_buf[BSIZE];		/* buffer space */
		short	b_lnks[SPERB];		/* link counts */
		daddr_t	b_indir[NINDIR];	/* indirect block */
		struct filsys b_fs;		/* super block */
		struct fblk b_fb;		/* free block */
		struct dinode b_dinode[INOPB];	/* inode block */
		DIRECT b_dir[NDIRECT];		/* directory */
	} b_un;
	char	b_dirty;
};

typedef struct bufarea BUFAREA;

BUFAREA	inoblk;			/* inode blocks */
BUFAREA	fileblk;		/* other blks in filesys */
BUFAREA	sblk;			/* file system superblock */
BUFAREA	*poolhead;		/* ptr to first buffer in pool */

#define initbarea(x)	(x)->b_dirty = 0;(x)->b_bno = (daddr_t)-1
#define dirty(x)	(x)->b_dirty = 1
#define inodirty()	inoblk.b_dirty = 1
#define fbdirty()	fileblk.b_dirty = 1
#define sbdirty()	sblk.b_dirty = 1

#define freeblk		fileblk.b_un.b_fb
#define dirblk		fileblk.b_un
#define superblk	sblk.b_un.b_fs

struct filecntl {
	int	rfdes;
	int	wfdes;
	int	mod;
};

struct filecntl	dfile;		/* file descriptors for filesys */
struct filecntl	sfile;		/* file descriptors for scratch file */

typedef unsigned MEMSIZE;

MEMSIZE	memsize;		/* amt of memory we got */
#ifdef pdp11
#define MAXDATA	((MEMSIZE)54*1024)
#endif
#if vax
#define	MAXDATA ((MEMSIZE)400*1024)
#endif
#if interdata
#define	MAXDATA ((MEMSIZE)400*1024)
#endif

#define	DUPTBLSIZE	100	/* num of dup blocks to remember */
daddr_t	duplist[DUPTBLSIZE];	/* dup block table */
daddr_t	*enddup;		/* next entry in dup table */
daddr_t	*muldup;		/* multiple dups part of table */

#define MAXLNCNT	20	/* num zero link cnts to remember */
ino_t	badlncnt[MAXLNCNT];	/* table of inos with zero link cnts */
ino_t	*badlnp;		/* next entry in table */

char	sflag;			/* salvage free block list */
char	csflag;			/* salvage free block list (conditional) */
char	nflag;			/* assume a no response */
char	yflag;			/* assume a yes response */
char	tflag;			/* scratch file specified */
char	rplyflag;		/* any questions asked? */
char	hotroot;		/* checking root device */
char	rawflg;			/* read raw device */
char	rmscr;			/* remove scratch file when done */
char	fixfree;		/* corrupted free list */
char	*membase;		/* base of memory we get */
char	*blkmap;		/* ptr to primary blk allocation map */
char	*freemap;		/* ptr to secondary blk allocation map */
char	*statemap;		/* ptr to inode state table */
char	*pathp;			/* pointer to pathname position */
char	*thisname;		/* ptr to current pathname component */
char	*srchname;		/* name being searched for in dir */
char	pathname[200];
char	scrfile[80];
char	*lfname =	"lost+found";
char	*checklist =	"/etc/checklist";

short	*lncntp;		/* ptr to link count table */

int	cylsize;		/* num blocks per cylinder */
int	stepsize;		/* num blocks for spacing purposes */
int	badblk;			/* num of bad blks seen (per inode) */
int	dupblk;			/* num of dup blks seen (per inode) */
int	(*pfunc)();		/* function to call to chk blk */

ino_t	inum;			/* inode we are currently working on */
ino_t	imax;			/* number of inodes */
ino_t	parentdir;		/* i number of parent directory */
ino_t	lastino;		/* hiwater mark of inodes */
ino_t	lfdir;			/* lost & found directory */
ino_t	orphan;			/* orphaned inode */

off_t	filsize;		/* num blks seen in file */
off_t	maxblk;			/* largest logical blk in file */
off_t	bmapsz;			/* num chars in blkmap */

daddr_t	smapblk;		/* starting blk of state map */
daddr_t	lncntblk;		/* starting blk of link cnt table */
daddr_t	fmapblk;		/* starting blk of free map */
daddr_t	n_free;			/* number of free blocks */
daddr_t	n_blks;			/* number of blocks used */
daddr_t	n_files;		/* number of files seen */
daddr_t	fmin;			/* block number of the first data block */
daddr_t	fmax;			/* number of blocks in the volume */

#define howmany(x,y)	(((x)+((y)-1))/(y))
#define roundup(x,y)	((((x)+((y)-1))/(y))*(y))
#define outrange(x)	(x < fmin || x >= fmax)
#define zapino(x)	clear((char *)(x),sizeof(DINODE))

#define setlncnt(x)	dolncnt(x,0)
#define getlncnt()	dolncnt(0,1)
#define declncnt()	dolncnt(0,2)

#define setbmap(x)	domap(x,0)
#define getbmap(x)	domap(x,1)
#define clrbmap(x)	domap(x,2)

#define setfmap(x)	domap(x,0+4)
#define getfmap(x)	domap(x,1+4)
#define clrfmap(x)	domap(x,2+4)

#define setstate(x)	dostate(x,0)
#define getstate()	dostate(0,1)

#define DATA	1
#define ADDR	0
#define ALTERD	010
#define KEEPON	04
#define SKIP	02
#define STOP	01

int	(*signal())();
long	lseek();
long	time();
DINODE	*ginode();
BUFAREA	*getblk();
BUFAREA	*search();
int	dirscan();
int	findino();
int	catch();
int	mkentry();
int	chgdd();
int	pass1();
int	pass1b();
int	pass2();
int	pass3();
int	pass4();
int	pass5();

main(argc,argv)
int	argc;
char	*argv[];
{
	register FILE *fp;
	register n;
	register char *p;
	char filename[50];
	char *sbrk();

	sync();
	while(--argc > 0 && **++argv == '-') {
		switch(*++*argv) {
			case 't':
			case 'T':
				tflag++;
				if(**++argv == '-' || --argc <= 0)
					errexit("Bad -t option\n");
				p = scrfile;
				while(*p++ = **argv)
					(*argv)++;
				break;
			case 's':	/* salvage flag */
				stype(++*argv);
				sflag++;
				break;
			case 'S':	/* conditional salvage */
				stype(++*argv);
				csflag++;
				break;
			case 'n':	/* default no answer flag */
			case 'N':
				nflag++;
				yflag = 0;
				break;
			case 'y':	/* default yes answer flag */
			case 'Y':
				yflag++;
				nflag = 0;
				break;
			default:
				errexit("%c option?\n",**argv);
		}
	}
	if(nflag && (sflag || csflag))
		errexit("Incompatible options: -n and -%s\n",sflag?"s":"S");
	if(sflag && csflag)
		sflag = 0;
	memsize = (MEMSIZE)sbrk(0);
	memsize = MAXDATA - memsize - sizeof(int);
	while(memsize >= 2*sizeof(BUFAREA) &&
		(membase = sbrk(memsize)) == (char *)-1)
		memsize -= 1024;
	if(memsize < 2*sizeof(BUFAREA))
		errexit("Can't get memory\n");
#define SIG_IGN	(int (*)())1
	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, catch);
	if(argc) {		/* arg list has file names */
		while(argc-- > 0)
			check(*argv++);
	}
	else {			/* use default checklist */
		if((fp = fopen(checklist,"r")) == NULL)
			errexit("Can't open checklist file: %s\n",checklist);
		while(getline(fp,filename,sizeof(filename)) != EOF)
			check(filename);
		fclose(fp);
	}
	exit(0);
}


/* VARARGS1 */
error(s1,s2,s3,s4)
char *s1;
{
	printf(s1,s2,s3,s4);
}


/* VARARGS1 */
errexit(s1,s2,s3,s4)
char *s1;
{
	error(s1,s2,s3,s4);
	exit(8);
}


check(dev)
char *dev;
{
	register DINODE *dp;
	register n;
	register ino_t *blp;
	ino_t savino;
	daddr_t blk;
	BUFAREA *bp1, *bp2;

	if(setup(dev) == NO)
		return;


	printf("** Phase 1 - Check Blocks and Sizes\n");
	pfunc = pass1;
	for(inum = 1; inum <= imax; inum++) {
		if((dp = ginode()) == NULL)
			continue;
		if(ALLOC) {
			lastino = inum;
			if(ftypeok(dp) == NO) {
				printf("UNKNOWN FILE TYPE I=%u",inum);
				if(reply("CLEAR") == YES) {
					zapino(dp);
					inodirty();
				}
				continue;
			}
			n_files++;
			if(setlncnt(dp->di_nlink) <= 0) {
				if(badlnp < &badlncnt[MAXLNCNT])
					*badlnp++ = inum;
				else {
					printf("LINK COUNT TABLE OVERFLOW");
					if(reply("CONTINUE") == NO)
						errexit("");
				}
			}
			setstate(DIR ? DSTATE : FSTATE);
			badblk = dupblk = 0;
			filsize = 0;
			maxblk = 0;
			ckinode(dp,ADDR);
			if((n = getstate()) == DSTATE || n == FSTATE)
				sizechk(dp);
		}
		else if(dp->di_mode != 0) {
			printf("PARTIALLY ALLOCATED INODE I=%u",inum);
			if(reply("CLEAR") == YES) {
				zapino(dp);
				inodirty();
			}
		}
	}


	if(enddup != &duplist[0]) {
		printf("** Phase 1b - Rescan For More DUPS\n");
		pfunc = pass1b;
		for(inum = 1; inum <= lastino; inum++) {
			if(getstate() != USTATE && (dp = ginode()) != NULL)
				if(ckinode(dp,ADDR) & STOP)
					break;
		}
	}
	if(rawflg) {
		if(inoblk.b_dirty)
			bwrite(&dfile,membase,startib,(int)niblk*BSIZE);
		inoblk.b_dirty = 0;
		if(poolhead) {
			clear(membase,niblk*BSIZE);
			for(bp1 = poolhead;bp1->b_next;bp1 = bp1->b_next);
			bp2 = &((BUFAREA *)membase)[(niblk*BSIZE)/sizeof(BUFAREA)];
			while(--bp2 >= (BUFAREA *)membase) {
				initbarea(bp2);
				bp2->b_next = bp1->b_next;
				bp1->b_next = bp2;
			}
		}
		rawflg = 0;

	}


	printf("** Phase 2 - Check Pathnames\n");
	inum = ROOTINO;
	thisname = pathp = pathname;
	pfunc = pass2;
	switch(getstate()) {
		case USTATE:
			errexit("ROOT INODE UNALLOCATED. TERMINATING.\n");
		case FSTATE:
			printf("ROOT INODE NOT DIRECTORY");
			if(reply("FIX") == NO || (dp = ginode()) == NULL)
				errexit("");
			dp->di_mode &= ~IFMT;
			dp->di_mode |= IFDIR;
			inodirty();
			setstate(DSTATE);
		case DSTATE:
			descend();
			break;
		case CLEAR:
			printf("DUPS/BAD IN ROOT INODE\n");
			if(reply("CONTINUE") == NO)
				errexit("");
			setstate(DSTATE);
			descend();
	}


	printf("** Phase 3 - Check Connectivity\n");
	for(inum = ROOTINO; inum <= lastino; inum++) {
		if(getstate() == DSTATE) {
			pfunc = findino;
			srchname = "..";
			savino = inum;
			do {
				orphan = inum;
				if((dp = ginode()) == NULL)
					break;
				filsize = dp->di_size;
				parentdir = 0;
				ckinode(dp,DATA);
				if((inum = parentdir) == 0)
					break;
			} while(getstate() == DSTATE);
			inum = orphan;
			if(linkup() == YES) {
				thisname = pathp = pathname;
				*pathp++ = '?';
				pfunc = pass2;
				descend();
			}
			inum = savino;
		}
	}


	printf("** Phase 4 - Check Reference Counts\n");
	pfunc = pass4;
	for(inum = ROOTINO; inum <= lastino; inum++) {
		switch(getstate()) {
			case FSTATE:
				if(n = getlncnt())
					adjust((short)n);
				else {
					for(blp = badlncnt;blp < badlnp; blp++)
						if(*blp == inum) {
							clri("UNREF",YES);
							break;
						}
				}
				break;
			case DSTATE:
				clri("UNREF",YES);
				break;
			case CLEAR:
				clri("BAD/DUP",YES);
		}
	}
#ifndef interdata
	if(imax - n_files != superblk.s_tinode) {
		printf("FREE INODE COUNT WRONG IN SUPERBLK");
		if(reply("FIX") == YES) {
			superblk.s_tinode = imax - n_files;
			sbdirty();
		}
	}
#endif
	flush(&dfile,&fileblk);


	printf("** Phase 5 - Check Free List ");
	if(sflag || (csflag && rplyflag == 0)) {
		printf("(Ignored)\n");
		fixfree = 1;
	}
	else {
		printf("\n");
		if(freemap)
			copy(blkmap,freemap,(MEMSIZE)bmapsz);
		else {
			for(blk = 0; blk < fmapblk; blk++) {
				bp1 = getblk((BUFAREA *)NULL,blk);
				bp2 = getblk((BUFAREA *)NULL,blk+fmapblk);
				copy(bp1->b_un.b_buf,bp2->b_un.b_buf,BSIZE);
				dirty(bp2);
			}
		}
		badblk = dupblk = 0;
		freeblk.df_nfree = superblk.s_nfree;
		for(n = 0; n < NICFREE; n++)
			freeblk.df_free[n] = superblk.s_free[n];
		freechk();
		if(badblk)
			printf("%d BAD BLKS IN FREE LIST\n",badblk);
		if(dupblk)
			printf("%d DUP BLKS IN FREE LIST\n",dupblk);
		if(fixfree == 0) {
			if((n_blks+n_free) != (fmax-fmin)) {
				printf("%ld BLK(S) MISSING\n",
					fmax-fmin-n_blks-n_free);
				fixfree = 1;
			}
			else if(n_free != superblk.s_tfree) {
#ifndef interdata
				printf("FREE BLK COUNT WRONG IN SUPERBLK");
				if(reply("FIX") == YES) {
					superblk.s_tfree = n_free;
					sbdirty();
				}
#endif
			}
		}
		if(fixfree) {
			printf("BAD FREE LIST");
			if(reply("SALVAGE") == NO)
				fixfree = 0;
		}
	}


	if(fixfree) {
		printf("** Phase 6 - Salvage Free List\n");
		makefree();
		n_free = superblk.s_tfree;
	}


	printf("%ld files %ld blocks %ld free\n",
		n_files,n_blks,n_free);
	if(dfile.mod) {
		time(&superblk.s_time);
		sbdirty();
	}
	ckfini();
	sync();
	if(dfile.mod && hotroot) {
		printf("\n***** BOOT UNIX (NO SYNC!) *****\n");
		for(;;);
	}
	if(dfile.mod)
		printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
}


ckinode(dp,flg)
DINODE *dp;
register flg;
{
	register daddr_t *ap;
	register ret;
	int (*func)(), n;
	daddr_t	iaddrs[NADDR];

	if(SPECIAL)
		return(KEEPON);
	l3tol(iaddrs,dp->di_addr,NADDR);
	func = (flg == ADDR) ? pfunc : dirscan;
	for(ap = iaddrs; ap < &iaddrs[NADDR-3]; ap++) {
		if(*ap && (ret = (*func)(*ap)) & STOP)
			return(ret);
	}
	for(n = 1; n < 4; n++) {
		if(*ap && (ret = iblock(*ap,n,flg)) & STOP)
			return(ret);
		ap++;
	}
	return(KEEPON);
}


iblock(blk,ilevel,flg)
daddr_t blk;
register ilevel;
{
	register daddr_t *ap;
	register n;
	int (*func)();
	BUFAREA ib;

	if(flg == ADDR) {
		func = pfunc;
		if(((n = (*func)(blk)) & KEEPON) == 0)
			return(n);
	}
	else
		func = dirscan;
	if(outrange(blk))		/* protect thyself */
		return(SKIP);
	initbarea(&ib);
	if(getblk(&ib,blk) == NULL)
		return(SKIP);
	ilevel--;
	for(ap = ib.b_un.b_indir; ap < &ib.b_un.b_indir[NINDIR]; ap++) {
		if(*ap) {
			if(ilevel > 0) {
				n = iblock(*ap,ilevel,flg);
			}
			else
				n = (*func)(*ap);
			if(n & STOP)
				return(n);
		}
	}
	return(KEEPON);
}


pass1(blk)
daddr_t blk;
{
	register daddr_t *dlp;

	if(outrange(blk)) {
		blkerr("BAD",blk);
		if(++badblk >= MAXBAD) {
			printf("EXCESSIVE BAD BLKS I=%u",inum);
			if(reply("CONTINUE") == NO)
				errexit("");
			return(STOP);
		}
		return(SKIP);
	}
	if(getbmap(blk)) {
		blkerr("DUP",blk);
		if(++dupblk >= MAXDUP) {
			printf("EXCESSIVE DUP BLKS I=%u",inum);
			if(reply("CONTINUE") == NO)
				errexit("");
			return(STOP);
		}
		if(enddup >= &duplist[DUPTBLSIZE]) {
			printf("DUP TABLE OVERFLOW.");
			if(reply("CONTINUE") == NO)
				errexit("");
			return(STOP);
		}
		for(dlp = duplist; dlp < muldup; dlp++) {
			if(*dlp == blk) {
				*enddup++ = blk;
				break;
			}
		}
		if(dlp >= muldup) {
			*enddup++ = *muldup;
			*muldup++ = blk;
		}
	}
	else {
		n_blks++;
		setbmap(blk);
	}
	filsize++;
	return(KEEPON);
}


pass1b(blk)
daddr_t blk;
{
	register daddr_t *dlp;

	if(outrange(blk))
		return(SKIP);
	for(dlp = duplist; dlp < muldup; dlp++) {
		if(*dlp == blk) {
			blkerr("DUP",blk);
			*dlp = *--muldup;
			*muldup = blk;
			return(muldup == duplist ? STOP : KEEPON);
		}
	}
	return(KEEPON);
}


pass2(dirp)
register DIRECT *dirp;
{
	register char *p;
	register n;
	DINODE *dp;

	if((inum = dirp->d_ino) == 0)
		return(KEEPON);
	thisname = pathp;
	for(p = dirp->d_name; p < &dirp->d_name[DIRSIZ]; )
		if((*pathp++ = *p++) == 0) {
			--pathp;
			break;
		}
	*pathp = 0;
	n = NO;
	if(inum > imax || inum < ROOTINO)
		n = direrr("I OUT OF RANGE");
	else {
	again:
		switch(getstate()) {
			case USTATE:
				n = direrr("UNALLOCATED");
				break;
			case CLEAR:
				if((n = direrr("DUP/BAD")) == YES)
					break;
				if((dp = ginode()) == NULL)
					break;
				setstate(DIR ? DSTATE : FSTATE);
				goto again;
			case FSTATE:
				declncnt();
				break;
			case DSTATE:
				declncnt();
				descend();
		}
	}
	pathp = thisname;
	if(n == NO)
		return(KEEPON);
	dirp->d_ino = 0;
	return(KEEPON|ALTERD);
}


pass4(blk)
daddr_t blk;
{
	register daddr_t *dlp;

	if(outrange(blk))
		return(SKIP);
	if(getbmap(blk)) {
		for(dlp = duplist; dlp < enddup; dlp++)
			if(*dlp == blk) {
				*dlp = *--enddup;
				return(KEEPON);
			}
		clrbmap(blk);
		n_blks--;
	}
	return(KEEPON);
}


pass5(blk)
daddr_t blk;
{
	if(outrange(blk)) {
		fixfree = 1;
		if(++badblk >= MAXBAD) {
			printf("EXCESSIVE BAD BLKS IN FREE LIST.");
			if(reply("CONTINUE") == NO)
				errexit("");
			return(STOP);
		}
		return(SKIP);
	}
	if(getfmap(blk)) {
		fixfree = 1;
		if(++dupblk >= DUPTBLSIZE) {
			printf("EXCESSIVE DUP BLKS IN FREE LIST.");
			if(reply("CONTINUE") == NO)
				errexit("");
			return(STOP);
		}
	}
	else {
		n_free++;
		setfmap(blk);
	}
	return(KEEPON);
}


blkerr(s,blk)
daddr_t blk;
char *s;
{
	printf("%ld %s I=%u\n",blk,s,inum);
	setstate(CLEAR);	/* mark for possible clearing */
}


descend()
{
	register DINODE *dp;
	register char *savname;
	off_t savsize;

	setstate(FSTATE);
	if((dp = ginode()) == NULL)
		return;
	savname = thisname;
	*pathp++ = '/';
	savsize = filsize;
	filsize = dp->di_size;
	ckinode(dp,DATA);
	thisname = savname;
	*--pathp = 0;
	filsize = savsize;
}


dirscan(blk)
daddr_t blk;
{
	register DIRECT *dirp;
	register char *p1, *p2;
	register n;
	DIRECT direntry;

	if(outrange(blk)) {
		filsize -= BSIZE;
		return(SKIP);
	}
	for(dirp = dirblk.b_dir; dirp < &dirblk.b_dir[NDIRECT] &&
		filsize > 0; dirp++, filsize -= sizeof(DIRECT)) {
		if(getblk(&fileblk,blk) == NULL) {
			filsize -= (&dirblk.b_dir[NDIRECT]-dirp)*sizeof(DIRECT);
			return(SKIP);
		}
		p1 = &dirp->d_name[DIRSIZ];
		p2 = &direntry.d_name[DIRSIZ];
		while(p1 > (char *)dirp)
			*--p2 = *--p1;
		if((n = (*pfunc)(&direntry)) & ALTERD) {
			if(getblk(&fileblk,blk) != NULL) {
				p1 = &dirp->d_name[DIRSIZ];
				p2 = &direntry.d_name[DIRSIZ];
				while(p1 > (char *)dirp)
					*--p1 = *--p2;
				fbdirty();
			}
			else
				n &= ~ALTERD;
		}
		if(n & STOP)
			return(n);
	}
	return(filsize > 0 ? KEEPON : STOP);
}


direrr(s)
char *s;
{
	register DINODE *dp;

	printf("%s ",s);
	pinode();
	if((dp = ginode()) != NULL && ftypeok(dp))
		printf("\n%s=%s",DIR?"DIR":"FILE",pathname);
	else
		printf("\nNAME=%s",pathname);
	return(reply("REMOVE"));
}


adjust(lcnt)
register short lcnt;
{
	register DINODE *dp;

	if((dp = ginode()) == NULL)
		return;
	if(dp->di_nlink == lcnt) {
		if(linkup() == NO)
			clri("UNREF",NO);
	}
	else {
		printf("LINK COUNT %s",
			(lfdir==inum)?lfname:(DIR?"DIR":"FILE"));
		pinode();
		printf(" COUNT %d SHOULD BE %d",
			dp->di_nlink,dp->di_nlink-lcnt);
		if(reply("ADJUST") == YES) {
			dp->di_nlink -= lcnt;
			inodirty();
		}
	}
}


clri(s,flg)
char *s;
{
	register DINODE *dp;

	if((dp = ginode()) == NULL)
		return;
	if(flg == YES) {
		printf("%s %s",s,DIR?"DIR":"FILE");
		pinode();
	}
	if(reply("CLEAR") == YES) {
		n_files--;
		pfunc = pass4;
		ckinode(dp,ADDR);
		zapino(dp);
		inodirty();
	}
}


setup(dev)
char *dev;
{
	register n;
	register BUFAREA *bp;
	register MEMSIZE msize;
	char *mbase;
	daddr_t bcnt, nscrblk;
	dev_t rootdev;
	off_t smapsz, lncntsz, totsz;
	struct {
		daddr_t	tfree;
		ino_t	tinode;
		char	fname[6];
		char	fpack[6];
	} ustatarea;
	struct stat statarea;

	if(stat("/",&statarea) < 0)
		errexit("Can't stat root\n");
	rootdev = statarea.st_dev;
	if(stat(dev,&statarea) < 0) {
		error("Can't stat %s\n",dev);
		return(NO);
	}
	hotroot = 0;
	rawflg = 0;
	if((statarea.st_mode & S_IFMT) == S_IFBLK) {
		if(ustat(statarea.st_rdev, (char *)&ustatarea) >= 0) {
			hotroot++;
		}
	}
	else if((statarea.st_mode & S_IFMT) == S_IFCHR)
		rawflg++;
	else {
		if (reply("file is not a block or character device; OK") == NO)
			return(NO);
	}
	if(rootdev == statarea.st_rdev)
		hotroot++;
	if((dfile.rfdes = open(dev,0)) < 0) {
		error("Can't open %s\n",dev);
		return(NO);
	}
	printf("\n%s",dev);
	if(nflag || (dfile.wfdes = open(dev,1)) < 0) {
		dfile.wfdes = -1;
		printf(" (NO WRITE)");
	}
	printf("\n");
	fixfree = 0;
	dfile.mod = 0;
	n_files = n_blks = n_free = 0;
	muldup = enddup = &duplist[0];
	badlnp = &badlncnt[0];
	lfdir = 0;
	rplyflag = 0;
	initbarea(&sblk);
	initbarea(&fileblk);
	initbarea(&inoblk);
	sfile.wfdes = sfile.rfdes = -1;
	rmscr = 0;
	if(getblk(&sblk,SUPERB) == NULL) {
		ckfini();
		return(NO);
	}
	imax = ((ino_t)superblk.s_isize - (SUPERB+1)) * INOPB;
	fmin = (daddr_t)superblk.s_isize;	/* first data blk num */
	fmax = superblk.s_fsize;		/* first invalid blk num */
	if(fmin >= fmax || 
		(imax/INOPB) != ((ino_t)superblk.s_isize-(SUPERB+1))) {
		error("Size check: fsize %ld isize %d\n",
			superblk.s_fsize,superblk.s_isize);
		ckfini();
		return(NO);
	}
	printf("File System: %.6s Volume: %.6s\n\n", superblk.s_fname,
		superblk.s_fpack);
	bmapsz = roundup(howmany(fmax,BITSPB),sizeof(*lncntp));
	smapsz = roundup(howmany((long)(imax+1),STATEPB),sizeof(*lncntp));
	lncntsz = (long)(imax+1) * sizeof(*lncntp);
	if(bmapsz > smapsz+lncntsz)
		smapsz = bmapsz-lncntsz;
	totsz = bmapsz+smapsz+lncntsz;
	msize = memsize;
	mbase = membase;
	if(rawflg) {
		if(msize < (MEMSIZE)(NINOBLK*BSIZE) + 2*sizeof(BUFAREA))
			rawflg = 0;
		else {
			msize -= (MEMSIZE)NINOBLK*BSIZE;
			mbase += (MEMSIZE)NINOBLK*BSIZE;
			niblk = NINOBLK;
			startib = fmax;
		}
	}
	clear(mbase,msize);
	if((off_t)msize < totsz) {
		bmapsz = roundup(bmapsz,BSIZE);
		smapsz = roundup(smapsz,BSIZE);
		lncntsz = roundup(lncntsz,BSIZE);
		nscrblk = (bmapsz+smapsz+lncntsz)>>BSHIFT;
		if(tflag == 0) {
			printf("\nNEED SCRATCH FILE (%ld BLKS)\n",nscrblk);
			do {
				printf("ENTER FILENAME:  ");
				if((n = getline(stdin,scrfile,sizeof(scrfile))) == EOF)
					errexit("\n");
			} while(n == 0);
		}
		if(stat(scrfile,&statarea) < 0 ||
			(statarea.st_mode & S_IFMT) == S_IFREG)
			rmscr++;
		if((sfile.wfdes = creat(scrfile,0666)) < 0 ||
			(sfile.rfdes = open(scrfile,0)) < 0) {
			error("Can't create %s\n",scrfile);
			ckfini();
			return(NO);
		}
		bp = &((BUFAREA *)mbase)[(msize/sizeof(BUFAREA))];
		poolhead = NULL;
		while(--bp >= (BUFAREA *)mbase) {
			initbarea(bp);
			bp->b_next = poolhead;
			poolhead = bp;
		}
		bp = poolhead;
		for(bcnt = 0; bcnt < nscrblk; bcnt++) {
			bp->b_bno = bcnt;
			dirty(bp);
			flush(&sfile,bp);
		}
		blkmap = freemap = statemap = (char *) NULL;
		lncntp = (short *) NULL;
		smapblk = bmapsz / BSIZE;
		lncntblk = smapblk + smapsz / BSIZE;
		fmapblk = smapblk;
	}
	else {
		if(rawflg && (off_t)msize > totsz+BSIZE) {
			niblk += (unsigned)((off_t)msize-totsz)>>BSHIFT;
			if(niblk > MAXRAW)
				niblk = MAXRAW;
			msize = memsize - (niblk*BSIZE);
			mbase = membase + (niblk*BSIZE);
		}
		poolhead = NULL;
		blkmap = mbase;
		statemap = &mbase[(MEMSIZE)bmapsz];
		freemap = statemap;
		lncntp = (short *)&statemap[(MEMSIZE)smapsz];
	}
	return(YES);
}


DINODE *
ginode()
{
	register DINODE *dp;
	register char *mbase;
	daddr_t iblk;

	if(inum > imax)
		return(NULL);
	iblk = itod(inum);
	if(rawflg) {
		mbase = membase;
		if(iblk < startib || iblk >= startib+niblk) {
			if(inoblk.b_dirty)
				bwrite(&dfile,mbase,startib,(int)niblk*BSIZE);
			inoblk.b_dirty = 0;
			if(bread(&dfile,mbase,iblk,(int)niblk*BSIZE) == NO) {
				startib = fmax;
				return(NULL);
			}
			startib = iblk;
		}
		dp = (DINODE *)&mbase[(unsigned)((iblk-startib)<<BSHIFT)];
	}
	else if(getblk(&inoblk,iblk) != NULL)
		dp = inoblk.b_un.b_dinode;
	else
		return(NULL);
	return(dp + itoo(inum));
}


ftypeok(dp)
DINODE *dp;
{
	switch(dp->di_mode & IFMT) {
		case IFDIR:
		case IFREG:
		case IFBLK:
		case IFCHR:
		case IFMPC:
		case IFMPB:
			return(YES);
		default:
			return(NO);
	}
}


reply(s)
char *s;
{
	char line[80];

	rplyflag = 1;
	printf("\n%s? ",s);
	if(nflag || csflag || dfile.wfdes < 0) {
		printf(" no\n\n");
		return(NO);
	}
	if(yflag) {
		printf(" yes\n\n");
		return(YES);
	}
	if(getline(stdin,line,sizeof(line)) == EOF)
		errexit("\n");
	printf("\n");
	if(line[0] == 'y' || line[0] == 'Y')
		return(YES);
	else
		return(NO);
}


getline(fp,loc,maxlen)
FILE *fp;
char *loc;
{
	register n;
	register char *p, *lastloc;

	p = loc;
	lastloc = &p[maxlen-1];
	while((n = getc(fp)) != '\n') {
		if(n == EOF)
			return(EOF);
		if(!isspace(n) && p < lastloc)
			*p++ = n;
	}
	*p = 0;
	return(p - loc);
}


stype(p)
register char *p;
{
	if(*p == 0)
		return;
	if (*(p+1) == 0) {
		if (*p == '3') {
			cylsize = 200;
			stepsize = 5;
			return;
		}
		if (*p == '4') {
			cylsize = 418;
			stepsize = 9;
			return;
		}
	}
	cylsize = atoi(p);
	while(*p && *p != ':')
		p++;
	if(*p)
		p++;
	stepsize = atoi(p);
	if(stepsize <= 0 || stepsize > cylsize ||
	cylsize <= 0 || cylsize > MAXCYL) {
		error("Invalid -s argument, defaults assumed\n");
		cylsize = stepsize = 0;
	}
}


dostate(s,flg)
{
	register char *p;
	register unsigned byte, shift;
	BUFAREA *bp;

	byte = (inum)/STATEPB;
	shift = LSTATE * ((inum)%STATEPB);
	if(statemap != NULL) {
		bp = NULL;
		p = &statemap[byte];
	}
	else if((bp = getblk((BUFAREA *)NULL,(daddr_t)(smapblk+(byte/BSIZE)))) == NULL)
		errexit("Fatal I/O error\n");
	else
		p = &bp->b_un.b_buf[byte%BSIZE];
	switch(flg) {
		case 0:
			*p &= ~(SMASK<<(shift));
			*p |= s<<(shift);
			if(bp != NULL)
				dirty(bp);
			return(s);
		case 1:
			return((*p>>(shift)) & SMASK);
	}
	return(USTATE);
}


domap(blk,flg)
daddr_t blk;
{
	register char *p;
	register unsigned n;
	register BUFAREA *bp;
	off_t byte;

	byte = blk >> BITSHIFT;
	n = 1<<((unsigned)(blk & BITMASK));
	if(flg & 04) {
		p = freemap;
		blk = fmapblk;
	}
	else {
		p = blkmap;
		blk = 0;
	}
	if(p != NULL) {
		bp = NULL;
		p += (unsigned)byte;
	}
	else if((bp = getblk((BUFAREA *)NULL,blk+(byte>>BSHIFT))) == NULL)
		errexit("Fatal I/O error\n");
	else
		p = &bp->b_un.b_buf[(unsigned)(byte&BMASK)];
	switch(flg&03) {
		case 0:
			*p |= n;
			break;
		case 1:
			n &= *p;
			bp = NULL;
			break;
		case 2:
			*p &= ~n;
	}
	if(bp != NULL)
		dirty(bp);
	return(n);
}


dolncnt(val,flg)
short val;
{
	register short *sp;
	register BUFAREA *bp;

	if(lncntp != NULL) {
		bp = NULL;
		sp = &lncntp[inum];
	}
	else if((bp = getblk((BUFAREA *)NULL,(daddr_t)(lncntblk+(inum/SPERB)))) == NULL)
		errexit("Fatal I/O error\n");
	else
		sp = &bp->b_un.b_lnks[inum%SPERB];
	switch(flg) {
		case 0:
			*sp = val;
			break;
		case 1:
			bp = NULL;
			break;
		case 2:
			(*sp)--;
	}
	if(bp != NULL)
		dirty(bp);
	return(*sp);
}


BUFAREA *
getblk(bp,blk)
daddr_t blk;
register BUFAREA *bp;
{
	register struct filecntl *fcp;

	if(bp == NULL) {
		bp = search(blk);
		fcp = &sfile;
	}
	else
		fcp = &dfile;
	if(bp->b_bno == blk)
		return(bp);
	flush(fcp,bp);
	if(bread(fcp,bp->b_un.b_buf,blk,BSIZE) != NO) {
		bp->b_bno = blk;
		return(bp);
	}
	bp->b_bno = (daddr_t)-1;
	return(NULL);
}


flush(fcp,bp)
struct filecntl *fcp;
register BUFAREA *bp;
{
	if(bp->b_dirty) {
		bwrite(fcp,bp->b_un.b_buf,bp->b_bno,BSIZE);
	}
	bp->b_dirty = 0;
}


rwerr(s,blk)
char *s;
daddr_t blk;
{
	printf("\nCAN NOT %s: BLK %ld",s,blk);
	if(reply("CONTINUE") == NO)
		errexit("Program terminated\n");
}


sizechk(dp)
register DINODE *dp;
{
/*
	if (maxblk != howmany(dp->di_size, BSIZE))
		printf("POSSIBLE FILE SIZE ERROR I=%u (%ld,%ld)\n\n",inum, maxblk, howmany(dp->di_size,BSIZE));
*/
	if(DIR && (dp->di_size % sizeof(DIRECT)) != 0) {
		printf("DIRECTORY MISALIGNED I=%u\n\n",inum);
	}
}


ckfini()
{
	flush(&dfile,&fileblk);
	flush(&dfile,&sblk);
	flush(&dfile,&inoblk);
	close(dfile.rfdes);
	close(dfile.wfdes);
	close(sfile.rfdes);
	close(sfile.wfdes);
	if(rmscr) {
		unlink(scrfile);
	}
}


pinode()
{
	register DINODE *dp;
	register char *p;
	char uidbuf[200];
	char *ctime();

	printf(" I=%u ",inum);
	if((dp = ginode()) == NULL)
		return;
	printf(" OWNER=");
	if(getpw((int)dp->di_uid,uidbuf) == 0) {
		for(p = uidbuf; *p != ':'; p++);
		*p = 0;
		printf("%s ",uidbuf);
	}
	else {
		printf("%d ",dp->di_uid);
	}
	printf("MODE=%o\n",dp->di_mode);
	printf("SIZE=%ld ",dp->di_size);
	p = ctime(&dp->di_mtime);
	printf("MTIME=%12.12s %4.4s ",p+4,p+20);
}


copy(fp,tp,size)
register char *tp, *fp;
MEMSIZE size;
{
	while(size--)
		*tp++ = *fp++;
}


freechk()
{
	register daddr_t *ap;

	if(freeblk.df_nfree == 0)
		return;
	do {
		if(freeblk.df_nfree <= 0 || freeblk.df_nfree > NICFREE) {
			printf("BAD FREEBLK COUNT\n");
			fixfree = 1;
			return;
		}
		ap = &freeblk.df_free[freeblk.df_nfree];
		while(--ap > &freeblk.df_free[0]) {
			if(pass5(*ap) == STOP)
				return;
		}
		if(*ap == (daddr_t)0 || pass5(*ap) != KEEPON)
			return;
	} while(getblk(&fileblk,*ap) != NULL);
}


makefree()
{
	register i, cyl, step;
	int j;
	char flg[MAXCYL];
	short addr[MAXCYL];
	daddr_t blk, baseblk;

	superblk.s_nfree = 0;
	superblk.s_flock = 0;
	superblk.s_fmod = 0;
	superblk.s_tfree = 0;
	superblk.s_ninode = 0;
	superblk.s_ilock = 0;
	superblk.s_ronly = 0;
	if(cylsize == 0 || stepsize == 0) {
		step = superblk.s_dinfo[0];
		cyl = superblk.s_dinfo[1];
	}
	else {
		step = stepsize;
		cyl = cylsize;
	}
	if(step > cyl || step <= 0 || cyl <= 0 || cyl > MAXCYL) {
		error("Default free list spacing assumed\n");
		step = STEPSIZE;
		cyl = CYLSIZE;
	}
	superblk.s_dinfo[0] = step;
	superblk.s_dinfo[1] = cyl;
	clear(flg,sizeof(flg));
	i = 0;
	for(j = 0; j < cyl; j++) {
		while(flg[i])
			i = (i + 1) % cyl;
		addr[j] = i + 1;
		flg[i]++;
		i = (i + step) % cyl;
	}
	baseblk = (daddr_t)roundup(fmax,cyl);
	clear((char *)&freeblk,BSIZE);
	freeblk.df_nfree++;
	for( ; baseblk > 0; baseblk -= cyl)
		for(i = 0; i < cyl; i++) {
			blk = baseblk - addr[i];
			if(!outrange(blk) && !getbmap(blk)) {
				superblk.s_tfree++;
				if(freeblk.df_nfree >= NICFREE) {
					fbdirty();
					fileblk.b_bno = blk;
					flush(&dfile,&fileblk);
					clear((char *)&freeblk,BSIZE);
				}
				freeblk.df_free[freeblk.df_nfree] = blk;
				freeblk.df_nfree++;
			}
		}
	superblk.s_nfree = freeblk.df_nfree;
	for(i = 0; i < NICFREE; i++)
		superblk.s_free[i] = freeblk.df_free[i];
	sbdirty();
}


clear(p,cnt)
register char *p;
MEMSIZE cnt;
{
	while(cnt--)
		*p++ = 0;
}


BUFAREA *
search(blk)
daddr_t blk;
{
	register BUFAREA *pbp, *bp;

	for(bp = (BUFAREA *) &poolhead; bp->b_next; ) {
		pbp = bp;
		bp = pbp->b_next;
		if(bp->b_bno == blk)
			break;
	}
	pbp->b_next = bp->b_next;
	bp->b_next = poolhead;
	poolhead = bp;
	return(bp);
}


findino(dirp)
register DIRECT *dirp;
{
	register char *p1, *p2;

	if(dirp->d_ino == 0)
		return(KEEPON);
	for(p1 = dirp->d_name,p2 = srchname;*p2++ == *p1; p1++) {
		if(*p1 == 0 || p1 == &dirp->d_name[DIRSIZ-1]) {
			if(dirp->d_ino >= ROOTINO && dirp->d_ino <= imax)
				parentdir = dirp->d_ino;
			return(STOP);
		}
	}
	return(KEEPON);
}


mkentry(dirp)
register DIRECT *dirp;
{
	register ino_t in;
	register char *p;

	if(dirp->d_ino)
		return(KEEPON);
	dirp->d_ino = orphan;
	in = orphan;
	p = &dirp->d_name[7];
	*--p = 0;
	while(p > dirp->d_name) {
		*--p = (in % 10) + '0';
		in /= 10;
	}
	return(ALTERD|STOP);
}


chgdd(dirp)
register DIRECT *dirp;
{
	if(dirp->d_name[0] == '.' && dirp->d_name[1] == '.' &&
	dirp->d_name[2] == 0) {
		dirp->d_ino = lfdir;
		return(ALTERD|STOP);
	}
	return(KEEPON);
}


linkup()
{
	register DINODE *dp;
	register lostdir;
	register ino_t pdir;

	if((dp = ginode()) == NULL)
		return(NO);
	lostdir = DIR;
	pdir = parentdir;
	printf("UNREF %s ",lostdir ? "DIR" : "FILE");
	pinode();
	if(reply("RECONNECT") == NO)
		return(NO);
	orphan = inum;
	if(lfdir == 0) {
		inum = ROOTINO;
		if((dp = ginode()) == NULL) {
			inum = orphan;
			return(NO);
		}
		pfunc = findino;
		srchname = lfname;
		filsize = dp->di_size;
		parentdir = 0;
		ckinode(dp,DATA);
		inum = orphan;
		if((lfdir = parentdir) == 0) {
			printf("SORRY. NO lost+found DIRECTORY\n\n");
			return(NO);
		}
	}
	inum = lfdir;
	if((dp = ginode()) == NULL || !DIR || getstate() != FSTATE) {
		inum = orphan;
		printf("SORRY. NO lost+found DIRECTORY\n\n");
		return(NO);
	}
	if(dp->di_size & BMASK) {
		dp->di_size = roundup(dp->di_size,BSIZE);
		inodirty();
	}
	filsize = dp->di_size;
	inum = orphan;
	pfunc = mkentry;
	if((ckinode(dp,DATA) & ALTERD) == 0) {
		printf("SORRY. NO SPACE IN lost+found DIRECTORY\n\n");
		return(NO);
	}
	declncnt();
	if(lostdir) {
		pfunc = chgdd;
		dp = ginode();
		filsize = dp->di_size;
		ckinode(dp,DATA);
		inum = lfdir;
		if((dp = ginode()) != NULL) {
			dp->di_nlink++;
			inodirty();
			setlncnt(getlncnt()+1);
		}
		inum = orphan;
		printf("DIR I=%u CONNECTED. ",orphan);
		printf("PARENT WAS I=%u\n\n",pdir);
	}
	return(YES);
}


bread(fcp,buf,blk,size)
daddr_t blk;
register struct filecntl *fcp;
register size;
char *buf;
{
	if(lseek(fcp->rfdes,blk<<BSHIFT,0) < 0)
		rwerr("SEEK",blk);
	else if(read(fcp->rfdes,buf,size) == size)
		return(YES);
	rwerr("READ",blk);
	return(NO);
}


bwrite(fcp,buf,blk,size)
daddr_t blk;
register struct filecntl *fcp;
register size;
char *buf;
{
	if(fcp->wfdes < 0)
		return(NO);
	if(lseek(fcp->wfdes,blk<<BSHIFT,0) < 0)
		rwerr("SEEK",blk);
	else if(write(fcp->wfdes,buf,size) == size) {
		fcp->mod = 1;
		return(YES);
	}
	rwerr("WRITE",blk);
	return(NO);
}

catch()
{
	ckfini();
	exit(4);
}

ustat(x, s)
char *s;
{
	return(-1);
}

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-04 14:41 Noel Chiappa
  2023-03-04 14:49 ` KenUnix
  0 siblings, 1 reply; 37+ messages in thread
From: Noel Chiappa @ 2023-03-04 14:41 UTC (permalink / raw)
  To: tuhs

    > From: Clem Cole wrote:

    > It had more colorful name originally - fsck (pronounced as fisk BTW)
    > was finished. I suspect the fcheck name was a USG idea. 

I dunno. I don't think we at MIT wold have gratuitously changed the name to
'fcheck'; I rather think that was its original name - and we pretty
definitely got it from CMU. 'fsck' was definitely descended from 'fcheck'
(below).


    > From: Jonathan Gray

    >> (are 'fsck' and 'fcheck' the same program?)

    > https://www.tuhs.org/cgi-bin/utree.pl?file=V7addenda/fsck

Having looked the the source to both, it's quite clear that 'fcheck' is a
distant ancestor of 'fsck' (see below for thoughts on the connection(s)). The
latter has been _very_ extensively modified, but there are still some traces
of 'fcheck' left.

A lot of the changes are to increase the portability, and also to come into
compliance with the latest 'C' (e.g. function prototypes); others are just to
get rid of oddities in the original coding style. E.g.:

  unsigned
        dsize,
        fmin,
        fmax
  ;

Perfectly legal C, but nobody uses that style.


    > From: Jonathan Gray

    > fcheck is from Hal Pierson at Bell according to
    > https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/readme.txt

Hmm. "the major features that were added to UNIX by CB/UNIX ... Hal Person
(or Pierson?) also rewrote the original check disk command into something
that was useful by someone other than researchers."

I poked around in CB/UNIX, and found 'check(1M)':

  https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/cbunix_man1_01.pdf

(dated November 1979). Alas, the source isn't there, but it's clearly in the
fheck/fsck family. (CB/UNIX also has chkold(1M), which looks to me like it's
'icheck'.)

So now we have a question about the ancestry of 'check' and 'fcheck' - is one
an ancestor of the other, and if so, which - or are they independent
creations? Without the source, it's hard to be definitive, bur from the
messages (as given in the manual), they do seem related.

Clem's message of 3 Mar, 14:35 seems to indicate the the original was from
CMU, authored by Ted Kowalski; he also:

  https://wiki.tuhs.org/doku.php?id=anecdotes:clem_cole_student

says "Ted Kowalski shows up for his OYOC year in the EE dept after his summer
at Bell Labs ... He also brought his cool (but unfinished) program he had
started to write originally at U Mich - fsck". So maybe the CB/UNIX 'check' is
descended from a version that Ted left behind at Bell Labs?

Is anyone in touch with Hal Pierson? He could surely clear up these questions.

	Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-04  9:07 ` Jonathan Gray
@ 2023-03-04 11:19   ` KenUnix
  0 siblings, 0 replies; 37+ messages in thread
From: KenUnix @ 2023-03-04 11:19 UTC (permalink / raw)
  To: Jonathan Gray; +Cc: Noel Chiappa, tuhs

[-- Attachment #1: Type: text/plain, Size: 1692 bytes --]

After downloading fsck.c from v7addenda.tar.gz this happens:

w fsck.c
33044
q
# cc fsck.c
fsck.c:1441: s_dinfo undefined; func. makefree
fsck.c:1441: Illegal structure ref
fsck.c:1441: Incompatible structures
fsck.c:1442: Illegal structure ref
fsck.c:1442: Incompatible structures
fsck.c:1453: s_dinfo undefined; func. makefree
fsck.c:1453: Illegal structure ref
fsck.c:1453: Incompatible structures
fsck.c:1454: Illegal structure ref
fsck.c:1454: Incompatible structures

fsck.c lines of interest 1440-1455:

#define superblk sblk.b_un.b_fs

if(cylsize == 0 || stepsize == 0) {
step = superblk.s_dinfo[0];
cyl = superblk.s_dinfo[1];
}
else {
step = stepsize;
cyl = cylsize;
}
if(step > cyl || step <= 0 || cyl <= 0 || cyl > MAXCYL) {
error("Default free list spacing assumed\n");
step = STEPSIZE;
cyl = CYLSIZE;
}
superblk.s_dinfo[0] = step;
superblk.s_dinfo[1] = cyl;
clear(flg,sizeof(flg));

#define superblk sblk.b_un.b_fs

Ken


On Sat, Mar 4, 2023 at 4:07 AM Jonathan Gray <jsg@jsg.id.au> wrote:

> On Fri, Mar 03, 2023 at 01:22:00PM -0500, Noel Chiappa wrote:
> >     > From: Jonathan Gray
> >
> >     > That is close, but slightly different to the PWB fcheck.c
> >
> > Interesting. I wonder how 'fcheck' made it from CMU to Bell? Clem and I
> > discussed how it made it from CMU to MIT, and we think it was via Wayne
> > Gramlich, who'd been an undergrad at CMU, and then went to grad school
> at MIT.
>
> fcheck is from Hal Pierson at Bell according to
>
> https://wiki.tuhs.org/doku.php?id=misc:snippets:mert1
> https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/readme.txt
>


-- 
End of line
JOB TERMINATED

[-- Attachment #2: Type: text/html, Size: 2653 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 18:22 Noel Chiappa
                   ` (2 preceding siblings ...)
  2023-03-03 23:00 ` Jonathan Gray
@ 2023-03-04  9:07 ` Jonathan Gray
  2023-03-04 11:19   ` KenUnix
  3 siblings, 1 reply; 37+ messages in thread
From: Jonathan Gray @ 2023-03-04  9:07 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Fri, Mar 03, 2023 at 01:22:00PM -0500, Noel Chiappa wrote:
>     > From: Jonathan Gray
> 
>     > That is close, but slightly different to the PWB fcheck.c
> 
> Interesting. I wonder how 'fcheck' made it from CMU to Bell? Clem and I
> discussed how it made it from CMU to MIT, and we think it was via Wayne
> Gramlich, who'd been an undergrad at CMU, and then went to grad school at MIT.

fcheck is from Hal Pierson at Bell according to

https://wiki.tuhs.org/doku.php?id=misc:snippets:mert1
https://www.tuhs.org/Archive/Distributions/USDL/CB_Unix/readme.txt

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 19:35 ` Clem Cole
@ 2023-03-04  2:45   ` Jonathan Gray
  0 siblings, 0 replies; 37+ messages in thread
From: Jonathan Gray @ 2023-03-04  2:45 UTC (permalink / raw)
  To: Clem Cole; +Cc: Noel Chiappa, tuhs

On Fri, Mar 03, 2023 at 02:35:37PM -0500, Clem Cole wrote:
> 
> > Interesting. I wonder how 'fcheck' made it from CMU to Bell?
> 
> The late Ted Kowaski - the primary author. Undergrad EE UMICH (Bill Joy's
> roommate) and Grad EE at CMU (and my programming/lab partner originally in
> Dan Sieworick's grad RT course and Gordon Bell System Architecture
> courses). MTS and TSS had a disk scavenger from IBM for their common FS
> [which Ted has used at MICH and I had CMU].  icheck/ncheck/dcheck seemed
> less useful.
> A new program was started when he was an undergrad and never finished.
> 
> It had more colorful name originally - fsck (pronounced as fisk BTW) was
> finished.  I suspect the fcheck name was a USG idea.    The reason why many
> of the error messages are upper case is that was the IBM convention which
> both MTS and TSS used for system programs.

It is difficult to determine when fsck appeared in the USG releases.

fsck was perhaps present in USG Program Generic PG-1C300 Issue 3
(March 1977), as it was in the MERT Release 0 manual:
https://www.tuhs.org/Archive/Documentation/Manuals/MERT_Release_0/Unix%20Programmer%20Manual%20-%20UPM%20-%20White%20Tabs/System%20Programs%20-%20man8/fsck.8.pdf

"I would like to thank Larry A. Wehr for advice that lead to the first
version of fsck and Rick B. Brandt for adapting fsck to UNIX/TS."
T. J. Kowalski, FSCK - The UNIX/TS File System Check Program
included in System III manuals

'Credit for the various pieces involved goes to Ted Kowalski of CMU and
BTL, Mike Accetta of CMU, and George Goble of Purdue Univ. Kowalski
wrote the "fsck," file system check program, which does all that
icheck/dcheck did and more and also repairs errors that it finds. In the
Purdue V6 system Goble had added code to ensure that inodes and indirect
blocks on disk were always in a consistent state so that the worst that
could happen in a sudden halt or crash was that the file system may have
some dups in free, but never dups between files. Accetta enhanced these
and added a few of his own.

In the current Berkeley distribution (4BSD) all of these techniques are
provided as well as some additions.'

Bill Joy, A Crash-resistant UNIX file system
https://archive.org/details/login_january-1981/page/30/mode/2up

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 21:26   ` John Cowan
@ 2023-03-04  0:23     ` Chet Ramey
  0 siblings, 0 replies; 37+ messages in thread
From: Chet Ramey @ 2023-03-04  0:23 UTC (permalink / raw)
  To: John Cowan; +Cc: Noel Chiappa, tuhs

On 3/3/23 4:26 PM, John Cowan wrote:
> 
> 
> On Fri, Mar 3, 2023 at 2:25 PM Chet Ramey <chet.ramey@case.edu 
> <mailto:chet.ramey@case.edu>> wrote:
> 
>     A former CWRU president (very soon after the merger) used to tell freshmen
>     the same thing during his annual address to the incoming class.
> 
> 
> I remember being told that when I arrived at Case in 1976; sure enough, 
> within a year I was the one who had departed.  

That's Louis Toepfer. Also famous for the other line he was fond of:
"Learning is suffering."


> Two other things I remember from that speech were that Michelson was a 
> Casie and Morley was a Reservie,

Quite true. That distinction was more important back then, closer to the
merger. There were still "Casies" and "Reservies" when I went, but the
subsequent administrations have done a lot of work to unify the campus.

  and that (as the campus was completely
> covered with mud at the time), we were never to trust 100-year flood 
> estimates in the United States, as there was not enough evidence to go on, 
> and that in fact that was the third 100-year flood in Cleveland in the last 
> 16 years.

Doan Creek (buried and yet) still floods from time to time, most recently a
few years ago. It flooded the basement and parking garage of the building
where I work.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 18:22 Noel Chiappa
  2023-03-03 19:25 ` Chet Ramey
  2023-03-03 19:35 ` Clem Cole
@ 2023-03-03 23:00 ` Jonathan Gray
  2023-03-04  9:07 ` Jonathan Gray
  3 siblings, 0 replies; 37+ messages in thread
From: Jonathan Gray @ 2023-03-03 23:00 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Fri, Mar 03, 2023 at 01:22:00PM -0500, Noel Chiappa wrote:
>     > From: KenUnix
> 
>     > So is it safe to say there is no fsck or similar for v7?
> 
> There was a version of 'fcheck' (are 'fsck' and 'fcheck' the same program?)
> for V7, but I don't know if it's available. It would be really easy to
> convert the 'fcheck.c' that I put up to a V7 version; the V6 and V7 file
> systems are almost identical, except for the block size, I think.

https://www.tuhs.org/Archive/Distributions/Research/v7addenda.tar.gz
https://www.tuhs.org/cgi-bin/utree.pl?file=V7addenda/fsck

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 19:25 ` Chet Ramey
@ 2023-03-03 21:26   ` John Cowan
  2023-03-04  0:23     ` Chet Ramey
  0 siblings, 1 reply; 37+ messages in thread
From: John Cowan @ 2023-03-03 21:26 UTC (permalink / raw)
  To: chet.ramey; +Cc: Noel Chiappa, tuhs

[-- Attachment #1: Type: text/plain, Size: 1126 bytes --]

On Fri, Mar 3, 2023 at 2:25 PM Chet Ramey <chet.ramey@case.edu> wrote:


> A former CWRU president (very soon after the merger) used to tell freshmen
> the same thing during his annual address to the incoming class.
>

I remember being told that when I arrived at Case in 1976; sure enough,
within a year I was the one who had departed.  I didn't belong there
anyway.  I wound up, for family reasons, at CCNY and signed up for the
Communications and Mass Media program, but I haunted the college bookstore
and picked up the computer-science books (this was back when casuals could
actually afford to buy them; one I got then was the Elements of Programming
Style).  I have never allowed schooling to interfere with my education.

Two other things I remember from that speech were that Michelson was a
Casie and Morley was a Reservie, and that (as the campus was completely
covered with mud at the time), we were never to trust 100-year flood
estimates in the United States, as there was not enough evidence to go on,
and that in fact that was the third 100-year flood in Cleveland in the last
16 years.

[-- Attachment #2: Type: text/html, Size: 1860 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 18:22 Noel Chiappa
  2023-03-03 19:25 ` Chet Ramey
@ 2023-03-03 19:35 ` Clem Cole
  2023-03-04  2:45   ` Jonathan Gray
  2023-03-03 23:00 ` Jonathan Gray
  2023-03-04  9:07 ` Jonathan Gray
  3 siblings, 1 reply; 37+ messages in thread
From: Clem Cole @ 2023-03-03 19:35 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

[-- Attachment #1: Type: text/plain, Size: 3097 bytes --]

On Fri, Mar 3, 2023 at 1:22 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:

>     > From: KenUnix
>
>     > So is it safe to say there is no fsck or similar for v7?
>
Last fall, I recovered the original CMU sources to both. And I told Warren
after I clean things up, I'll push them to TUHS both source and binaries
but I have a number of other projects ahead of that.


>
> Yes, but that does't talk about '_end' not being defined if there
> are missing externals, either!

From V7: https://man.cat-v.org/unix_7th/1/ld     <--- this should only be a
URL - let me know if Chrome/gmail is peeing on it again

The symbols `_etext', `_edata' and `_end' (`etext', `edata'
          and `end' in C) are reserved, and if referred to, are set to
          the first location above the program, the first location
          above initialized data, and the first location above all
          data respectively.  It is erroneous to define these symbols.

Then check the section 3 man page: https://man.cat-v.org/unix_7th/3/end
which describes them in more detail.



> Interesting. I wonder how 'fcheck' made it from CMU to Bell?

The late Ted Kowaski - the primary author. Undergrad EE UMICH (Bill Joy's
roommate) and Grad EE at CMU (and my programming/lab partner originally in
Dan Sieworick's grad RT course and Gordon Bell System Architecture
courses). MTS and TSS had a disk scavenger from IBM for their common FS
[which Ted has used at MICH and I had CMU].  icheck/ncheck/dcheck seemed
less useful.
A new program was started when he was an undergrad and never finished.

It had more colorful name originally - fsck (pronounced as fisk BTW) was
finished.  I suspect the fcheck name was a USG idea.    The reason why many
of the error messages are upper case is that was the IBM convention which
both MTS and TSS used for system programs.


> I'm pretty sure the reason we liked it was not any auto-repair
> capabilities,
> but ISTR it was somewhat faster than icheck/dcheck. (Interesting that they
> were
> separate programs in V6; V5 seems to have only had check
>
CMU only ran V5 for a very short time and never in the EE Dept.  I only
knew of one system that ever ran it.  We were a hacked V6 most of the time
I was there.  V7 showed up at the end, although parts of V7 and PWB leaked
to us via different students who worked at Bell (that story was similar at
many sites).


>
> which contained the functionality of both. I wonder why they were split?
> Space?
>
Table space to support larger disk was always a huge problem. Since we
mostly ran UNIX on 11/40 class systems, it had to be able to run on non-I/D
(45 class) machines. A lot of creativity was used to keep it small.  It was
fine for RK05s and RP03s but Ted's temp space hack was done when the first
RP04-like disk showed up - it was an IBM disk on an aftermarket Unibus
controller made to look like an RP in EE and then Dan Klein and I got the
very low serial # RK07 at Mellon Institute and that was my first Unix
driver which we hacked together one weekend.
ᐧ

[-- Attachment #2: Type: text/html, Size: 6078 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-03 18:22 Noel Chiappa
@ 2023-03-03 19:25 ` Chet Ramey
  2023-03-03 21:26   ` John Cowan
  2023-03-03 19:35 ` Clem Cole
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 37+ messages in thread
From: Chet Ramey @ 2023-03-03 19:25 UTC (permalink / raw)
  To: Noel Chiappa, tuhs

On 3/3/23 1:22 PM, Noel Chiappa wrote:

> Hey, this _is_ the school that used to tell incoming freshpeople, at the
> welcoming picnic 'look at the person to your left, and to your right; at
> graduation, one of you won't be here'. I don't remeber if they said the same
> thing at mine, or if the story had just been passed down from class to class.

A former CWRU president (very soon after the merger) used to tell freshmen
the same thing during his annual address to the incoming class.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-03 18:22 Noel Chiappa
  2023-03-03 19:25 ` Chet Ramey
                   ` (3 more replies)
  0 siblings, 4 replies; 37+ messages in thread
From: Noel Chiappa @ 2023-03-03 18:22 UTC (permalink / raw)
  To: tuhs

    > From: KenUnix

    > So is it safe to say there is no fsck or similar for v7?

There was a version of 'fcheck' (are 'fsck' and 'fcheck' the same program?)
for V7, but I don't know if it's available. It would be really easy to
convert the 'fcheck.c' that I put up to a V7 version; the V6 and V7 file
systems are almost identical, except for the block size, I think.


    > From: Dan Cross

    > I believe you posted a link to end(3) here back in 2018

Yes, but that does't talk about '_end' not being defined if there
are missing externals, either! All it says is:

  "Values are given to these symbols by the link editor 'ld' when, and only
  when, they are referred to but not defined in the set of programs loaded."

Now that I think about it, I have this vague memory we had to look at the
source for 'ld.c' to verify what was going on!


    > From: Jonathan Gray

    > That is close, but slightly different to the PWB fcheck.c

Interesting. I wonder how 'fcheck' made it from CMU to Bell? Clem and I
discussed how it made it from CMU to MIT, and we think it was via Wayne
Gramlich, who'd been an undergrad at CMU, and then went to grad school at MIT.

I'm pretty sure the reason we liked it was not any auto-repair capabilities,
but ISTR it was somewhat faster than icheck/dcheck. (Interesting that they were
separate programs in V6; V5 seems to have only had check:

  http://squoze.net/UNIX/v5man/man8/check
  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V5/usr/source/s1/check.c

which contained the functionality of both. I wonder why they were split?
Space?)


    > From: Rich Salz

    > But the amazing point was it worked regardless of bit order.

I forgot to mention thast, but yes, its input was the number in bit-serial
form. I suspect there's a connection between the property he mentioned, and
the fact that the grad student could design something which would work with
binary numbers fed in from either end, but I can't bring myself to devote the
brain cells to figure it out.


    > From: John Cowan

    > I didn't know that one was done at MIT.

Yes; see:

  https://www.hactrn.net/sra/alice/alice.intro

There's a really funny story at the end of that about the real Ann Marie
Finn. In Rob's version, she took the role of KAREN in the earlier one. That
would be Karen Prendergast, Patrick Winston's admin; why we used her I don't
know, since I didn't really know her, but I guess she had a reputation as a bit of
a 'tough cookie'.

    >> I think that the person fails their oral. I have no idea if it's a
    >> true story.

    > That's vicious.

Hey, this _is_ the school that used to tell incoming freshpeople, at the
welcoming picnic 'look at the person to your left, and to your right; at
graduation, one of you won't be here'. I don't remeber if they said the same
thing at mine, or if the story had just been passed down from class to class.

	Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  7:56       ` John Cowan
@ 2023-03-02  8:53         ` Steve Nickolas
  0 siblings, 0 replies; 37+ messages in thread
From: Steve Nickolas @ 2023-03-02  8:53 UTC (permalink / raw)
  To: John Cowan; +Cc: The Eunuchs Hysterical Society

[-- Attachment #1: Type: text/plain, Size: 692 bytes --]

On Thu, 2 Mar 2023, John Cowan wrote:

> On Wed, Mar 1, 2023 at 10:05 PM Dave Horsfall <dave@horsfall.org> wrote:
>
>> Boy, that takes me back!  And I can't believe that I used American
>> spelling such as "utilizing" etc...
>
> Perhaps whoever typed it was an American or Canadian, or conceivably an
> Oxonian.  Typists routinely corrected, or "corrected", authors' spellings
> in those days.

Which reminds me of some bibles I have that were jointly produced by 
Cambridge University Press and Trinitarian Bible Society.  Any of the 
stuff in there that came from Cambridge would say "Authorized" etc., while 
if it came from Trinitarian, it would say "Authorised".

-uso.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  3:05     ` Dave Horsfall
  2023-03-02  7:56       ` John Cowan
@ 2023-03-02  8:01       ` Jonathan Gray
  1 sibling, 0 replies; 37+ messages in thread
From: Jonathan Gray @ 2023-03-02  8:01 UTC (permalink / raw)
  To: Dave Horsfall; +Cc: tuhs

On Thu, Mar 02, 2023 at 02:05:45PM +1100, Dave Horsfall wrote:
> On Thu, 2 Mar 2023, Jonathan Gray wrote:
> 
> > > I could've sworn that I wrote a paper for AUUGN on that very thing, 
> > > but I'm damned if I can find it...  Anyone here remember it?  It 
> > > explained exactly how to use icheck/dcheck/ncheck/clri on a creamed 
> > > file system (and no, I no longer have the document).
> > 
> > "A Proposal for a Simple Bad Block Utility"
> > page 8 of
> > https://www.tuhs.org/Archive/Documentation/AUUGN/AUUGN-V03.5.pdf
> 
> Boy, that takes me back!  And I can't believe that I used American 
> spelling such as "utilizing" etc...
> 
> Anyway, that's not the one.  It occurred to me that I wrote it before 
> AUUGN was published, as all that we had until then were just informal 
> notes.
> 
> Oh well, more CSU history lost (along with our version of V6 which was 
> almost but not quite V7) :-{

part of it is in

https://www.tuhs.org/Archive/Applications/Spencer_Tapes/unsw3.tar.gz
usr/source/csu/

"Software from Computing Services Unit"

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  3:05     ` Dave Horsfall
@ 2023-03-02  7:56       ` John Cowan
  2023-03-02  8:53         ` Steve Nickolas
  2023-03-02  8:01       ` Jonathan Gray
  1 sibling, 1 reply; 37+ messages in thread
From: John Cowan @ 2023-03-02  7:56 UTC (permalink / raw)
  To: Dave Horsfall; +Cc: The Eunuchs Hysterical Society

[-- Attachment #1: Type: text/plain, Size: 360 bytes --]

On Wed, Mar 1, 2023 at 10:05 PM Dave Horsfall <dave@horsfall.org> wrote:



> Boy, that takes me back!  And I can't believe that I used American
> spelling such as "utilizing" etc...
>

Perhaps whoever typed it was an American or Canadian, or conceivably an
Oxonian.  Typists routinely corrected, or "corrected", authors' spellings
in those days.

[-- Attachment #2: Type: text/html, Size: 963 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 20:52 ` Dave Horsfall
  2023-03-02  1:46   ` Jonathan Gray
@ 2023-03-02  7:34   ` arnold
  1 sibling, 0 replies; 37+ messages in thread
From: arnold @ 2023-03-02  7:34 UTC (permalink / raw)
  To: tuhs, dave

Dave Horsfall <dave@horsfall.org> wrote:

> On Wed, 1 Mar 2023, Noel Chiappa wrote:
>
> > > I am having a problem clearing a dup inode.
> > 
> > V6 had almost no tools for automagically fixing file system corruption. 
> > To do it, you need to i) understand how the FS works (see:
>
> I could've sworn that I wrote a paper for AUUGN on that very thing, but 
> I'm damned if I can find it...  Anyone here remember it?  It explained 
> exactly how to use icheck/dcheck/ncheck/clri on a creamed file system (and 
> no, I no longer have the document).
>
> -- Dave

So Dave, did you clri the wrong inode such that your lost the paper? :-) :-)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 21:29 Noel Chiappa
                   ` (2 preceding siblings ...)
  2023-03-01 22:15 ` Jon Forrest
@ 2023-03-02  4:16 ` Jonathan Gray
  3 siblings, 0 replies; 37+ messages in thread
From: Jonathan Gray @ 2023-03-02  4:16 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Wed, Mar 01, 2023 at 04:29:16PM -0500, Noel Chiappa wrote:
>     > I'm not sure if 'fsck' would fix these
> 
> Turns out it was called 'fcheck' when we had it.
> 
>     > I have a V6 one
> 
> I'd already put it on my Web site, here:
> 
>   http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c
> 
> if anyone wants it.

That is close, but slightly different to the PWB fcheck.c
https://www.tuhs.org/cgi-bin/utree.pl?file=PWB1/sys/source/s8/fcheck.c

UNSW also had

/*
 *	chk: fast combination of icheck+dcheck
 *
 *	Original from Vrije Universiteit, Amsterdam.
 *	Modified by Kevin Hill, University of NSW.
 */ 

https://www.tuhs.org/cgi-bin/utree.pl?file=AUSAM/source/S/chk.c

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  1:46   ` Jonathan Gray
@ 2023-03-02  3:05     ` Dave Horsfall
  2023-03-02  7:56       ` John Cowan
  2023-03-02  8:01       ` Jonathan Gray
  0 siblings, 2 replies; 37+ messages in thread
From: Dave Horsfall @ 2023-03-02  3:05 UTC (permalink / raw)
  To: The Eunuchs Hysterical Society

On Thu, 2 Mar 2023, Jonathan Gray wrote:

> > I could've sworn that I wrote a paper for AUUGN on that very thing, 
> > but I'm damned if I can find it...  Anyone here remember it?  It 
> > explained exactly how to use icheck/dcheck/ncheck/clri on a creamed 
> > file system (and no, I no longer have the document).
> 
> "A Proposal for a Simple Bad Block Utility"
> page 8 of
> https://www.tuhs.org/Archive/Documentation/AUUGN/AUUGN-V03.5.pdf

Boy, that takes me back!  And I can't believe that I used American 
spelling such as "utilizing" etc...

Anyway, that's not the one.  It occurred to me that I wrote it before 
AUUGN was published, as all that we had until then were just informal 
notes.

Oh well, more CSU history lost (along with our version of V6 which was 
almost but not quite V7) :-{

PS: I never did get to write FLAW...

-- Dave

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-02  1:59 Noel Chiappa
@ 2023-03-02  2:11 ` Dan Cross
  0 siblings, 0 replies; 37+ messages in thread
From: Dan Cross @ 2023-03-02  2:11 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Wed, Mar 1, 2023 at 8:59 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:
>     >> _end
>
>     > They are all in the V6 library.
>
> Oops, not _end. In the V6 linker, "_end" is not defined if there are still
> undefined symbols at the end of the linking run.
>
> I remember finding this in some obscure place in the V6 documents; it's not
> in 'ld(I)'. Anyone remember where it's discussed?

I believe you posted a link to end(3) here back in 2018:
http://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man3/end.3

        - Dan C.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-02  1:59 Noel Chiappa
  2023-03-02  2:11 ` Dan Cross
  0 siblings, 1 reply; 37+ messages in thread
From: Noel Chiappa @ 2023-03-02  1:59 UTC (permalink / raw)
  To: tuhs; +Cc: jnc

    >> _end

    > They are all in the V6 library.

Oops, not _end. In the V6 linker, "_end" is not defined if there are still
undefined symbols at the end of the linking run.

I remember finding this in some obscure place in the V6 documents; it's not
in 'ld(I)'. Anyone remember where it's discussed?

	Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 20:52 ` Dave Horsfall
@ 2023-03-02  1:46   ` Jonathan Gray
  2023-03-02  3:05     ` Dave Horsfall
  2023-03-02  7:34   ` arnold
  1 sibling, 1 reply; 37+ messages in thread
From: Jonathan Gray @ 2023-03-02  1:46 UTC (permalink / raw)
  To: Dave Horsfall; +Cc: tuhs

On Thu, Mar 02, 2023 at 07:52:02AM +1100, Dave Horsfall wrote:
> On Wed, 1 Mar 2023, Noel Chiappa wrote:
> 
> > > I am having a problem clearing a dup inode.
> > 
> > V6 had almost no tools for automagically fixing file system corruption. 
> > To do it, you need to i) understand how the FS works (see:
> 
> I could've sworn that I wrote a paper for AUUGN on that very thing, but 
> I'm damned if I can find it...  Anyone here remember it?  It explained 
> exactly how to use icheck/dcheck/ncheck/clri on a creamed file system (and 
> no, I no longer have the document).
> 
> -- Dave

"A Proposal for a Simple Bad Block Utility"
page 8 of
https://www.tuhs.org/Archive/Documentation/AUUGN/AUUGN-V03.5.pdf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 21:29 Noel Chiappa
  2023-03-01 21:54 ` KenUnix
  2023-03-01 21:55 ` John Cowan
@ 2023-03-01 22:15 ` Jon Forrest
  2023-03-02  4:16 ` Jonathan Gray
  3 siblings, 0 replies; 37+ messages in thread
From: Jon Forrest @ 2023-03-01 22:15 UTC (permalink / raw)
  To: tuhs



On 3/1/2023 1:29 PM, Noel Chiappa wrote:

> Although I like the old story about the person at their oral exam and
> the Coke bottle in the window.

What Coke bottle?

Jon


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 21:29 Noel Chiappa
  2023-03-01 21:54 ` KenUnix
@ 2023-03-01 21:55 ` John Cowan
  2023-03-01 22:15 ` Jon Forrest
  2023-03-02  4:16 ` Jonathan Gray
  3 siblings, 0 replies; 37+ messages in thread
From: John Cowan @ 2023-03-01 21:55 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

On Wed, Mar 1, 2023 at 4:29 PM Noel Chiappa



> You may sit with Arlo Guthrie on the 'Windows user' bench. :-)
>

http://vrici.lojban.org/~cowan/alice_flame.txt

This is AFAIK the only parody ever to appear on Arlo's own site (it is no
longer there).  It was an update/rewrite of the MIT version.

> Although I like the old story about the person at their oral exam and
> the Coke bottle in the window.
>

Details?

[-- Attachment #2: Type: text/html, Size: 1584 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 21:29 Noel Chiappa
@ 2023-03-01 21:54 ` KenUnix
  2023-03-01 21:55 ` John Cowan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 37+ messages in thread
From: KenUnix @ 2023-03-01 21:54 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

[-- Attachment #1: Type: text/plain, Size: 1450 bytes --]

Noel,

Downloaded your fsck.c to play with but things are missing:

# cc fsck.c
Undefined:
_setexit
_reset
_seek
_alloc
_end

Is there a makefile?

Yes, I am trying to compile it on Unix v7.

Ken

On Wed, Mar 1, 2023 at 4:29 PM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:

>     > I'm not sure if 'fsck' would fix these
>
> Turns out it was called 'fcheck' when we had it.
>
>     > I have a V6 one
>
> I'd already put it on my Web site, here:
>
>   http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c
>
> if anyone wants it.
>
>
>     > From: "Ron Natalie"
>
>     > You had adb?
>
> Yeah, MIT had a lot of stuff that 'fell off the back of a truck' (including
> things like the circuit design tools, etc). Well, having an undergrad who
> was
> in the famous Boy Scout troop at Bell helped... :-)
>
>
>     > From: KenUnix <ken.unix.guy@gmail.com>
>
>     > What I finally did was restore the ".disk" files from a previous
> backup
>
> You may sit with Arlo Guthrie on the 'Windows user' bench. :-)
>
>
>     > From: "Theodore Ts'o"
>
>     > some have argued that if someone doesn't do backups of their research
>     > data, maybe they don't *deserve* to get their Ph.D. :-)
>
> 'Think of it as evolution in action.'
>
> Although I like the old story about the person at their oral exam and
> the Coke bottle in the window.
>
>         Noel
>


-- 
End of line
JOB TERMINATED

[-- Attachment #2: Type: text/html, Size: 2401 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-01 21:29 Noel Chiappa
  2023-03-01 21:54 ` KenUnix
                   ` (3 more replies)
  0 siblings, 4 replies; 37+ messages in thread
From: Noel Chiappa @ 2023-03-01 21:29 UTC (permalink / raw)
  To: tuhs; +Cc: jnc

    > I'm not sure if 'fsck' would fix these

Turns out it was called 'fcheck' when we had it.

    > I have a V6 one

I'd already put it on my Web site, here:

  http://ana-3.lcs.mit.edu/~jnc/tech/unix/s1/fcheck.c

if anyone wants it.


    > From: "Ron Natalie"

    > You had adb?

Yeah, MIT had a lot of stuff that 'fell off the back of a truck' (including
things like the circuit design tools, etc). Well, having an undergrad who was
in the famous Boy Scout troop at Bell helped... :-)


    > From: KenUnix <ken.unix.guy@gmail.com>

    > What I finally did was restore the ".disk" files from a previous backup

You may sit with Arlo Guthrie on the 'Windows user' bench. :-)


    > From: "Theodore Ts'o"

    > some have argued that if someone doesn't do backups of their research
    > data, maybe they don't *deserve* to get their Ph.D. :-)

'Think of it as evolution in action.'

Although I like the old story about the person at their oral exam and
the Coke bottle in the window.

	Noel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 15:09 Noel Chiappa
  2023-03-01 16:18 ` Ron Natalie
  2023-03-01 16:57 ` Theodore Ts'o
@ 2023-03-01 20:52 ` Dave Horsfall
  2023-03-02  1:46   ` Jonathan Gray
  2023-03-02  7:34   ` arnold
  2 siblings, 2 replies; 37+ messages in thread
From: Dave Horsfall @ 2023-03-01 20:52 UTC (permalink / raw)
  To: The Eunuchs Hysterical Society

On Wed, 1 Mar 2023, Noel Chiappa wrote:

> > I am having a problem clearing a dup inode.
> 
> V6 had almost no tools for automagically fixing file system corruption. 
> To do it, you need to i) understand how the FS works (see:

I could've sworn that I wrote a paper for AUUGN on that very thing, but 
I'm damned if I can find it...  Anyone here remember it?  It explained 
exactly how to use icheck/dcheck/ncheck/clri on a creamed file system (and 
no, I no longer have the document).

-- Dave

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 15:09 Noel Chiappa
  2023-03-01 16:18 ` Ron Natalie
@ 2023-03-01 16:57 ` Theodore Ts'o
  2023-03-01 20:52 ` Dave Horsfall
  2 siblings, 0 replies; 37+ messages in thread
From: Theodore Ts'o @ 2023-03-01 16:57 UTC (permalink / raw)
  To: Noel Chiappa; +Cc: tuhs

On Wed, Mar 01, 2023 at 10:09:05AM -0500, Noel Chiappa wrote:
> To do it, you need to i) understand how the FS works (see:
> 
>   https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man5/fs.5
> 
> but it's pretty simple); ii) understand what the few tools (dcheck; icheck;
> clri) do; iii) dive in.

In honor of dcheck, icheck, and clri, when I creating debugfs(8) for
ext2/ext3/ext4 file system, I implemented the dcheck, icheck, and clri
commands.

I've been known to use them (and other debugfs commands) from time to
time when someone needs emergency data recovery (say, someone who has
ten years of Ph.D. research without ever doing backups, and then the
file system get scrambled --- although some have argued that if
someone doesn't do backups of their research data, maybe they don't
*deserve* to get their Ph.D.  :-)

						- Ted

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 16:18 ` Ron Natalie
@ 2023-03-01 16:45   ` KenUnix
  0 siblings, 0 replies; 37+ messages in thread
From: KenUnix @ 2023-03-01 16:45 UTC (permalink / raw)
  To: Ron Natalie; +Cc: Noel Chiappa, tuhs

[-- Attachment #1: Type: text/plain, Size: 2052 bytes --]

Thanks for all your suggestions.

What I finally did was restore the ".disk" files from a previous backup
'tar -xf ~/research-backups/backup-mu-0228.tar'
under Linux then restored my backup copies of files using 'tar x0
backup.tap' under Unix v7.

All is well now. Thanks
Ken


On Wed, Mar 1, 2023 at 11:19 AM Ron Natalie <ron@ronnatalie.com> wrote:

> You had adb?    They hadn’t even released that when we were fixing
> things up.    If we had a mountable disk that got too corrupt to fix
> using the tools, we usually wrote our own and fixed the disk (all our
> packs in those days were pretty much RK05s) from a running sytsem.
>
> It was reqiured before you could come on the operations staff at my
> college to be able to be quizzed on just how the (then version 6)
> filesystem was layed out and what the possible corruptions were and how
> to fix them.
>
> The original V6 filesystem was pretty ugly in that it wasn’t careful in
> even trying to do operations in the right order so as not to lead to
> hideous corruptions (duplicated blocks etc…).   One of our summer
> projects at the BRL when we were interning up there was that one of us
> (not me) was to write an automatic disk fixer (I had a different
> project).   Bob never got too far with that.
>
> Clri was especially problematic as a tool.   If you wanted to zap a node
> that was a 0..0 (i.e., with a zero reference count AND not in any
> directory referneces), it would irreverably write zeros over all of it.
>    We changed it to “clam” which only zonked the mode bits which if you
> did it to the wrong inode, you could usually get back to some working
> state.
>
> Running icheck and dcheck were standard on reboots.   ncheck was pretty
> darned slow and we used it mostly for hunting down file names for things
> we knew were corrupted and relinking chunks of the filesystem that got
> detached from the root.
>
> The world changed when we got better file system code and fsck.
>
>

-- 
End of line
JOB TERMINATED

[-- Attachment #2: Type: text/html, Size: 2674 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
  2023-03-01 15:09 Noel Chiappa
@ 2023-03-01 16:18 ` Ron Natalie
  2023-03-01 16:45   ` KenUnix
  2023-03-01 16:57 ` Theodore Ts'o
  2023-03-01 20:52 ` Dave Horsfall
  2 siblings, 1 reply; 37+ messages in thread
From: Ron Natalie @ 2023-03-01 16:18 UTC (permalink / raw)
  To: Noel Chiappa, tuhs; +Cc: jnc

You had adb?    They hadn’t even released that when we were fixing 
things up.    If we had a mountable disk that got too corrupt to fix 
using the tools, we usually wrote our own and fixed the disk (all our 
packs in those days were pretty much RK05s) from a running sytsem.

It was reqiured before you could come on the operations staff at my 
college to be able to be quizzed on just how the (then version 6) 
filesystem was layed out and what the possible corruptions were and how 
to fix them.

The original V6 filesystem was pretty ugly in that it wasn’t careful in 
even trying to do operations in the right order so as not to lead to 
hideous corruptions (duplicated blocks etc…).   One of our summer 
projects at the BRL when we were interning up there was that one of us 
(not me) was to write an automatic disk fixer (I had a different 
project).   Bob never got too far with that.

Clri was especially problematic as a tool.   If you wanted to zap a node 
that was a 0..0 (i.e., with a zero reference count AND not in any 
directory referneces), it would irreverably write zeros over all of it.  
   We changed it to “clam” which only zonked the mode bits which if you 
did it to the wrong inode, you could usually get back to some working 
state.

Running icheck and dcheck were standard on reboots.   ncheck was pretty 
darned slow and we used it mostly for hunting down file names for things 
we knew were corrupted and relinking chunks of the filesystem that got 
detached from the root.

The world changed when we got better file system code and fsck.


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [TUHS] Re: Unix v7 icheck dup problem
@ 2023-03-01 15:09 Noel Chiappa
  2023-03-01 16:18 ` Ron Natalie
                   ` (2 more replies)
  0 siblings, 3 replies; 37+ messages in thread
From: Noel Chiappa @ 2023-03-01 15:09 UTC (permalink / raw)
  To: tuhs; +Cc: jnc

    > I am having a problem clearing a dup inode.

V6 had almost no tools for automagically fixing file system corruption.
To do it, you need to i) understand how the FS works (see:

  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man5/fs.5

but it's pretty simple); ii) understand what the few tools (dcheck; icheck;
clri) do; iii) dive in.

I recall I used to use 'adb' a lot, to manually patch things when there was a
problem, so you'll want to study up on the 'db' syntax (no 'adb' in vanilla
V6, but for this, they are basically equivalent):

 https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man1/db.1

You'll have to use the non-raw version of the device (the raw version can only
read/write complete blocks), and then judiciously use 'sync' to flush the
updated blocks out to the 'physical' disk. (There are some corner cases where
data is stored elsewhere, such as when one is patching the inode of an open
file, but I'm going to ignore them.)


    > # icheck -s /dev/rp0

'icheck -s' only rebuilds the free list; it doesn't help with any other error
(e.g. a block being assigned to two different files).

    > 4244 dup; inode=323

Which is probably what is happening here. 'icheck':

  https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man8/icheck.8

is not telling you what _else_ is using that block, because it has already
forgotten that by the time it discovers this second claimant (it only keeps a
bit array of 'used' blocks).

    > # icheck -b 323 /dev/rp0

Err, you wanted to say 'icheck -b 4244' to find out who else was using block
4244.


I'm not sure if 'fsck' would fix these; I have a V6 one, if anyone wants it.

The 'easy' way to fix this is i) copy the second file to somewhere else, ii)
delete the original, iii) re-build the free list (because the duplicate block
will now be in both the first file, and the free list), iv) examine both files,
and see which one has the smashed contents.

I'll turn this into a 'Fixing damaged V5/V6 file systems' article on the
CHWiki.

	   Noel


^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2023-03-07  2:05 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-02  1:36 [TUHS] Re: Unix v7 icheck dup problem Noel Chiappa
2023-03-02  1:56 ` John Cowan
2023-03-02  6:41   ` Lars Brinkhoff
2023-03-02  2:12 ` Bakul Shah
2023-03-02  2:46   ` Rich Salz
  -- strict thread matches above, loose matches on Subject: below --
2023-03-06  8:14 Noel Chiappa
2023-03-06  8:58 ` Jonathan Gray
2023-03-07  2:05   ` Kenneth Goodwin
2023-03-04 14:41 Noel Chiappa
2023-03-04 14:49 ` KenUnix
2023-03-03 18:22 Noel Chiappa
2023-03-03 19:25 ` Chet Ramey
2023-03-03 21:26   ` John Cowan
2023-03-04  0:23     ` Chet Ramey
2023-03-03 19:35 ` Clem Cole
2023-03-04  2:45   ` Jonathan Gray
2023-03-03 23:00 ` Jonathan Gray
2023-03-04  9:07 ` Jonathan Gray
2023-03-04 11:19   ` KenUnix
2023-03-02  1:59 Noel Chiappa
2023-03-02  2:11 ` Dan Cross
2023-03-01 21:29 Noel Chiappa
2023-03-01 21:54 ` KenUnix
2023-03-01 21:55 ` John Cowan
2023-03-01 22:15 ` Jon Forrest
2023-03-02  4:16 ` Jonathan Gray
2023-03-01 15:09 Noel Chiappa
2023-03-01 16:18 ` Ron Natalie
2023-03-01 16:45   ` KenUnix
2023-03-01 16:57 ` Theodore Ts'o
2023-03-01 20:52 ` Dave Horsfall
2023-03-02  1:46   ` Jonathan Gray
2023-03-02  3:05     ` Dave Horsfall
2023-03-02  7:56       ` John Cowan
2023-03-02  8:53         ` Steve Nickolas
2023-03-02  8:01       ` Jonathan Gray
2023-03-02  7:34   ` arnold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).