Bug Summary

File:src/sbin/fsck_ffs/utilities.c
Warning:line 465, column 9
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name utilities.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/fsck_ffs/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sbin/fsck_ffs/../fsck -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/fsck_ffs/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/fsck_ffs/utilities.c
1/* $OpenBSD: utilities.c,v 1.54 2020/07/13 06:52:53 otto Exp $ */
2/* $NetBSD: utilities.c,v 1.18 1996/09/27 22:45:20 christos Exp $ */
3
4/*
5 * Copyright (c) 1980, 1986, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h> /* DEV_BSIZE isset setbit clrbit */
34#include <sys/time.h>
35#include <sys/uio.h>
36#include <ufs/ufs/dinode.h>
37#include <ufs/ufs/dir.h>
38#include <ufs/ffs/fs.h>
39#include <signal.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <ctype.h>
44#include <unistd.h>
45#include <limits.h>
46#include <errno(*__errno()).h>
47#include <fcntl.h>
48#include <paths.h>
49
50#include "fsutil.h"
51#include "fsck.h"
52#include "extern.h"
53
54long diskreads, totalreads; /* Disk cache statistics */
55static struct bufarea cgblk; /* backup buffer for cylinder group blocks */
56
57static void rwerror(char *, daddr_t);
58
59int
60ftypeok(union dinode *dp)
61{
62 switch (DIP(dp, di_mode)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mode
: (dp)->dp2.di_mode)
& IFMT0170000) {
63 case IFDIR0040000:
64 case IFREG0100000:
65 case IFBLK0060000:
66 case IFCHR0020000:
67 case IFLNK0120000:
68 case IFSOCK0140000:
69 case IFIFO0010000:
70 return (1);
71 default:
72 if (debug)
73 printf("bad file type 0%o\n", DIP(dp, di_mode)(((*sblk.b_un.b_fs).fs_magic == 0x011954) ? (dp)->dp1.di_mode
: (dp)->dp2.di_mode)
);
74 return (0);
75 }
76}
77
78int
79reply(char *question)
80{
81 int persevere, c;
82
83 if (preen)
84 pfatal("INTERNAL ERROR: GOT TO reply()");
85 persevere = !strcmp(question, "CONTINUE");
86 printf("\n");
87 if (!persevere && (nflag || fswritefd < 0)) {
88 printf("%s? no\n\n", question);
89 resolved = 0;
90 return (0);
91 }
92 if (yflag || (persevere && nflag)) {
93 printf("%s? yes\n\n", question);
94 return (1);
95 }
96
97 do {
98 printf("%s? [Fyn?] ", question);
99 (void) fflush(stdout(&__sF[1]));
100 c = getc(stdin)(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
;
101 if (c == 'F') {
102 yflag = 1;
103 return (1);
104 }
105 while (c != '\n' && getc(stdin)(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
!= '\n') {
106 if (feof(stdin)(!__isthreaded ? ((((&__sF[0]))->_flags & 0x0020) !=
0) : (feof)((&__sF[0])))
) {
107 resolved = 0;
108 return (0);
109 }
110 }
111 } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
112 printf("\n");
113 if (c == 'y' || c == 'Y')
114 return (1);
115 resolved = 0;
116 return (0);
117}
118
119/*
120 * Look up state information for an inode.
121 */
122struct inostat *
123inoinfo(ino_t inum)
124{
125 static struct inostat unallocated = { USTATE01, 0, 0 };
126 struct inostatlist *ilp;
127 int iloff;
128
129 if (inum > maxino)
130 errexit("inoinfo: inumber %llu out of range",
131 (unsigned long long)inum);
132 ilp = &inostathead[inum / sblock(*sblk.b_un.b_fs).fs_ipg];
133 iloff = inum % sblock(*sblk.b_un.b_fs).fs_ipg;
134 if (iloff >= ilp->il_numalloced)
135 return (&unallocated);
136 return (&ilp->il_stat[iloff]);
137}
138
139/*
140 * Malloc buffers and set up cache.
141 */
142void
143bufinit(void)
144{
145 struct bufarea *bp;
146 long bufcnt, i;
147 char *bufp;
148
149 pbp = pdirbp = NULL((void *)0);
150 bufp = malloc((unsigned int)sblock(*sblk.b_un.b_fs).fs_bsize);
151 if (bufp == 0)
152 errexit("cannot allocate buffer pool\n");
153 cgblk.b_un.b_buf = bufp;
154 initbarea(&cgblk)(&cgblk)->b_dirty = 0; (&cgblk)->b_bno = -1; (&
cgblk)->b_flags = 0;
;
155 bufhead.b_next = bufhead.b_prev = &bufhead;
156 bufcnt = MAXBUFSPACE40*1024 / sblock(*sblk.b_un.b_fs).fs_bsize;
157 if (bufcnt < MINBUFS5)
158 bufcnt = MINBUFS5;
159 for (i = 0; i < bufcnt; i++) {
160 bp = malloc(sizeof(struct bufarea));
161 bufp = malloc((unsigned int)sblock(*sblk.b_un.b_fs).fs_bsize);
162 if (bp == NULL((void *)0) || bufp == NULL((void *)0)) {
163 free(bp);
164 free(bufp);
165 if (i >= MINBUFS5)
166 break;
167 errexit("cannot allocate buffer pool\n");
168 }
169 bp->b_un.b_buf = bufp;
170 bp->b_prev = &bufhead;
171 bp->b_next = bufhead.b_next;
172 bufhead.b_next->b_prev = bp;
173 bufhead.b_next = bp;
174 initbarea(bp)(bp)->b_dirty = 0; (bp)->b_bno = -1; (bp)->b_flags =
0;
;
175 }
176 bufhead.b_size = i; /* save number of buffers */
177}
178
179/*
180 * Manage cylinder group buffers.
181 */
182static struct bufarea *cgbufs; /* header for cylinder group cache */
183static int flushtries; /* number of tries to reclaim memory */
184struct bufarea *
185cglookup(u_int cg)
186{
187 struct bufarea *cgbp;
188 struct cg *cgp;
189
190 if (cgbufs == NULL((void *)0)) {
14
Assuming 'cgbufs' is not equal to NULL
15
Taking false branch
191 cgbufs = calloc(sblock(*sblk.b_un.b_fs).fs_ncg, sizeof(struct bufarea));
192 if (cgbufs == NULL((void *)0))
193 errexit("cannot allocate cylinder group buffers");
194 }
195 cgbp = &cgbufs[cg];
196 if (cgbp->b_un.b_cg != NULL((void *)0))
16
Assuming field 'b_cg' is equal to NULL
17
Taking false branch
197 return (cgbp);
198 cgp = NULL((void *)0);
199 if (flushtries == 0)
18
Assuming 'flushtries' is equal to 0
19
Taking true branch
200 cgp = malloc((unsigned int)sblock(*sblk.b_un.b_fs).fs_cgsize);
20
Uninitialized value stored to field 'cg_magic'
201 if (cgp == NULL((void *)0)) {
21
Assuming 'cgp' is not equal to NULL
22
Taking false branch
202 getblk(&cgblk, cgtod(&sblock, cg)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (cg)) + (&
(*sblk.b_un.b_fs))->fs_cgoffset * ((cg) & ~((&(*sblk
.b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))->
fs_cblkno)
, sblock(*sblk.b_un.b_fs).fs_cgsize);
203 return (&cgblk);
204 }
205 cgbp->b_un.b_cg = cgp;
206 initbarea(cgbp)(cgbp)->b_dirty = 0; (cgbp)->b_bno = -1; (cgbp)->b_flags
= 0;
;
207 getblk(cgbp, cgtod(&sblock, cg)((((daddr_t)(&(*sblk.b_un.b_fs))->fs_fpg * (cg)) + (&
(*sblk.b_un.b_fs))->fs_cgoffset * ((cg) & ~((&(*sblk
.b_un.b_fs))->fs_cgmask))) + (&(*sblk.b_un.b_fs))->
fs_cblkno)
, sblock(*sblk.b_un.b_fs).fs_cgsize);
208 return (cgbp);
209}
210
211
212/*
213 * Manage a cache of directory blocks.
214 */
215struct bufarea *
216getdatablk(daddr_t blkno, long size)
217{
218 struct bufarea *bp;
219
220 for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
221 if (bp->b_bno == fsbtodb(&sblock, blkno)((blkno) << (&(*sblk.b_un.b_fs))->fs_fsbtodb))
222 goto foundit;
223 for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
224 if ((bp->b_flags & B_INUSE1) == 0)
225 break;
226 if (bp == &bufhead)
227 errexit("deadlocked buffer pool\n");
228 getblk(bp, blkno, size);
229 /* FALLTHROUGH */
230foundit:
231 totalreads++;
232 bp->b_prev->b_next = bp->b_next;
233 bp->b_next->b_prev = bp->b_prev;
234 bp->b_prev = &bufhead;
235 bp->b_next = bufhead.b_next;
236 bufhead.b_next->b_prev = bp;
237 bufhead.b_next = bp;
238 bp->b_flags |= B_INUSE1;
239 return (bp);
240}
241
242void
243getblk(struct bufarea *bp, daddr_t blk, long size)
244{
245 daddr_t dblk;
246
247 dblk = fsbtodb(&sblock, blk)((blk) << (&(*sblk.b_un.b_fs))->fs_fsbtodb);
248 if (bp->b_bno != dblk) {
249 flush(fswritefd, bp);
250 diskreads++;
251 bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
252 bp->b_bno = dblk;
253 bp->b_size = size;
254 }
255}
256
257void
258flush(int fd, struct bufarea *bp)
259{
260 int i, j;
261
262 if (!bp->b_dirty)
263 return;
264 if (bp->b_errs != 0)
265 pfatal("WRITING %sZERO'ED BLOCK %lld TO DISK\n",
266 (bp->b_errs == bp->b_size / DEV_BSIZE(1 << 9)) ? "" : "PARTIALLY ",
267 (long long)bp->b_bno);
268 bp->b_dirty = 0;
269 bp->b_errs = 0;
270 bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
271 if (bp != &sblk)
272 return;
273 for (i = 0, j = 0; i < sblock(*sblk.b_un.b_fs).fs_cssize; i += sblock(*sblk.b_un.b_fs).fs_bsize, j++) {
274 bwrite(fswritefd, (char *)sblock(*sblk.b_un.b_fs).fs_csp + i,
275 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag)(((*sblk.b_un.b_fs).fs_csaddr + j * (*sblk.b_un.b_fs).fs_frag
) << (&(*sblk.b_un.b_fs))->fs_fsbtodb)
,
276 sblock(*sblk.b_un.b_fs).fs_cssize - i < sblock(*sblk.b_un.b_fs).fs_bsize ?
277 sblock(*sblk.b_un.b_fs).fs_cssize - i : sblock(*sblk.b_un.b_fs).fs_bsize);
278 }
279}
280
281static void
282rwerror(char *mesg, daddr_t blk)
283{
284
285 if (preen == 0)
286 printf("\n");
287 pfatal("CANNOT %s: BLK %lld", mesg, (long long)blk);
288 if (reply("CONTINUE") == 0)
289 errexit("Program terminated\n");
290}
291
292void
293ckfini(int markclean)
294{
295 struct bufarea *bp, *nbp;
296 int cnt = 0;
297 sigset_t oset, nset;
298 int64_t sblockloc;
299
300 sigemptyset(&nset);
301 sigaddset(&nset, SIGINT2);
302 sigprocmask(SIG_BLOCK1, &nset, &oset);
303
304 if (fswritefd < 0) {
305 (void)close(fsreadfd);
306 fsreadfd = -1;
307 sigprocmask(SIG_SETMASK3, &oset, NULL((void *)0));
308 return;
309 }
310 if (sblock(*sblk.b_un.b_fs).fs_magic == FS_UFS1_MAGIC0x011954) {
311 sblockloc = SBLOCK_UFS18192;
312 sblock(*sblk.b_un.b_fs).fs_ffs1_time = sblock(*sblk.b_un.b_fs).fs_time;
313 sblock(*sblk.b_un.b_fs).fs_ffs1_size = sblock(*sblk.b_un.b_fs).fs_size;
314 sblock(*sblk.b_un.b_fs).fs_ffs1_dsize = sblock(*sblk.b_un.b_fs).fs_dsize;
315 sblock(*sblk.b_un.b_fs).fs_ffs1_csaddr = sblock(*sblk.b_un.b_fs).fs_csaddr;
316 sblock(*sblk.b_un.b_fs).fs_ffs1_cstotal.cs_ndir = sblock(*sblk.b_un.b_fs).fs_cstotal.cs_ndir;
317 sblock(*sblk.b_un.b_fs).fs_ffs1_cstotal.cs_nbfree = sblock(*sblk.b_un.b_fs).fs_cstotal.cs_nbfree;
318 sblock(*sblk.b_un.b_fs).fs_ffs1_cstotal.cs_nifree = sblock(*sblk.b_un.b_fs).fs_cstotal.cs_nifree;
319 sblock(*sblk.b_un.b_fs).fs_ffs1_cstotal.cs_nffree = sblock(*sblk.b_un.b_fs).fs_cstotal.cs_nffree;
320 /* Force update on next mount */
321 sblock(*sblk.b_un.b_fs).fs_ffs1_flags &= ~FS_FLAGS_UPDATED0x80;
322 } else
323 sblockloc = SBLOCK_UFS265536;
324 flush(fswritefd, &sblk);
325 if (havesb && sblk.b_bno != sblockloc / DEV_BSIZE(1 << 9) && !preen &&
326 reply("UPDATE STANDARD SUPERBLOCK")) {
327 sblk.b_bno = sblockloc / DEV_BSIZE(1 << 9);
328 sbdirty()sblk.b_dirty = 1;
329 flush(fswritefd, &sblk);
330 }
331 flush(fswritefd, &cgblk);
332 free(cgblk.b_un.b_buf);
333 for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) {
334 cnt++;
335 flush(fswritefd, bp);
336 nbp = bp->b_prev;
337 free(bp->b_un.b_buf);
338 free(bp);
339 }
340 if (bufhead.b_size != cnt)
341 errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
342 if (cgbufs != NULL((void *)0)) {
343 for (cnt = 0; cnt < sblock(*sblk.b_un.b_fs).fs_ncg; cnt++) {
344 if (cgbufs[cnt].b_un.b_cg == NULL((void *)0))
345 continue;
346 flush(fswritefd, &cgbufs[cnt]);
347 free(cgbufs[cnt].b_un.b_cg);
348 }
349 free(cgbufs);
350 }
351 pbp = pdirbp = NULL((void *)0);
352 if (markclean && (sblock(*sblk.b_un.b_fs).fs_clean & FS_ISCLEAN0x01) == 0) {
353 /*
354 * Mark the file system as clean, and sync the superblock.
355 */
356 if (preen)
357 pwarn("MARKING FILE SYSTEM CLEAN\n");
358 else if (!reply("MARK FILE SYSTEM CLEAN"))
359 markclean = 0;
360 if (markclean) {
361 sblock(*sblk.b_un.b_fs).fs_clean = FS_ISCLEAN0x01;
362 sbdirty()sblk.b_dirty = 1;
363 flush(fswritefd, &sblk);
364 }
365 }
366 if (debug)
367 printf("cache missed %ld of %ld (%d%%)\n", diskreads,
368 totalreads, (int)(diskreads * 100 / totalreads));
369 (void)close(fsreadfd);
370 fsreadfd = -1;
371 (void)close(fswritefd);
372 fswritefd = -1;
373 sigprocmask(SIG_SETMASK3, &oset, NULL((void *)0));
374}
375
376int
377bread(int fd, char *buf, daddr_t blk, long size)
378{
379 char *cp;
380 int i, errs;
381 off_t offset;
382
383 offset = blk;
384 offset *= DEV_BSIZE(1 << 9);
385 if (pread(fd, buf, size, offset) == size)
386 return (0);
387 rwerror("READ", blk);
388 errs = 0;
389 memset(buf, 0, (size_t)size);
390 printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
391 for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
392 if (pread(fd, cp, secsize, offset + i) != secsize) {
393 if (secsize != DEV_BSIZE(1 << 9))
394 printf(" %lld (%lld),",
395 (long long)(offset + i) / secsize,
396 (long long)blk + i / DEV_BSIZE(1 << 9));
397 else
398 printf(" %lld,", (long long)blk +
399 i / DEV_BSIZE(1 << 9));
400 errs++;
401 }
402 }
403 printf("\n");
404 return (errs);
405}
406
407void
408bwrite(int fd, char *buf, daddr_t blk, long size)
409{
410 int i;
411 char *cp;
412 off_t offset;
413
414 if (fd < 0)
415 return;
416 offset = blk;
417 offset *= DEV_BSIZE(1 << 9);
418 if (pwrite(fd, buf, size, offset) == size) {
419 fsmodified = 1;
420 return;
421 }
422 rwerror("WRITE", blk);
423 printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
424 for (cp = buf, i = 0; i < size; i += secsize, cp += secsize)
425 if (pwrite(fd, cp, secsize, offset + i) != secsize) {
426 if (secsize != DEV_BSIZE(1 << 9))
427 printf(" %lld (%lld),",
428 (long long)(offset + i) / secsize,
429 (long long)blk + i / DEV_BSIZE(1 << 9));
430 else
431 printf(" %lld,", (long long)blk +
432 i / DEV_BSIZE(1 << 9));
433 }
434 printf("\n");
435 return;
436}
437
438/*
439 * allocate a data block with the specified number of fragments
440 */
441daddr_t
442allocblk(int frags)
443{
444 daddr_t i, baseblk;
445 int j, k, cg;
446 struct bufarea *cgbp;
447 struct cg *cgp;
448
449 if (frags <= 0 || frags > sblock(*sblk.b_un.b_fs).fs_frag)
1
Assuming 'frags' is > 0
2
Assuming 'frags' is <= field 'fs_frag'
3
Taking false branch
450 return (0);
451 for (i = 0; i < maxfsblock - sblock(*sblk.b_un.b_fs).fs_frag; i += sblock(*sblk.b_un.b_fs).fs_frag) {
4
Assuming the condition is true
5
Loop condition is true. Entering loop body
452 for (j = 0; j <= sblock(*sblk.b_un.b_fs).fs_frag - frags; j++) {
6
Assuming the condition is true
7
Loop condition is true. Entering loop body
453 if (testbmap(i + j)((blockmap)[(i + j)>>3] & (1<<((i + j)&(8
-1))))
)
8
Assuming the condition is false
9
Taking false branch
454 continue;
455 for (k = 1; k < frags; k++)
10
Assuming 'k' is >= 'frags'
11
Loop condition is false. Execution continues on line 458
456 if (testbmap(i + j + k)((blockmap)[(i + j + k)>>3] & (1<<((i + j + k
)&(8 -1))))
)
457 break;
458 if (k
11.1
'k' is >= 'frags'
< frags) {
12
Taking false branch
459 j += k;
460 continue;
461 }
462 cg = dtog(&sblock, i + j)((i + j) / (&(*sblk.b_un.b_fs))->fs_fpg);
463 cgbp = cglookup(cg);
13
Calling 'cglookup'
23
Returning from 'cglookup'
464 cgp = cgbp->b_un.b_cg;
465 if (!cg_chkmagic(cgp)((cgp)->cg_magic == 0x090255 || ((struct ocg *)(cgp))->
cg_magic == 0x090255)
)
24
The left operand of '==' is a garbage value
466 pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
467 baseblk = dtogd(&sblock, i + j)((i + j) % (&(*sblk.b_un.b_fs))->fs_fpg);
468
469 for (k = 0; k < frags; k++) {
470 setbmap(i + j + k)((blockmap)[(i + j + k)>>3] |= 1<<((i + j + k)&
(8 -1)))
;
471 clrbit(cg_blksfree(cgp), baseblk + k)(((((cgp)->cg_magic != 0x090255) ? (((struct ocg *)(cgp))->
cg_free) : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff
))))[(baseblk + k)>>3] &= ~(1<<((baseblk + k)
&(8 -1))))
;
472 }
473 n_blks += frags;
474 if (frags == sblock(*sblk.b_un.b_fs).fs_frag)
475 cgp->cg_cs.cs_nbfree--;
476 else
477 cgp->cg_cs.cs_nffree -= frags;
478 return (i + j);
479 }
480 }
481 return (0);
482}
483
484/*
485 * Free a previously allocated block
486 */
487void
488freeblk(daddr_t blkno, int frags)
489{
490 struct inodesc idesc;
491
492 idesc.id_blkno = blkno;
493 idesc.id_numfrags = frags;
494 (void)pass4check(&idesc);
495}
496
497/*
498 * Find a pathname
499 */
500void
501getpathname(char *namebuf, size_t namebuflen, ino_t curdir, ino_t ino)
502{
503 int len;
504 char *cp;
505 struct inodesc idesc;
506 static int busy = 0;
507
508 if (curdir == ino && ino == ROOTINO((ufsino_t)2)) {
509 (void)strlcpy(namebuf, "/", namebuflen);
510 return;
511 }
512 if (busy ||
513 (GET_ISTATE(curdir)(inoinfo(curdir)->ino_state) != DSTATE03 && GET_ISTATE(curdir)(inoinfo(curdir)->ino_state) != DFOUND04)) {
514 (void)strlcpy(namebuf, "?", namebuflen);
515 return;
516 }
517 busy = 1;
518 memset(&idesc, 0, sizeof(struct inodesc));
519 idesc.id_type = DATA1;
520 idesc.id_fix = IGNORE;
521 cp = &namebuf[PATH_MAX1024 - 1];
522 *cp = '\0';
523 if (curdir != ino) {
524 idesc.id_parent = curdir;
525 goto namelookup;
526 }
527 while (ino != ROOTINO((ufsino_t)2)) {
528 idesc.id_number = ino;
529 idesc.id_func = findino;
530 idesc.id_name = "..";
531 if ((ckinode(ginode(ino), &idesc) & FOUND0x10) == 0)
532 break;
533 namelookup:
534 idesc.id_number = idesc.id_parent;
535 idesc.id_parent = ino;
536 idesc.id_func = findname;
537 idesc.id_name = namebuf;
538 if ((ckinode(ginode(idesc.id_number), &idesc)&FOUND0x10) == 0)
539 break;
540 len = strlen(namebuf);
541 cp -= len;
542 memmove(cp, namebuf, (size_t)len);
543 *--cp = '/';
544 if (cp < &namebuf[MAXNAMLEN255])
545 break;
546 ino = idesc.id_number;
547 }
548 busy = 0;
549 if (ino != ROOTINO((ufsino_t)2))
550 *--cp = '?';
551 memmove(namebuf, cp, (size_t)(&namebuf[PATH_MAX1024] - cp));
552}
553
554/*ARGSUSED*/
555void
556catch(int signo)
557{
558 ckfini(0); /* XXX signal race */
559 _exit(12);
560}
561
562/*
563 * When preening, allow a single quit to signal
564 * a special exit after filesystem checks complete
565 * so that reboot sequence may be interrupted.
566 */
567/*ARGSUSED*/
568void
569catchquit(int signo)
570{
571 extern volatile sig_atomic_t returntosingle;
572 static const char message[] =
573 "returning to single-user after filesystem check\n";
574
575 write(STDOUT_FILENO1, message, sizeof(message)-1);
576 returntosingle = 1;
577 (void)signal(SIGQUIT3, SIG_DFL(void (*)(int))0);
578}
579
580/*
581 * Ignore a single quit signal; wait and flush just in case.
582 * Used by child processes in preen.
583 */
584/*ARGSUSED*/
585void
586voidquit(int signo)
587{
588 int save_errno = errno(*__errno());
589
590 sleep(1);
591 (void)signal(SIGQUIT3, SIG_IGN(void (*)(int))1);
592 (void)signal(SIGQUIT3, SIG_DFL(void (*)(int))0);
593 errno(*__errno()) = save_errno;
594}
595
596/*
597 * determine whether an inode should be fixed.
598 */
599int
600dofix(struct inodesc *idesc, char *msg)
601{
602 switch (idesc->id_fix) {
603
604 case DONTKNOW:
605 if (idesc->id_type == DATA1)
606 direrror(idesc->id_number, msg);
607 else
608 pwarn("%s", msg);
609 if (preen) {
610 printf(" (SALVAGED)\n");
611 idesc->id_fix = FIX;
612 return (ALTERED0x08);
613 }
614 if (reply("SALVAGE") == 0) {
615 idesc->id_fix = NOFIX;
616 return (0);
617 }
618 idesc->id_fix = FIX;
619 return (ALTERED0x08);
620
621 case FIX:
622 return (ALTERED0x08);
623
624 case NOFIX:
625 case IGNORE:
626 return (0);
627
628 default:
629 errexit("UNKNOWN INODESC FIX MODE %u\n", idesc->id_fix);
630 }
631 /* NOTREACHED */
632}
633
634int (* info_fn)(char *, size_t) = NULL((void *)0);
635char *info_filesys = "?";
636
637/*ARGSUSED*/
638void
639catchinfo(int signo)
640{
641 static int info_fd;
642 int save_errno = errno(*__errno());
643 struct iovec iov[4];
644 char buf[1024];
645
646 if (signo == 0) {
647 info_fd = open(_PATH_TTY"/dev/tty", O_WRONLY0x0001);
648 signal(SIGINFO29, catchinfo);
649 } else if (info_fd > 0 && info_fn != NULL((void *)0) && info_fn(buf, sizeof buf)) {
650 iov[0].iov_base = info_filesys;
651 iov[0].iov_len = strlen(info_filesys);
652 iov[1].iov_base = ": ";
653 iov[1].iov_len = sizeof ": " - 1;
654 iov[2].iov_base = buf;
655 iov[2].iov_len = strlen(buf);
656 iov[3].iov_base = "\n";
657 iov[3].iov_len = sizeof "\n" - 1;
658
659 writev(info_fd, iov, 4);
660 }
661 errno(*__errno()) = save_errno;
662}
663/*
664 * Attempt to flush a cylinder group cache entry.
665 * Return whether the flush was successful.
666 */
667static int
668flushentry(void)
669{
670 struct bufarea *cgbp;
671
672 if (flushtries == sblock(*sblk.b_un.b_fs).fs_ncg || cgbufs == NULL((void *)0))
673 return (0);
674 cgbp = &cgbufs[flushtries++];
675 if (cgbp->b_un.b_cg == NULL((void *)0))
676 return (0);
677 flush(fswritefd, cgbp);
678 free(cgbp->b_un.b_buf);
679 cgbp->b_un.b_buf = NULL((void *)0);
680 return (1);
681}
682
683/*
684 * Wrapper for malloc() that flushes the cylinder group cache to try
685 * to get space.
686 */
687void *
688Malloc(size_t size)
689{
690 void *retval;
691
692 while ((retval = malloc(size)) == NULL((void *)0))
693 if (flushentry() == 0)
694 break;
695 return (retval);
696}
697
698/*
699 * Wrapper for calloc() that flushes the cylinder group cache to try
700 * to get space.
701 */
702void*
703Calloc(size_t cnt, size_t size)
704{
705 void *retval;
706
707 while ((retval = calloc(cnt, size)) == NULL((void *)0))
708 if (flushentry() == 0)
709 break;
710 return (retval);
711}
712
713/*
714 * Wrapper for reallocarray() that flushes the cylinder group cache to try
715 * to get space.
716 */
717void*
718Reallocarray(void *p, size_t cnt, size_t size)
719{
720 void *retval;
721
722 while ((retval = reallocarray(p, cnt, size)) == NULL((void *)0))
723 if (flushentry() == 0)
724 break;
725 return (retval);
726}