minor optimization
[unix-history] / usr / src / sbin / fsck / main.c
CommitLineData
76797561 1/*
fe32782c
KM
2 * Copyright (c) 1980, 1986 The Regents of the University of California.
3 * All rights reserved.
4 *
70ab3c27 5 * %sccs.include.redist.c%
76797561
DF
6 */
7
8#ifndef lint
9char copyright[] =
fe32782c 10"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
76797561 11 All rights reserved.\n";
fe32782c 12#endif /* not lint */
76797561 13
fa95fc59 14#ifndef lint
d08e3849 15static char sccsid[] = "@(#)main.c 5.27 (Berkeley) %G%";
fe32782c 16#endif /* not lint */
07670f7d 17
4d308541 18#include <sys/param.h>
72e5286b 19#include <ufs/dinode.h>
4d7f4685 20#include <ufs/fs.h>
7718c0e6 21#include <fstab.h>
d72e970b 22#include <stdlib.h>
38dde0cd 23#include <string.h>
c689da7b 24#include <ctype.h>
304178c6 25#include <stdio.h>
f7635e39 26#include "fsck.h"
6e884967 27
392fe950 28void catch(), catchquit(), voidquit();
3cfe4689 29int returntosingle;
7718c0e6
KM
30
31main(argc, argv)
32 int argc;
33 char *argv[];
34{
d72e970b 35 int ch;
e23b720f 36 int ret, maxrun = 0;
304178c6
KM
37 extern int docheck(), checkfilesys();
38 extern char *optarg;
39 extern int optind;
7718c0e6
KM
40
41 sync();
304178c6
KM
42 while ((ch = getopt(argc, argv, "cdpnNyYb:l:m:")) != EOF) {
43 switch (ch) {
7718c0e6
KM
44 case 'p':
45 preen++;
46 break;
47
48 case 'b':
d72e970b 49 bflag = argtoi('b', "number", optarg, 10);
7718c0e6
KM
50 printf("Alternate super block location: %d\n", bflag);
51 break;
52
d3e80ec3
KM
53 case 'c':
54 cvtflag++;
55 break;
56
7718c0e6
KM
57 case 'd':
58 debug++;
59 break;
60
5eeaeb24 61 case 'l':
d72e970b 62 maxrun = argtoi('l', "number", optarg, 10);
5eeaeb24
MK
63 break;
64
c689da7b 65 case 'm':
d72e970b 66 lfmode = argtoi('m', "mode", optarg, 8);
c689da7b
KM
67 if (lfmode &~ 07777)
68 errexit("bad mode to -m: %o\n", lfmode);
c689da7b
KM
69 printf("** lost+found creation mode %o\n", lfmode);
70 break;
71
569ec282 72 case 'n':
7718c0e6
KM
73 case 'N':
74 nflag++;
75 yflag = 0;
76 break;
77
569ec282 78 case 'y':
7718c0e6
KM
79 case 'Y':
80 yflag++;
81 nflag = 0;
82 break;
83
84 default:
304178c6 85 errexit("%c option?\n", ch);
7718c0e6
KM
86 }
87 }
304178c6
KM
88 argc -= optind;
89 argv += optind;
7718c0e6
KM
90 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
91 (void)signal(SIGINT, catch);
3cfe4689
MK
92 if (preen)
93 (void)signal(SIGQUIT, catchquit);
7718c0e6 94 if (argc) {
304178c6 95 while (argc-- > 0)
d08e3849 96 (void)checkfilesys(*argv++, (char *)0, 0L, 0);
7718c0e6
KM
97 exit(0);
98 }
e23b720f 99 ret = checkfstab(preen, maxrun, docheck, checkfilesys);
3cfe4689
MK
100 if (returntosingle)
101 exit(2);
e23b720f 102 exit(ret);
7718c0e6
KM
103}
104
d72e970b
KM
105argtoi(flag, req, str, base)
106 int flag;
107 char *req, *str;
108 int base;
109{
110 char *cp;
111 int ret;
112
113 ret = (int)strtol(str, &cp, base);
114 if (cp == str || *cp)
115 errexit("-%c flag requires a %s\n", flag, req);
116 return (ret);
117}
118
e23b720f
KM
119/*
120 * Determine whether a filesystem should be checked.
121 */
122docheck(fsp)
123 register struct fstab *fsp;
5eeaeb24
MK
124{
125
e23b720f
KM
126 if (strcmp(fsp->fs_vfstype, "ufs") ||
127 (strcmp(fsp->fs_type, FSTAB_RW) &&
128 strcmp(fsp->fs_type, FSTAB_RO)) ||
129 fsp->fs_passno == 0)
130 return (0);
131 return (1);
5eeaeb24
MK
132}
133
e23b720f
KM
134/*
135 * Check the specified filesystem.
136 */
137/* ARGSUSED */
d08e3849 138checkfilesys(filesys, mntpt, auxdata, child)
e23b720f
KM
139 char *filesys, *mntpt;
140 long auxdata;
6e884967 141{
993a756c 142 daddr_t n_ffree, n_bfree;
d4233021 143 struct dups *dp;
1a02fd3a 144 struct zlncnt *zlnp;
6e884967 145
d08e3849
MK
146 if (preen && child)
147 (void)signal(SIGQUIT, voidquit);
d2c95d76 148 devname = filesys;
5eeaeb24
MK
149 if (debug && preen)
150 pwarn("starting\n");
d2c95d76 151 if (setup(filesys) == 0) {
6e884967 152 if (preen)
d2c95d76 153 pfatal("CAN'T CHECK FILE SYSTEM.");
e23b720f 154 return (0);
6e884967 155 }
993a756c
KM
156 /*
157 * 1: scan inodes tallying blocks used
158 */
690f77ba
KM
159 if (preen == 0) {
160 printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
6e884967
KM
161 if (hotroot)
162 printf("** Root file system\n");
163 printf("** Phase 1 - Check Blocks and Sizes\n");
164 }
d2c95d76
BJ
165 pass1();
166
993a756c
KM
167 /*
168 * 1b: locate first references to duplicates, if any
169 */
62e6c152 170 if (duplist) {
d2c95d76
BJ
171 if (preen)
172 pfatal("INTERNAL ERROR: dups with -p");
173 printf("** Phase 1b - Rescan For More DUPS\n");
174 pass1b();
175 }
176
993a756c
KM
177 /*
178 * 2: traverse directories from root to mark all connected directories
179 */
d2c95d76
BJ
180 if (preen == 0)
181 printf("** Phase 2 - Check Pathnames\n");
182 pass2();
183
993a756c
KM
184 /*
185 * 3: scan inodes looking for disconnected directories
186 */
d2c95d76
BJ
187 if (preen == 0)
188 printf("** Phase 3 - Check Connectivity\n");
189 pass3();
190
993a756c
KM
191 /*
192 * 4: scan inodes looking for disconnected files; check reference counts
193 */
d2c95d76
BJ
194 if (preen == 0)
195 printf("** Phase 4 - Check Reference Counts\n");
196 pass4();
197
993a756c
KM
198 /*
199 * 5: check and repair resource counts in cylinder groups
200 */
d2c95d76
BJ
201 if (preen == 0)
202 printf("** Phase 5 - Check Cyl groups\n");
203 pass5();
204
993a756c
KM
205 /*
206 * print out summary statistics
207 */
208 n_ffree = sblock.fs_cstotal.cs_nffree;
209 n_bfree = sblock.fs_cstotal.cs_nbfree;
d72e970b 210 pwarn("%ld files, %ld used, %ld free ",
8755a38b 211 n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
d72e970b 212 printf("(%ld frags, %ld blocks, %.1f%% fragmentation)\n",
8755a38b 213 n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
569ec282
KM
214 if (debug &&
215 (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
d72e970b 216 printf("%ld files missing\n", n_files);
993a756c
KM
217 if (debug) {
218 n_blks += sblock.fs_ncg *
219 (cgdmin(&sblock, 0) - cgsblock(&sblock, 0));
220 n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0);
221 n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize);
569ec282 222 if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree))
d72e970b 223 printf("%ld blocks missing\n", n_blks);
d4233021
KM
224 if (duplist != NULL) {
225 printf("The following duplicate blocks remain:");
226 for (dp = duplist; dp; dp = dp->next)
d72e970b 227 printf(" %ld,", dp->dup);
d4233021
KM
228 printf("\n");
229 }
1a02fd3a
KM
230 if (zlnhead != NULL) {
231 printf("The following zero link count inodes remain:");
232 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
d72e970b 233 printf(" %lu,", zlnp->zlncnt);
1a02fd3a
KM
234 printf("\n");
235 }
d2c95d76 236 }
1a02fd3a
KM
237 zlnhead = (struct zlncnt *)0;
238 duplist = (struct dups *)0;
57117c0f 239 inocleanup();
569ec282 240 if (fsmodified) {
1a724405 241 (void)time(&sblock.fs_time);
d2c95d76
BJ
242 sbdirty();
243 }
244 ckfini();
245 free(blockmap);
d2c95d76 246 free(statemap);
1a724405 247 free((char *)lncntp);
569ec282 248 if (!fsmodified)
e23b720f 249 return (0);
addfa1aa
BJ
250 if (!preen) {
251 printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
252 if (hotroot)
253 printf("\n***** REBOOT UNIX *****\n");
254 }
255 if (hotroot) {
256 sync();
e23b720f 257 return (4);
7718c0e6 258 }
7718c0e6
KM
259 return (0);
260}