Re: fsck_ffs patch testers wanted

From: Don Lewis <truckman_at_FreeBSD.org>
Date: Thu, 30 Sep 2004 21:07:01 -0700 (PDT)
On 30 Sep, Marc G. Fournier wrote:
> 
> Would you be willing to post a 4.x version of this, or send me one, that I 
> can test, since I'm the one that seems lucky to get the "glacially slow" 
> fsck's :(

I was planning on posting a 4.x version sometime after I did the commit
to -CURRENT and it had time to get well exercised by the masses.  My
plan is to allow about a month of testing between the commit to -CURRENT
and the MFC.

> Also, some sort of "what I should be watching for" would be nice, if 
> anything ... I've got my remote techs "trained" so that they can get me 
> into single user mode so that I can watch fsck using ctl-t, so I can 
> install this as a seperate fsck and manually test it as required ...

Things to watch out for are fsck going berzerk and deleting all your
files.  The behaviour should be the same as the unpatched version of
fsck other than the worst case time it takes to get through pass 4.

I just cranked out the 4.x patch below.  I've only given it some light
testing, mostly just running versions of fsck with and without the patch
in read-only mode (-n option) on the same file system and comparing the
fsck output.  I've done this on a clean file system, and one with some
minor inconsistencies.

I'll repost this patch to stable_at_ if no problems show up after the
commit to -CURRENT.


Index: sbin/fsck/dir.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/dir.c,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 dir.c
--- sbin/fsck/dir.c	29 Oct 2003 09:53:29 -0000	1.15.2.1
+++ sbin/fsck/dir.c	1 Oct 2004 03:19:54 -0000
_at__at_ -90,7 +90,7 _at__at_
 			if (inp->i_parent == 0)
 				continue;
 			if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
-			    inoinfo(inp->i_number)->ino_state == DSTATE) {
+			    INO_IS_DUNFOUND(inp->i_number)) {
 				inoinfo(inp->i_number)->ino_state = DFOUND;
 				change++;
 			}
_at__at_ -692,8 +692,7 _at__at_
 		cacheino(dp, ino);
 		return(ino);
 	}
