Subject: filesystem clean Index: src/sys/sys/{ufs_mount,ufs_subr.c} src/sys/pdp/machdep2.c src/sys/h/mount.h src/sbin/fsck src/man/man8/fsck.8 Description: Large capacity disks take a very long time for fsck to verify the integrity of the filesystems. Repeat-By: Have large filesystems present and perform a 'reboot'. Observe that fsck can take a very long time for the larger filesystems Fix: This patch implements a 'filesystem clean' flag. When a filesystem is clean and unmounted successfully the superblock is updated with the 'clean flag' set. When fsck sees the 'clean flag' it will, unless the -f flag is used, skip checking the filesystem. This patch is courtesy of Johnny Billquist (bqt@softjar.se). NOTE: A kernel recompile, install and reboot is part of this patch! If you maintain a copy of the generic kernel (in /genunix for example then rebuild and install /genunix) WARNING: A small amount of code is added in ufs_subr.c and ufs_mount.c - this MAY affect the overlay layout. Cut where indicated and save to a file (/tmp/456.patch). Then: cd /usr/src/man/man8 /usr/man/manroff fsck.8 > fsck.0 install -c -o bin -g bin -m 444 fsck.0 /usr/man/cat8 rm -f fsck.0 cd /usr/src/sbin/fsck make make install make clean cd /sys/ make # optionally save the old kernel and networking #mv /unix /ounix #mv /netnix /onetnix install -c -o root -g wheel -m 744 unix /unix install -c -o root -g wheel -m 744 netnix /netnix make clean # optional #cd /sys/GENERIC #make #install -c -o root -g wheel -m 744 unix /genunix #make clean reboot The first time you run fsck after booting you must halt the system without sync! This sets the clean flag on the root filesystem After the first fsck and reboot the clean flag will be used to avoid checking filesystems that were cleanly unmounted. This and previous updates to 2.11BSD are available at the following locations: ftp://ftp.update.uu.se/pub/pdp11/2.11BSD https://www.tuhs.org/Archive/Distributions/UCB/2.11BSD/Patches/ ftp://ftp.2bsd.com/2.11BSD ---------------------------cut here-------------------- *** usr/src/man/man8/fsck.8.old Sun Nov 17 22:48:06 1996 --- usr/src/man/man8/fsck.8 Mon Nov 18 07:47:21 2019 *************** *** 7,13 **** fsck \- file system consistency check and interactive repair .SH SYNOPSIS .B fsck ! .BR \-p "[ # ]" [ filesystem ... ] --- 7,13 ---- fsck \- file system consistency check and interactive repair .SH SYNOPSIS .B fsck ! .BR \-p "[ # ] [ -f ]" [ filesystem ... ] *************** *** 18,23 **** --- 18,25 ---- ] [ .B \-n ] [ + .B \-f + ] [ .BR \-s X ] [ .BR \-S X *************** *** 146,151 **** --- 148,156 ---- Assume a no response to all questions asked by .I fsck; do not open the file system for writing. + .TP 6 + .B \-\^f + Force checking of file system, even if it is marked clean. .TP 6 .BR \-\^s \fIX Ignore the actual free list and (unconditionally) reconstruct a new *** usr/src/sbin/fsck/fsck.h.old Thu Apr 26 12:34:21 1990 --- usr/src/sbin/fsck/fsck.h Mon Nov 18 07:54:42 2019 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)fsck.h 5.1 (Berkeley) 6/5/85 */ #define MAXDUP 10 /* limit on dup blks (per inode) */ --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)fsck.h 5.2 (2.11BSD) 2019/11/18 */ #define MAXDUP 10 /* limit on dup blks (per inode) */ *************** *** 155,160 **** --- 155,162 ---- char sflag; /* rebuild free list */ int debug; /* output debugging info */ char preen; /* just fix normal inconsistencies */ + char fflag; /* force check on clean file system */ + char noflag; /* flag is we answered any question with no */ char hotroot; /* checking root device */ char fixfree; /* force rebuild of freelist */ char *membase; /* base of memory we get */ *** usr/src/sbin/fsck/main.c.old Sat Feb 3 23:42:38 1996 --- usr/src/sbin/fsck/main.c Mon Nov 18 07:55:23 2019 *************** *** 9,20 **** "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)main.c 5.4.1 (2.11BSD) 1996/2/3"; #endif not lint #include #include #include #include #include #include --- 9,21 ---- "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)main.c 5.5 (2.11BSD) 2019/11/18"; #endif not lint #include #include #include + #include #include #include #include *************** *** 60,65 **** --- 61,70 ---- preen++; break; + case 'f': /* force check */ + fflag++; + break; + case 'd': debug++; break; *************** *** 168,180 **** { daddr_t n_ffree, n_bfree; register ino_t *zp; devname = filesys; ! if (setup(filesys) == 0) { if (preen) pfatal("CAN'T CHECK FILE SYSTEM."); return; } /* * 1: scan inodes tallying blocks used */ --- 173,191 ---- { daddr_t n_ffree, n_bfree; register ino_t *zp; + int i; devname = filesys; ! if ((i = setup(filesys)) == 0) { if (preen) pfatal("CAN'T CHECK FILE SYSTEM."); return; } + if (i<0) { + pwarn("%sile system is clean; not checking\n", preen ? "f" : "** F"); + return; + } + /* * 1: scan inodes tallying blocks used */ *************** *** 252,261 **** --- 263,292 ---- } bzero(zlnlist, sizeof zlnlist); bzero(duplist, sizeof duplist); + if (dfile.mod) { (void)time(&sblock.fs_time); sbdirty(); } + + /* If the superblock wasn't marked clean, we'll + * mark it clean now, and update it. + * + * Note: The root filesystem is special, since it + * is already mounted (hotroot). For this one + * we instead look at WASCLEAN, since it reflect + * the clean status at mount time. + */ + if ((sblock.fs_flags & MNT_CLEAN) == 0) { + if (!(hotroot && (sblock.fs_flags & MNT_WASCLEAN))) { + if (!noflag) { + pwarn("Marking file system clean\n"); + sblock.fs_flags |= MNT_CLEAN|MNT_WASCLEAN; + sbdirty(); + } + } + } + ckfini(); if (!dfile.mod) return; *** usr/src/sbin/fsck/setup.c.old Sat Feb 3 23:46:25 1996 --- usr/src/sbin/fsck/setup.c Mon Nov 18 07:55:41 2019 *************** *** 5,11 **** */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)setup.c 5.3.1 (2.11BSD) 1996/2/3"; #endif not lint #include --- 5,11 ---- */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)setup.c 5.4 (2.11BSD) 2019/11/18"; #endif not lint #include *************** *** 14,19 **** --- 14,20 ---- #include #include #include + #include #include "fsck.h" setup(dev) *************** *** 158,163 **** --- 159,169 ---- statemap = &mbase[bmapsz]; freemap = statemap; lncntp = (short *)&statemap[smapsz]; + } + + if (!fflag) { + if (sblock.fs_flags & MNT_CLEAN) return(-1); + if (hotroot && (sblock.fs_flags & MNT_WASCLEAN)) return(-1); } return(1); } *** usr/src/sbin/fsck/utilities.c.old Sat Sep 15 22:19:09 1990 --- usr/src/sbin/fsck/utilities.c Mon Nov 18 07:56:32 2019 *************** *** 5,11 **** */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)utilities.c 5.2 (Berkeley) 9/10/85"; #endif not lint #include --- 5,11 ---- */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)utilities.c 5.3 (2.11BSD) 2019/11/18"; #endif not lint #include *************** *** 48,53 **** --- 48,54 ---- printf("\n%s? ", s); if (nflag || dfile.wfdes < 0) { printf(" no\n\n"); + noflag = 1; return (0); } if (yflag) { *************** *** 59,66 **** printf("\n"); if (line[0] == 'y' || line[0] == 'Y') return (1); ! else ! return (0); } getline(fp, loc, maxlen) --- 60,67 ---- printf("\n"); if (line[0] == 'y' || line[0] == 'Y') return (1); ! noflag = 1; ! return (0); } getline(fp, loc, maxlen) *** usr/src/sys/h/mount.h.old Sun Jun 29 16:47:54 1997 --- usr/src/sys/h/mount.h Mon Nov 18 07:57:12 2019 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)mount.h 7.2.5 (2.11BSD GTE) 1997/6/29 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)mount.h 7.3 (2.11BSD) 2019/11/18 */ /* *************** *** 90,95 **** --- 90,97 ---- * support will never be a problem we can avoid making the flags into a 'long. */ #define MNT_UPDATE 0x1000 /* not a real mount, just an update */ + #define MNT_CLEAN 0x2000 /* file system is clean */ + #define MNT_WASCLEAN 0x4000 /* file system was clean at mount */ /* * Flags for various system call interfaces. *** usr/src/sys/pdp/machdep2.c.old Sun Jul 25 23:19:26 1999 --- usr/src/sys/pdp/machdep2.c Mon Nov 18 07:59:08 2019 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)machdep2.c 2.9 (2.11BSD) 1999/2/19 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)machdep2.c 2.10 (2.11BSD) 2019/11/18 */ #include "param.h" *************** *** 411,416 **** --- 411,417 ---- } } printf("done\n"); + fsclean(); } (void) _splhigh(); if (howto & RB_HALT) { *** usr/src/sys/sys/ufs_mount.c.old Sun Jun 29 18:27:23 1997 --- usr/src/sys/sys/ufs_mount.c Mon Nov 18 07:59:50 2019 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ufs_mount.c 2.1 (2.11BSD GTE) 1997/6/29 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ufs_mount.c 2.2 (2.11BSD) 2019/11/18 */ #include "param.h" *************** *** 228,233 **** --- 228,234 ---- fs->fs_flock = 0; fs->fs_nbehind = 0; fs->fs_lasti = 1; + if (fs->fs_flags & MNT_CLEAN) flags |= MNT_WASCLEAN; fs->fs_flags = flags; if (ip) { ip->i_flag |= IMOUNT; *************** *** 234,239 **** --- 235,241 ---- cacheinval(ip); IUNLOCK(ip); } + if (fs->fs_fmod) ufs_sync(mp); return (fs); out: if (error == 0) *************** *** 283,288 **** --- 285,300 ---- nchinval(dev); /* flush the name cache */ aflag = mp->m_flags & MNT_ASYNC; mp->m_flags &= ~MNT_ASYNC; /* Don't want async when unmounting */ + + if ((mp->m_flags & MNT_RDONLY) == 0) { + struct fs *fs; + fs = &mp->m_filsys; + if (fs->fs_flags & MNT_WASCLEAN) { + fs->fs_fmod = 1; /* SB update needed */ + fs->fs_flags |= MNT_CLEAN; /* File system is now clean */ + } + } + ufs_sync(mp); #ifdef QUOTA *** usr/src/sys/sys/ufs_subr.c.old Mon Sep 16 23:08:51 1996 --- usr/src/sys/sys/ufs_subr.c Mon Nov 18 08:00:48 2019 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ufs_subr.c 1.5 (2.11BSD GTE) 1996/9/13 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ufs_subr.c 1.6 (2.11BSD) 2019/11/18 */ #include "param.h" *************** *** 43,48 **** --- 43,80 ---- mp->m_flags &= ~MNT_ASYNC; ufs_sync(mp); mp->m_flags |= async; + } + updlock = 0; + } + + /* + * Go through the mount table marking filesystems clean. + */ + fsclean() + { + register struct mount *mp; + register struct fs *fs; + int async; + + if (updlock) + return; + updlock++; + for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) + { + if (mp->m_inodp == NULL || mp->m_dev == NODEV) + continue; + fs = &mp->m_filsys; + if (fs->fs_ronly == 1 || fs->fs_ilock || fs->fs_flock) + continue; + if (fs->fs_flags & MNT_WASCLEAN) { + async = mp->m_flags & MNT_ASYNC; + mp->m_flags &= ~MNT_ASYNC; + fs->fs_flags |= MNT_CLEAN; + fs->fs_fmod = 1; + ufs_sync(mp); + fs->fs_flags &= ~MNT_CLEAN; + mp->m_flags |= async; + } } updlock = 0; } *** VERSION.old Tue Oct 29 07:57:20 2019 --- VERSION Mon Nov 18 07:53:08 2019 *************** *** 1,5 **** ! Current Patch Level: 455 ! Date: October 29, 2019 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 456 ! Date: November 18, 2019 2.11 BSD ============