-	if (inoinfo(parent)->ino_state != DSTATE &&
-	    inoinfo(parent)->ino_state != DFOUND) {
+	if (!INO_IS_DVALID(parent)) {
 		freeino(ino);
 		return (0);
 	}
Index: sbin/fsck/fsck.h
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/fsck.h,v
retrieving revision 1.12.2.1
diff -u -r1.12.2.1 fsck.h
--- sbin/fsck/fsck.h	23 Jan 2001 23:11:07 -0000	1.12.2.1
+++ sbin/fsck/fsck.h	1 Oct 2004 03:19:54 -0000
_at__at_ -58,12 +58,21 _at__at_
 /*
  * Inode states.
  */
-#define	USTATE	01		/* inode not allocated */
-#define	FSTATE	02		/* inode is file */
-#define	DSTATE	03		/* inode is directory */
-#define	DFOUND	04		/* directory found during descent */
-#define	DCLEAR	05		/* directory is to be cleared */
-#define	FCLEAR	06		/* file is to be cleared */
+#define	USTATE	0x1		/* inode not allocated */
+#define	FSTATE	0x2		/* inode is file */
+#define	FZLINK	0x3		/* inode is file with a link count of zero */
+#define	DSTATE	0x4		/* inode is directory */
+#define	DZLINK	0x5		/* inode is directory with a zero link count  */
+#define	DFOUND	0x6		/* directory found during descent */
+/*     		0x7		   UNUSED - see S_IS_DVALID() definition */
+#define	DCLEAR	0x8		/* directory is to be cleared */
+#define	FCLEAR	0x9		/* file is to be cleared */
+/*     	DUNFOUND === (state == DSTATE || state == DZLINK) */
+#define	S_IS_DUNFOUND(state)	(((state) & ~0x1) == DSTATE)
+/*     	DVALID   === (state == DSTATE || state == DZLINK || state == DFOUND) */
+#define	S_IS_DVALID(state)	(((state) & ~0x3) == DSTATE)
+#define	INO_IS_DUNFOUND(ino)	S_IS_DUNFOUND(inoinfo(ino)->ino_state)
+#define	INO_IS_DVALID(ino)	S_IS_DVALID(inoinfo(ino)->ino_state)
 /*
  * Inode state information is contained on per cylinder group lists
  * which are described by the following structure.
_at__at_ -162,15 +171,6 _at__at_
 struct dups *muldup;		/* end of unique duplicate dup block numbers */
 
 /*
- * Linked list of inodes with zero link counts.
- */
-struct zlncnt {
-	struct zlncnt *next;
-	ino_t zlncnt;
-};
-struct zlncnt *zlnhead;		/* head of zero link count list */
-
-/*
  * Inode cache data structures.
  */
 struct inoinfo {
Index: sbin/fsck/inode.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/inode.c,v
retrieving revision 1.20
diff -u -r1.20 inode.c
--- sbin/fsck/inode.c	28 Feb 2000 20:02:41 -0000	1.20
+++ sbin/fsck/inode.c	1 Oct 2004 03:19:54 -0000
_at__at_ -565,10 +565,12 _at__at_
 	switch (inoinfo(ino)->ino_state) {
 
 	case FSTATE:
+	case FZLINK:
 		inoinfo(ino)->ino_state = FCLEAR;
 		return;
 
 	case DSTATE:
+	case DZLINK:
 		inoinfo(ino)->ino_state = DCLEAR;
 		return;
 
Index: sbin/fsck/main.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/main.c,v
retrieving revision 1.21.2.1
diff -u -r1.21.2.1 main.c
--- sbin/fsck/main.c	23 Jan 2001 23:11:07 -0000	1.21.2.1
+++ sbin/fsck/main.c	1 Oct 2004 03:29:14 -0000
_at__at_ -206,7 +206,6 _at__at_
 	ufs_daddr_t n_ffree, n_bfree;
 	struct dups *dp;
 	struct statfs *mntbuf;
-	struct zlncnt *zlnp;
 	int cylno;
 
 	if (preen && child)
_at__at_ -314,14 +313,7 _at__at_
 				printf(" %d,", dp->dup);
 			printf("\n");
 		}
-		if (zlnhead != NULL) {
-			printf("The following zero link count inodes remain:");
-			for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
-				printf(" %u,", zlnp->zlncnt);
-			printf("\n");
-		}
 	}
-	zlnhead = (struct zlncnt *)0;
 	duplist = (struct dups *)0;
 	muldup = (struct dups *)0;
 	inocleanup();
Index: sbin/fsck/pass1.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/pass1.c,v
retrieving revision 1.16.2.5
diff -u -r1.16.2.5 pass1.c
--- sbin/fsck/pass1.c	23 Jun 2002 22:34:58 -0000	1.16.2.5
+++ sbin/fsck/pass1.c	1 Oct 2004 03:39:37 -0000
_at__at_ -181,7 +181,6 _at__at_
 	register struct inodesc *idesc;
 {
 	register struct dinode *dp;
-	struct zlncnt *zlnp;
 	u_int64_t kernmaxfilesize;
 	ufs_daddr_t ndb, j;
 	mode_t mode;
_at__at_ -291,28 +290,18 _at__at_
 		goto unknown;
 	n_files++;
 	inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
-	if (dp->di_nlink <= 0) {
-		zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
-		if (zlnp == NULL) {
-			pfatal("LINK COUNT TABLE OVERFLOW");
-			if (reply("CONTINUE") == 0) {
-				ckfini(0);
-				exit(EEXIT);
-			}
-		} else {
-			zlnp->zlncnt = inumber;
-			zlnp->next = zlnhead;
-			zlnhead = zlnp;
-		}
-	}
 	if (mode == IFDIR) {
 		if (dp->di_size == 0)
 			inoinfo(inumber)->ino_state = DCLEAR;
+		else if (dp->di_nlink <= 0)
+			inoinfo(inumber)->ino_state = DZLINK;
 		else
 			inoinfo(inumber)->ino_state = DSTATE;
 		cacheino(dp, inumber);
 		countdirs++;
-	} else
+	} else if (dp->di_nlink <= 0)
+		inoinfo(inumber)->ino_state = FZLINK;
+	else
 		inoinfo(inumber)->ino_state = FSTATE;
 	inoinfo(inumber)->ino_type = IFTODT(mode);
 	if (doinglevel2 &&
Index: sbin/fsck/pass2.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/pass2.c,v
retrieving revision 1.10.2.2
diff -u -r1.10.2.2 pass2.c
--- sbin/fsck/pass2.c	24 Nov 2001 15:14:59 -0000	1.10.2.2
+++ sbin/fsck/pass2.c	1 Oct 2004 03:33:34 -0000
_at__at_ -92,6 +92,7 _at__at_
 
 	case FSTATE:
 	case FCLEAR:
+	case FZLINK:
 		pfatal("ROOT INODE NOT DIRECTORY");
 		if (reply("REALLOCATE")) {
 			freeino(ROOTINO);
_at__at_ -110,6 +111,7 _at__at_
 		break;
 
 	case DSTATE:
+	case DZLINK:
 		break;
 
 	default:
_at__at_ -189,7 +191,7 _at__at_
 		if (inp->i_parent == 0 || inp->i_isize == 0)
 			continue;
 		if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
-		    inoinfo(inp->i_number)->ino_state == DSTATE)
+		    INO_IS_DUNFOUND(inp->i_number))
 			inoinfo(inp->i_number)->ino_state = DFOUND;
 		if (inp->i_dotdot == inp->i_parent ||
 		    inp->i_dotdot == (ino_t)-1)
_at__at_ -431,6 +433,7 _at__at_
 			goto again;
 
 		case DSTATE:
+		case DZLINK:
 			if (inoinfo(idesc->id_number)->ino_state == DFOUND)
 				inoinfo(dirp->d_ino)->ino_state = DFOUND;
 			/* fall through */
_at__at_ -459,6 +462,7 _at__at_
 			/* fall through */
 
 		case FSTATE:
+		case FZLINK:
 			if (newinofmt &&
 			    dirp->d_type != inoinfo(dirp->d_ino)->ino_type) {
 				fileerror(idesc->id_number, dirp->d_ino,
Index: sbin/fsck/pass3.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/pass3.c,v
retrieving revision 1.7.2.1
diff -u -r1.7.2.1 pass3.c
--- sbin/fsck/pass3.c	23 Jan 2001 23:11:07 -0000	1.7.2.1
+++ sbin/fsck/pass3.c	1 Oct 2004 03:44:18 -0000
_at__at_ -68,7 +68,7 _at__at_
 		inp = inpsort[inpindex];
 		state = inoinfo(inp->i_number)->ino_state;
 		if (inp->i_number == ROOTINO ||
-		    (inp->i_parent != 0 && state != DSTATE))
+		    (inp->i_parent != 0 && !S_IS_DUNFOUND(state)))
 			continue;
 		if (state == DCLEAR)
 			continue;
_at__at_ -78,7 +78,7 _at__at_
 		 * them in DSTATE which will cause them to be pitched
 		 * in pass 4.
 		 */
-		if (preen && resolved && usedsoftdep && state == DSTATE) {
+		if (preen && resolved && usedsoftdep && S_IS_DUNFOUND(state)) {
 			if (inp->i_dotdot >= ROOTINO)
 				inoinfo(inp->i_dotdot)->ino_linkcnt++;
 			continue;
_at__at_ -86,7 +86,7 _at__at_
 		for (loopcnt = 0; ; loopcnt++) {
 			orphan = inp->i_number;
 			if (inp->i_parent == 0 ||
-			    inoinfo(inp->i_parent)->ino_state != DSTATE ||
+			    !INO_IS_DUNFOUND(inp->i_parent) ||
 			    loopcnt > countdirs)
 				break;
 			inp = getinoinfo(inp->i_parent);
Index: sbin/fsck/pass4.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/pass4.c,v
retrieving revision 1.7.2.1
diff -u -r1.7.2.1 pass4.c
--- sbin/fsck/pass4.c	23 Jan 2001 23:11:07 -0000	1.7.2.1
+++ sbin/fsck/pass4.c	1 Oct 2004 03:35:03 -0000
_at__at_ -53,7 +53,6 _at__at_
 pass4()
 {
 	register ino_t inumber;
-	register struct zlncnt *zlnp;
 	struct dinode *dp;
 	struct inodesc idesc;
 	int i, n, cg;
_at__at_ -75,6 +74,14 _at__at_
 			idesc.id_number = inumber;
 			switch (inoinfo(inumber)->ino_state) {
 
+			case FZLINK:
+			case DZLINK:
+				if (inoinfo(inumber)->ino_linkcnt == 0) {
+					clri(&idesc, "UNREF", 1);
+					break;
+				}
+				/* fall through */
+
 			case FSTATE:
 			case DFOUND:
 				n = inoinfo(inumber)->ino_linkcnt;
_at__at_ -82,16 +89,6 _at__at_
 					adjust(&idesc, (short)n);
 					break;
 				}
-				for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) {
-					if (zlnp->zlncnt == inumber) {
-						zlnp->zlncnt = zlnhead->zlncnt;
-						zlnp = zlnhead;
-						zlnhead = zlnhead->next;
-						free((char *)zlnp);
-						clri(&idesc, "UNREF", 1);
-						break;
-					}
-				}
 				break;
 
 			case DSTATE:
Index: sbin/fsck/pass5.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/pass5.c,v
retrieving revision 1.17.2.2
diff -u -r1.17.2.2 pass5.c
--- sbin/fsck/pass5.c	26 Nov 2002 04:46:59 -0000	1.17.2.2
+++ sbin/fsck/pass5.c	1 Oct 2004 03:36:45 -0000
_at__at_ -222,11 +222,13 _at__at_
 			case DSTATE:
 			case DCLEAR:
 			case DFOUND:
+			case DZLINK:
 				newcg->cg_cs.cs_ndir++;
 				/* fall through */
 
 			case FSTATE:
 			case FCLEAR:
+			case FZLINK:
 				newcg->cg_cs.cs_nifree--;
 				setbit(cg_inosused(newcg), i);
 				break;
Index: sbin/fsck/utilities.c
===================================================================
RCS file: /home/ncvs/src/sbin/fsck/Attic/utilities.c,v
retrieving revision 1.11.2.3
diff -u -r1.11.2.3 utilities.c
--- sbin/fsck/utilities.c	23 Jan 2001 23:11:07 -0000	1.11.2.3
+++ sbin/fsck/utilities.c	1 Oct 2004 03:28:19 -0000
_at__at_ -466,9 +466,7 _at__at_
 		(void)strcpy(namebuf, "/");
 		return;
 	}
-	if (busy ||
-	    (inoinfo(curdir)->ino_state != DSTATE &&
-	     inoinfo(curdir)->ino_state != DFOUND)) {
+	if (busy || !INO_IS_DVALID(curdir)) {
 		(void)strcpy(namebuf, "?");
 		return;
 	}
Received on Fri Oct 01 2004 - 02:07:09 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:15 UTC