Bug Summary

File:src/sbin/dump/traverse.c
Warning:line 908, column 3
Null pointer passed as 2nd argument to memory copy function

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 traverse.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/dump/obj -resource-dir /usr/local/lib/clang/13.0.0 -D RDUMP -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/dump/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/dump/traverse.c
1/* $OpenBSD: traverse.c,v 1.39 2018/04/26 17:40:48 guenther Exp $ */
2/* $NetBSD: traverse.c,v 1.17 1997/06/05 11:13:27 lukem Exp $ */
3
4/*-
5 * Copyright (c) 1980, 1988, 1991, 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> /* MAXBSIZE DEV_BSIZE dbtob */
34#include <sys/time.h>
35#include <sys/stat.h>
36#include <sys/disklabel.h>
37#include <ufs/ffs/fs.h>
38#include <ufs/ufs/dir.h>
39#include <ufs/ufs/dinode.h>
40
41#include <protocols/dumprestore.h>
42
43#include <ctype.h>
44#include <errno(*__errno()).h>
45#include <fts.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <unistd.h>
50#include <limits.h>
51
52#include "dump.h"
53
54extern struct disklabel lab;
55
56union dinode {
57 struct ufs1_dinode dp1;
58 struct ufs2_dinode dp2;
59};
60#define DIP(dp, field)((sblock->fs_magic == 0x011954) ? (dp)->dp1.field : (dp
)->dp2.field)
\
61 ((sblock->fs_magic == FS_UFS1_MAGIC0x011954) ? \
62 (dp)->dp1.field : (dp)->dp2.field)
63
64#define HASDUMPEDFILE0x1 0x1
65#define HASSUBDIRS0x2 0x2
66
67static int dirindir(ino_t, daddr_t, int, off_t *, int64_t *, int);
68static void dmpindir(ino_t, daddr_t, int, off_t *);
69static int searchdir(ino_t, daddr_t, long, off_t, int64_t *, int);
70void fs_mapinodes(ino_t maxino, off_t *tapesize, int *anydirskipped);
71
72/*
73 * This is an estimation of the number of TP_BSIZE blocks in the file.
74 * It estimates the number of blocks in files with holes by assuming
75 * that all of the blocks accounted for by di_blocks are data blocks
76 * (when some of the blocks are usually used for indirect pointers);
77 * hence the estimate may be high.
78 */
79int64_t
80blockest(union dinode *dp)
81{
82 int64_t blkest, sizeest;
83
84 /*
85 * dp->di_size is the size of the file in bytes.
86 * dp->di_blocks stores the number of sectors actually in the file.
87 * If there are more sectors than the size would indicate, this just
88 * means that there are indirect blocks in the file or unused
89 * sectors in the last file block; we can safely ignore these
90 * (blkest = sizeest below).
91 * If the file is bigger than the number of sectors would indicate,
92 * then the file has holes in it. In this case we must use the
93 * block count to estimate the number of data blocks used, but
94 * we use the actual size for estimating the number of indirect
95 * dump blocks (sizeest vs. blkest in the indirect block
96 * calculation).
97 */
98 blkest = howmany(dbtob((int64_t)DIP(dp, di_blocks)), TP_BSIZE)((((((int64_t)((sblock->fs_magic == 0x011954) ? (dp)->dp1
.di_blocks : (dp)->dp2.di_blocks)) << 9)) + ((1024) -
1)) / (1024))
;
99 sizeest = howmany((int64_t)DIP(dp, di_size), TP_BSIZE)((((int64_t)((sblock->fs_magic == 0x011954) ? (dp)->dp1
.di_size : (dp)->dp2.di_size)) + ((1024) - 1)) / (1024))
;
100 if (blkest > sizeest)
101 blkest = sizeest;
102 if (DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
> sblock->fs_bsize * NDADDR12) {
103 /* calculate the number of indirect blocks on the dump tape */
104 blkest +=
105 howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE,(((sizeest - 12 * sblock->fs_bsize / 1024) + (((1024/2)) -
1)) / ((1024/2)))
106 TP_NINDIR)(((sizeest - 12 * sblock->fs_bsize / 1024) + (((1024/2)) -
1)) / ((1024/2)))
;
107 }
108 return (blkest + 1);
109}
110
111/* true if "nodump" flag has no effect here, i.e. dumping allowed */
112#define CHECKNODUMP(dp)(nonodump || (((sblock->fs_magic == 0x011954) ? ((dp))->
dp1.di_flags : ((dp))->dp2.di_flags) & 0x00000001) != 0x00000001
)
\
113 (nonodump || (DIP((dp), di_flags)((sblock->fs_magic == 0x011954) ? ((dp))->dp1.di_flags :
((dp))->dp2.di_flags)
& UF_NODUMP0x00000001) != UF_NODUMP0x00000001)
114
115/*
116 * Determine if given inode should be dumped
117 */
118void
119mapfileino(ino_t ino, int64_t *tapesize, int *dirskipped)
120{
121 int mode;
122 union dinode *dp;
123
124 dp = getino(ino, &mode);
125 if (mode == 0)
126 return;
127 SETINO(ino, usedinomap)usedinomap[(u_int)((ino) - 1) / 8] |= 1 << ((u_int)((ino
) - 1) % 8)
;
128 if (mode == IFDIR0040000)
129 SETINO(ino, dumpdirmap)dumpdirmap[(u_int)((ino) - 1) / 8] |= 1 << ((u_int)((ino
) - 1) % 8)
;
130 if (CHECKNODUMP(dp)(nonodump || (((sblock->fs_magic == 0x011954) ? ((dp))->
dp1.di_flags : ((dp))->dp2.di_flags) & 0x00000001) != 0x00000001
)
&&
131 (DIP(dp, di_mtime)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_mtime : (
dp)->dp2.di_mtime)
>= spclu_spcl.s_spcl.c_ddate ||
132 DIP(dp, di_ctime)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_ctime : (
dp)->dp2.di_ctime)
>= spclu_spcl.s_spcl.c_ddate)) {
133 SETINO(ino, dumpinomap)dumpinomap[(u_int)((ino) - 1) / 8] |= 1 << ((u_int)((ino
) - 1) % 8)
;
134 if (mode != IFREG0100000 && mode != IFDIR0040000 && mode != IFLNK0120000)
135 *tapesize += 1;
136 else
137 *tapesize += blockest(dp);
138 return;
139 }
140 if (mode == IFDIR0040000) {
141 if (!CHECKNODUMP(dp)(nonodump || (((sblock->fs_magic == 0x011954) ? ((dp))->
dp1.di_flags : ((dp))->dp2.di_flags) & 0x00000001) != 0x00000001
)
)
142 CLRINO(ino, usedinomap)usedinomap[(u_int)((ino) - 1) / 8] &= ~(1 << ((u_int
)((ino) - 1) % 8))
;
143 *dirskipped = 1;
144 }
145}
146
147void
148fs_mapinodes(ino_t maxino, int64_t *tapesize, int *anydirskipped)
149{
150 int i, cg, inosused;
151 struct cg *cgp;
152 ino_t ino;
153 char *cp;
154
155 if ((cgp = malloc(sblock->fs_cgsize)) == NULL((void *)0))
156 quit("fs_mapinodes: cannot allocate memory.\n");
157
158 for (cg = 0; cg < sblock->fs_ncg; cg++) {
159 ino = cg * (ino_t)sblock->fs_ipg;
160 bread(fsbtodb(sblock, cgtod(sblock, cg))((((((daddr_t)(sblock)->fs_fpg * (cg)) + (sblock)->fs_cgoffset
* ((cg) & ~((sblock)->fs_cgmask))) + (sblock)->fs_cblkno
)) << (sblock)->fs_fsbtodb)
, (char *)cgp,
161 sblock->fs_cgsize);
162 if (sblock->fs_magic == FS_UFS2_MAGIC0x19540119)
163 inosused = cgp->cg_initediblk;
164 else
165 inosused = sblock->fs_ipg;
166 /*
167 * If we are using soft updates, then we can trust the
168 * cylinder group inode allocation maps to tell us which
169 * inodes are allocated. We will scan the used inode map
170 * to find the inodes that are really in use, and then
171 * read only those inodes in from disk.
172 */
173 if (sblock->fs_flags & FS_DOSOFTDEP0x02) {
174 if (!cg_chkmagic(cgp)((cgp)->cg_magic == 0x090255 || ((struct ocg *)(cgp))->
cg_magic == 0x090255)
)
175 quit("mapfiles: cg %d: bad magic number\n", cg);
176 cp = &cg_inosused(cgp)(((cgp)->cg_magic != 0x090255) ? (((struct ocg *)(cgp))->
cg_iused) : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff
)))
[(inosused - 1) / CHAR_BIT8];
177 for ( ; inosused > 0; inosused -= CHAR_BIT8, cp--) {
178 if (*cp == 0)
179 continue;
180 for (i = 1 << (CHAR_BIT8 - 1); i > 0; i >>= 1) {
181 if (*cp & i)
182 break;
183 inosused--;
184 }
185 break;
186 }
187 if (inosused <= 0)
188 continue;
189 }
190 for (i = 0; i < inosused; i++, ino++) {
191 if (ino < ROOTINO((ufsino_t)2))
192 continue;
193 mapfileino(ino, tapesize, anydirskipped);
194 }
195 }
196
197 free(cgp);
198}
199
200/*
201 * Dump pass 1.
202 *
203 * Walk the inode list for a filesystem to find all allocated inodes
204 * that have been modified since the previous dump time. Also, find all
205 * the directories in the filesystem.
206 */
207int
208mapfiles(ino_t maxino, int64_t *tapesize, char *disk, char * const *dirv)
209{
210 int anydirskipped = 0;
211
212 if (dirv != NULL((void *)0)) {
213 char curdir[PATH_MAX1024];
214 FTS *dirh;
215 FTSENT *entry;
216 int d;
217
218 if (getcwd(curdir, sizeof(curdir)) == NULL((void *)0)) {
219 msg("Can't determine cwd: %s\n", strerror(errno(*__errno())));
220 dumpabort(0);
221 }
222 if ((dirh = fts_open(dirv, FTS_PHYSICAL0x0010|FTS_SEEDOT0x0020|FTS_XDEV0x0040,
223 NULL((void *)0))) == NULL((void *)0)) {
224 msg("fts_open failed: %s\n", strerror(errno(*__errno())));
225 dumpabort(0);
226 }
227 while ((entry = fts_read(dirh)) != NULL((void *)0)) {
228 switch (entry->fts_info) {
229 case FTS_DNR4: /* an error */
230 case FTS_ERR7:
231 case FTS_NS10:
232 msg("Can't fts_read %s: %s\n", entry->fts_path,
233 strerror(errno(*__errno())));
234 /* FALLTHROUGH */
235 case FTS_DP6: /* already seen dir */
236 continue;
237 }
238 mapfileino(entry->fts_statp->st_ino, tapesize,
239 &anydirskipped);
240 }
241 if (errno(*__errno())) {
242 msg("fts_read failed: %s\n", strerror(errno(*__errno())));
243 dumpabort(0);
244 }
245 (void)fts_close(dirh);
246
247 /*
248 * Add any parent directories
249 */
250 for (d = 0 ; dirv[d] != NULL((void *)0) ; d++) {
251 char path[PATH_MAX1024];
252
253 if (dirv[d][0] != '/')
254 (void)snprintf(path, sizeof(path), "%s/%s",
255 curdir, dirv[d]);
256 else
257 (void)snprintf(path, sizeof(path), "%s",
258 dirv[d]);
259 while (strcmp(path, disk) != 0) {
260 char *p;
261 struct stat sb;
262
263 if (*path == '\0')
264 break;
265 if ((p = strrchr(path, '/')) == NULL((void *)0))
266 break;
267 if (p == path)
268 break;
269 *p = '\0';
270 if (stat(path, &sb) == -1) {
271 msg("Can't stat %s: %s\n", path,
272 strerror(errno(*__errno())));
273 break;
274 }
275 mapfileino(sb.st_ino, tapesize, &anydirskipped);
276 }
277 }
278
279 /*
280 * Ensure that the root inode actually appears in the
281 * file list for a subdir
282 */
283 mapfileino(ROOTINO((ufsino_t)2), tapesize, &anydirskipped);
284 } else {
285 fs_mapinodes(maxino, tapesize, &anydirskipped);
286 }
287 /*
288 * Restore gets very upset if the root is not dumped,
289 * so ensure that it always is dumped.
290 */
291 SETINO(ROOTINO, dumpinomap)dumpinomap[(u_int)((((ufsino_t)2)) - 1) / 8] |= 1 << ((
u_int)((((ufsino_t)2)) - 1) % 8)
;
292 return (anydirskipped);
293}
294
295/*
296 * Dump pass 2.
297 *
298 * Scan each directory on the filesystem to see if it has any modified
299 * files in it. If it does, and has not already been added to the dump
300 * list (because it was itself modified), then add it. If a directory
301 * has not been modified itself, contains no modified files and has no
302 * subdirectories, then it can be deleted from the dump list and from
303 * the list of directories. By deleting it from the list of directories,
304 * its parent may now qualify for the same treatment on this or a later
305 * pass using this algorithm.
306 */
307int
308mapdirs(ino_t maxino, int64_t *tapesize)
309{
310 union dinode *dp;
311 int i, isdir, nodump;
312 char *map;
313 ino_t ino;
314 union dinode di;
315 off_t filesize;
316 int ret, change = 0;
317
318 isdir = 0; /* XXX just to get gcc to shut up */
319 for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
320 if (((ino - 1) % NBBY8) == 0) /* map is offset by 1 */
321 isdir = *map++;
322 else
323 isdir >>= 1;
324 /*
325 * If a directory has been removed from usedinomap, it
326 * either has the nodump flag set, or has inherited
327 * it. Although a directory can't be in dumpinomap if
328 * it isn't in usedinomap, we have to go through it to
329 * propagate the nodump flag.
330 */
331 nodump = !nonodump && !TSTINO(ino, usedinomap)(usedinomap[(u_int)((ino) - 1) / 8] & (1 << ((u_int
)((ino) - 1) % 8)))
;
332 if ((isdir & 1) == 0 || (TSTINO(ino, dumpinomap)(dumpinomap[(u_int)((ino) - 1) / 8] & (1 << ((u_int
)((ino) - 1) % 8)))
&& !nodump))
333 continue;
334 dp = getino(ino, &i);
335 /*
336 * inode buf may change in searchdir().
337 */
338 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
339 di.dp1 = dp->dp1;
340 else
341 di.dp2 = dp->dp2;
342 filesize = (off_t)DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
;
343 for (ret = 0, i = 0; filesize > 0 && i < NDADDR12; i++) {
344 if (DIP(&di, di_db[i])((sblock->fs_magic == 0x011954) ? (&di)->dp1.di_db[
i] : (&di)->dp2.di_db[i])
!= 0)
345 ret |= searchdir(ino, DIP(&di, di_db[i])((sblock->fs_magic == 0x011954) ? (&di)->dp1.di_db[
i] : (&di)->dp2.di_db[i])
,
346 sblksize(sblock, DIP(dp, di_size), i)(((i) >= 12 || (((sblock->fs_magic == 0x011954) ? (dp)->
dp1.di_size : (dp)->dp2.di_size)) >= ((i) + 1) <<
(sblock)->fs_bshift) ? (u_int64_t)(sblock)->fs_bsize :
(((((((((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size
: (dp)->dp2.di_size))) & (sblock)->fs_qbmask)) + (
sblock)->fs_qfmask) & (sblock)->fs_fmask)))
,
347 filesize, tapesize, nodump);
348 if (ret & HASDUMPEDFILE0x1)
349 filesize = 0;
350 else
351 filesize -= sblock->fs_bsize;
352 }
353 for (i = 0; filesize > 0 && i < NIADDR3; i++) {
354 if (DIP(&di, di_ib[i])((sblock->fs_magic == 0x011954) ? (&di)->dp1.di_ib[
i] : (&di)->dp2.di_ib[i])
== 0)
355 continue;
356 ret |= dirindir(ino, DIP(&di, di_ib[i])((sblock->fs_magic == 0x011954) ? (&di)->dp1.di_ib[
i] : (&di)->dp2.di_ib[i])
, i, &filesize,
357 tapesize, nodump);
358 }
359 if (ret & HASDUMPEDFILE0x1) {
360 SETINO(ino, dumpinomap)dumpinomap[(u_int)((ino) - 1) / 8] |= 1 << ((u_int)((ino
) - 1) % 8)
;
361 *tapesize += blockest(dp);
362 change = 1;
363 continue;
364 }
365 if (nodump) {
366 if (ret & HASSUBDIRS0x2)
367 change = 1; /* subdirs inherit nodump */
368 CLRINO(ino, dumpdirmap)dumpdirmap[(u_int)((ino) - 1) / 8] &= ~(1 << ((u_int
)((ino) - 1) % 8))
;
369 } else if ((ret & HASSUBDIRS0x2) == 0) {
370 if (!TSTINO(ino, dumpinomap)(dumpinomap[(u_int)((ino) - 1) / 8] & (1 << ((u_int
)((ino) - 1) % 8)))
) {
371 CLRINO(ino, dumpdirmap)dumpdirmap[(u_int)((ino) - 1) / 8] &= ~(1 << ((u_int
)((ino) - 1) % 8))
;
372 change = 1;
373 }
374 }
375 }
376 return (change);
377}
378
379/*
380 * Read indirect blocks, and pass the data blocks to be searched
381 * as directories. Quit as soon as any entry is found that will
382 * require the directory to be dumped.
383 */
384static int
385dirindir(ino_t ino, daddr_t blkno, int ind_level, off_t *filesize,
386 int64_t *tapesize, int nodump)
387{
388 int ret = 0;
389 int i;
390 char idblk[MAXBSIZE(64 * 1024)];
391
392 bread(fsbtodb(sblock, blkno)((blkno) << (sblock)->fs_fsbtodb), idblk, (int)sblock->fs_bsize);
393 if (ind_level <= 0) {
394 for (i = 0; *filesize > 0 && i < NINDIR(sblock)((sblock)->fs_nindir); i++) {
395 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
396 blkno = ((int32_t *)idblk)[i];
397 else
398 blkno = ((int64_t *)idblk)[i];
399 if (blkno != 0)
400 ret |= searchdir(ino, blkno, sblock->fs_bsize,
401 *filesize, tapesize, nodump);
402 if (ret & HASDUMPEDFILE0x1)
403 *filesize = 0;
404 else
405 *filesize -= sblock->fs_bsize;
406 }
407 return (ret);
408 }
409 ind_level--;
410 for (i = 0; *filesize > 0 && i < NINDIR(sblock)((sblock)->fs_nindir); i++) {
411 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
412 blkno = ((int32_t *)idblk)[i];
413 else
414 blkno = ((int64_t *)idblk)[i];
415 if (blkno != 0)
416 ret |= dirindir(ino, blkno, ind_level, filesize,
417 tapesize, nodump);
418 }
419 return (ret);
420}
421
422/*
423 * Scan a disk block containing directory information looking to see if
424 * any of the entries are on the dump list and to see if the directory
425 * contains any subdirectories.
426 */
427static int
428searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize,
429 int64_t *tapesize, int nodump)
430{
431 struct direct *dp;
432 union dinode *ip;
433 long loc;
434 static caddr_t dblk;
435 int mode, ret = 0;
436
437 if (dblk == NULL((void *)0) && (dblk = malloc(sblock->fs_bsize)) == NULL((void *)0))
438 quit("searchdir: cannot allocate indirect memory.\n");
439 bread(fsbtodb(sblock, blkno)((blkno) << (sblock)->fs_fsbtodb), dblk, (int)size);
440 if (filesize < size)
441 size = filesize;
442 for (loc = 0; loc < size; ) {
443 dp = (struct direct *)(dblk + loc);
444 if (dp->d_reclen == 0) {
445 msg("corrupted directory, inumber %llu\n",
446 (unsigned long long)ino);
447 break;
448 }
449 loc += dp->d_reclen;
450 if (dp->d_ino == 0)
451 continue;
452 if (dp->d_name[0] == '.') {
453 if (dp->d_name[1] == '\0')
454 continue;
455 if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
456 continue;
457 }
458 if (nodump) {
459 ip = getino(dp->d_ino, &mode);
460 if (TSTINO(dp->d_ino, dumpinomap)(dumpinomap[(u_int)((dp->d_ino) - 1) / 8] & (1 <<
((u_int)((dp->d_ino) - 1) % 8)))
) {
461 CLRINO(dp->d_ino, dumpinomap)dumpinomap[(u_int)((dp->d_ino) - 1) / 8] &= ~(1 <<
((u_int)((dp->d_ino) - 1) % 8))
;
462 *tapesize -= blockest(ip);
463 }
464 /*
465 * Add back to dumpdirmap and remove from usedinomap
466 * to propagate nodump.
467 */
468 if (mode == IFDIR0040000) {
469 SETINO(dp->d_ino, dumpdirmap)dumpdirmap[(u_int)((dp->d_ino) - 1) / 8] |= 1 << ((u_int
)((dp->d_ino) - 1) % 8)
;
470 CLRINO(dp->d_ino, usedinomap)usedinomap[(u_int)((dp->d_ino) - 1) / 8] &= ~(1 <<
((u_int)((dp->d_ino) - 1) % 8))
;
471 ret |= HASSUBDIRS0x2;
472 }
473 } else {
474 if (TSTINO(dp->d_ino, dumpinomap)(dumpinomap[(u_int)((dp->d_ino) - 1) / 8] & (1 <<
((u_int)((dp->d_ino) - 1) % 8)))
) {
475 ret |= HASDUMPEDFILE0x1;
476 if (ret & HASSUBDIRS0x2)
477 break;
478 }
479 if (TSTINO(dp->d_ino, dumpdirmap)(dumpdirmap[(u_int)((dp->d_ino) - 1) / 8] & (1 <<
((u_int)((dp->d_ino) - 1) % 8)))
) {
480 ret |= HASSUBDIRS0x2;
481 if (ret & HASDUMPEDFILE0x1)
482 break;
483 }
484 }
485 }
486 return (ret);
487}
488
489/*
490 * Dump passes 3 and 4.
491 *
492 * Dump the contents of an inode to tape.
493 */
494void
495dumpino(union dinode *dp, ino_t ino)
496{
497 int ind_level, cnt;
498 off_t size;
499 char buf[TP_BSIZE1024];
500
501 if (newtape) {
1
Assuming 'newtape' is 0
2
Taking false branch
502 newtape = 0;
503 dumpmap(dumpinomap, TS_BITS3, ino);
504 }
505 CLRINO(ino, dumpinomap)dumpinomap[(u_int)((ino) - 1) / 8] &= ~(1 << ((u_int
)((ino) - 1) % 8))
;
506 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954) {
3
Assuming field 'fs_magic' is not equal to FS_UFS1_MAGIC
4
Taking false branch
507 spclu_spcl.s_spcl.c_mode__c_ino.__uc_ino.__uc_mode = dp->dp1.di_mode;
508 spclu_spcl.s_spcl.c_size__c_ino.__uc_ino.__uc_size = dp->dp1.di_size;
509 spclu_spcl.s_spcl.c_old_atime__c_ino.__uc_ino.__uc_old_atime = (time_t)dp->dp1.di_atime;
510 spclu_spcl.s_spcl.c_atime__c_ino.__uc_ino.__uc_atime = dp->dp1.di_atime;
511 spclu_spcl.s_spcl.c_atimensec__c_ino.__uc_ino.__uc_atimensec = dp->dp1.di_atimensec;
512 spclu_spcl.s_spcl.c_old_mtime__c_ino.__uc_ino.__uc_old_mtime = (time_t)dp->dp1.di_mtime;
513 spclu_spcl.s_spcl.c_mtime__c_ino.__uc_ino.__uc_mtime = dp->dp1.di_mtime;
514 spclu_spcl.s_spcl.c_mtimensec__c_ino.__uc_ino.__uc_mtimensec = dp->dp1.di_mtimensec;
515 spclu_spcl.s_spcl.c_birthtime__c_ino.__uc_ino.__uc_birthtime = 0;
516 spclu_spcl.s_spcl.c_birthtimensec__c_ino.__uc_ino.__uc_birthtimensec = 0;
517 spclu_spcl.s_spcl.c_rdev__c_ino.__uc_ino.__uc_rdev = dp->dp1.di_rdevdi_db[0];
518 spclu_spcl.s_spcl.c_file_flags__c_ino.__uc_ino.__uc_file_flags = dp->dp1.di_flags;
519 spclu_spcl.s_spcl.c_uid__c_ino.__uc_ino.__uc_uid = dp->dp1.di_uid;
520 spclu_spcl.s_spcl.c_gid__c_ino.__uc_ino.__uc_gid = dp->dp1.di_gid;
521 } else {
522 spclu_spcl.s_spcl.c_mode__c_ino.__uc_ino.__uc_mode = dp->dp2.di_mode;
523 spclu_spcl.s_spcl.c_size__c_ino.__uc_ino.__uc_size = dp->dp2.di_size;
524 spclu_spcl.s_spcl.c_atime__c_ino.__uc_ino.__uc_atime = dp->dp2.di_atime;
525 spclu_spcl.s_spcl.c_atimensec__c_ino.__uc_ino.__uc_atimensec = dp->dp2.di_atimensec;
526 spclu_spcl.s_spcl.c_mtime__c_ino.__uc_ino.__uc_mtime = dp->dp2.di_mtime;
527 spclu_spcl.s_spcl.c_mtimensec__c_ino.__uc_ino.__uc_mtimensec = dp->dp2.di_mtimensec;
528 spclu_spcl.s_spcl.c_birthtime__c_ino.__uc_ino.__uc_birthtime = dp->dp2.di_birthtime;
529 spclu_spcl.s_spcl.c_birthtimensec__c_ino.__uc_ino.__uc_birthtimensec = dp->dp2.di_birthnsec;
530 spclu_spcl.s_spcl.c_rdev__c_ino.__uc_ino.__uc_rdev = dp->dp2.di_rdevdi_db[0];
531 spclu_spcl.s_spcl.c_file_flags__c_ino.__uc_ino.__uc_file_flags = dp->dp2.di_flags;
532 spclu_spcl.s_spcl.c_uid__c_ino.__uc_ino.__uc_uid = dp->dp2.di_uid;
533 spclu_spcl.s_spcl.c_gid__c_ino.__uc_ino.__uc_gid = dp->dp2.di_gid;
534 }
535 spclu_spcl.s_spcl.c_type = TS_INODE2;
536 spclu_spcl.s_spcl.c_count = 0;
537 switch (DIP(dp, di_mode)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_mode : (
dp)->dp2.di_mode)
& S_IFMT0170000) {
5
'?' condition is false
6
Control jumps to 'case 16384:' at line 573
538
539 case 0:
540 /*
541 * Freed inode.
542 */
543 return;
544
545 case IFLNK0120000:
546 /*
547 * Check for short symbolic link.
548 */
549 if (DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
> 0 &&
550#ifdef FS_44INODEFMT2
551 (DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
< sblock->fs_maxsymlinklen ||
552 (sblock->fs_maxsymlinklen == 0 &&
553 DIP(dp, di_blocks)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_blocks :
(dp)->dp2.di_blocks)
== 0))) {
554#else
555 DIP(dp, di_blocks)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_blocks :
(dp)->dp2.di_blocks)
== 0) {
556#endif
557 void *shortlink;
558
559 spclu_spcl.s_spcl.c_addr[0] = 1;
560 spclu_spcl.s_spcl.c_count = 1;
561 writeheader(ino);
562 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
563 shortlink = dp->dp1.di_shortlinkdi_db;
564 else
565 shortlink = dp->dp2.di_shortlinkdi_db;
566 memcpy(buf, shortlink, DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
);
567 buf[DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
] = '\0';
568 writerec(buf, 0);
569 return;
570 }
571 /* FALLTHROUGH */
572
573 case IFDIR0040000:
574 case IFREG0100000:
575 if (DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
> 0
)
7
'?' condition is false
8
Assuming the condition is true
9
Taking true branch
576 break;
10
Execution continues on line 591
577 /* FALLTHROUGH */
578
579 case IFIFO0010000:
580 case IFSOCK0140000:
581 case IFCHR0020000:
582 case IFBLK0060000:
583 writeheader(ino);
584 return;
585
586 default:
587 msg("Warning: undefined file type 0%o\n",
588 DIP(dp, di_mode)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_mode : (
dp)->dp2.di_mode)
& IFMT0170000);
589 return;
590 }
591 if (DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
> NDADDR12 * sblock->fs_bsize
)
11
'?' condition is false
12
Assuming the condition is false
13
Taking false branch
592 cnt = NDADDR12 * sblock->fs_frag;
593 else
594 cnt = howmany(DIP(dp, di_size), sblock->fs_fsize)(((((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size :
(dp)->dp2.di_size)) + ((sblock->fs_fsize) - 1)) / (sblock
->fs_fsize))
;
14
'?' condition is false
595 if (sblock->fs_magic
14.1
Field 'fs_magic' is not equal to FS_UFS1_MAGIC
== FS_UFS1_MAGIC0x011954)
15
Taking false branch
596 ufs1_blksout(&dp->dp1.di_db[0], cnt, ino);
597 else
598 ufs2_blksout(&dp->dp2.di_db[0], cnt, ino);
599 if ((size = DIP(dp, di_size)((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_size : (
dp)->dp2.di_size)
- NDADDR12 * sblock->fs_bsize) <= 0
)
16
'?' condition is false
17
Assuming the condition is false
18
Taking false branch
600 return;
601 for (ind_level = 0; ind_level < NIADDR3; ind_level++) {
19
Loop condition is true. Entering loop body
602 dmpindir(ino, DIP(dp, di_ib[ind_level])((sblock->fs_magic == 0x011954) ? (dp)->dp1.di_ib[ind_level
] : (dp)->dp2.di_ib[ind_level])
, ind_level, &size)
;
20
'?' condition is false
21
Calling 'dmpindir'
603 if (size <= 0)
604 return;
605 }
606}
607
608/*
609 * Read indirect blocks, and pass the data blocks to be dumped.
610 */
611static void
612dmpindir(ino_t ino, daddr_t blk, int ind_level, off_t *size)
613{
614 int i, cnt;
615 char idblk[MAXBSIZE(64 * 1024)];
616
617 if (blk != 0)
22
Assuming 'blk' is not equal to 0
23
Taking true branch
618 bread(fsbtodb(sblock, blk)((blk) << (sblock)->fs_fsbtodb), idblk, (int) sblock->fs_bsize);
24
Calling 'bread'
619 else
620 memset(idblk, 0, (int)sblock->fs_bsize);
621 if (ind_level <= 0) {
622 if (*size < NINDIR(sblock)((sblock)->fs_nindir) * sblock->fs_bsize)
623 cnt = howmany(*size, sblock->fs_fsize)(((*size) + ((sblock->fs_fsize) - 1)) / (sblock->fs_fsize
))
;
624 else
625 cnt = NINDIR(sblock)((sblock)->fs_nindir) * sblock->fs_frag;
626 *size -= NINDIR(sblock)((sblock)->fs_nindir) * sblock->fs_bsize;
627 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
628 ufs1_blksout((int32_t *)idblk, cnt, ino);
629 else
630 ufs2_blksout((int64_t *)idblk, cnt, ino);
631 return;
632 }
633 ind_level--;
634 for (i = 0; i < NINDIR(sblock)((sblock)->fs_nindir); i++) {
635 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954)
636 dmpindir(ino, ((int32_t *)idblk)[i], ind_level,
637 size);
638 else
639 dmpindir(ino, ((int64_t *)idblk)[i], ind_level,
640 size);
641 if (*size <= 0)
642 return;
643 }
644}
645
646/*
647 * Collect up the data into tape record sized buffers and output them.
648 */
649void
650ufs1_blksout(int32_t *blkp, int frags, ino_t ino)
651{
652 int32_t *bp;
653 int i, j, count, blks, tbperdb;
654
655 blks = howmany(frags * sblock->fs_fsize, TP_BSIZE)(((frags * sblock->fs_fsize) + ((1024) - 1)) / (1024));
656 tbperdb = sblock->fs_bsize >> tp_bshift;
657 for (i = 0; i < blks; i += TP_NINDIR(1024/2)) {
658 if (i + TP_NINDIR(1024/2) > blks)
659 count = blks;
660 else
661 count = i + TP_NINDIR(1024/2);
662 for (j = i; j < count; j++)
663 if (blkp[j / tbperdb] != 0)
664 spclu_spcl.s_spcl.c_addr[j - i] = 1;
665 else
666 spclu_spcl.s_spcl.c_addr[j - i] = 0;
667 spclu_spcl.s_spcl.c_count = count - i;
668 writeheader(ino);
669 bp = &blkp[i / tbperdb];
670 for (j = i; j < count; j += tbperdb, bp++)
671 if (*bp != 0) {
672 if (j + tbperdb <= count)
673 dumpblock(*bp, (int)sblock->fs_bsize);
674 else
675 dumpblock(*bp, (count - j) * TP_BSIZE1024);
676 }
677 spclu_spcl.s_spcl.c_type = TS_ADDR4;
678 }
679}
680
681/*
682 * Collect up the data into tape record sized buffers and output them.
683 */
684void
685ufs2_blksout(daddr_t *blkp, int frags, ino_t ino)
686{
687 daddr_t *bp;
688 int i, j, count, blks, tbperdb;
689
690 blks = howmany(frags * sblock->fs_fsize, TP_BSIZE)(((frags * sblock->fs_fsize) + ((1024) - 1)) / (1024));
691 tbperdb = sblock->fs_bsize >> tp_bshift;
692 for (i = 0; i < blks; i += TP_NINDIR(1024/2)) {
693 if (i + TP_NINDIR(1024/2) > blks)
694 count = blks;
695 else
696 count = i + TP_NINDIR(1024/2);
697 for (j = i; j < count; j++)
698 if (blkp[j / tbperdb] != 0)
699 spclu_spcl.s_spcl.c_addr[j - i] = 1;
700 else
701 spclu_spcl.s_spcl.c_addr[j - i] = 0;
702 spclu_spcl.s_spcl.c_count = count - i;
703 writeheader(ino);
704 bp = &blkp[i / tbperdb];
705 for (j = i; j < count; j += tbperdb, bp++)
706 if (*bp != 0) {
707 if (j + tbperdb <= count)
708 dumpblock(*bp, (int)sblock->fs_bsize);
709 else
710 dumpblock(*bp, (count - j) * TP_BSIZE1024);
711 }
712 spclu_spcl.s_spcl.c_type = TS_ADDR4;
713 }
714}
715
716/*
717 * Dump a map to the tape.
718 */
719void
720dumpmap(map, type, ino)
721 char *map;
722 int type;
723 ino_t ino;
724{
725 int i;
726 char *cp;
727
728 spclu_spcl.s_spcl.c_type = type;
729 spclu_spcl.s_spcl.c_count = howmany(mapsize * sizeof(char), TP_BSIZE)(((mapsize * sizeof(char)) + ((1024) - 1)) / (1024));
730 writeheader(ino);
731 for (i = 0, cp = map; i < spclu_spcl.s_spcl.c_count; i++, cp += TP_BSIZE1024)
732 writerec(cp, 0);
733}
734
735/*
736 * Write a header record to the dump tape.
737 */
738void
739writeheader(ino)
740 ino_t ino;
741{
742 int32_t sum, cnt, *lp;
743
744 spclu_spcl.s_spcl.c_inumber = ino;
745 if (sblock->fs_magic == FS_UFS2_MAGIC0x19540119) {
746 spclu_spcl.s_spcl.c_magic = FS_UFS2_MAGIC0x19540119;
747 } else {
748 spclu_spcl.s_spcl.c_magic = NFS_MAGIC(int)60012;
749 spclu_spcl.s_spcl.c_old_date = (int32_t)spclu_spcl.s_spcl.c_date;
750 spclu_spcl.s_spcl.c_old_ddate = (int32_t)spclu_spcl.s_spcl.c_ddate;
751 spclu_spcl.s_spcl.c_old_tapea = (int32_t)spclu_spcl.s_spcl.c_tapea;
752 spclu_spcl.s_spcl.c_old_firstrec = (int32_t)spclu_spcl.s_spcl.c_firstrec;
753 }
754 spclu_spcl.s_spcl.c_checksum = 0;
755 lp = (int32_t *)&spclu_spcl.s_spcl;
756 sum = 0;
757 cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t));
758 while (--cnt >= 0) {
759 sum += *lp++;
760 sum += *lp++;
761 sum += *lp++;
762 sum += *lp++;
763 }
764 spclu_spcl.s_spcl.c_checksum = CHECKSUM(int)84446 - sum;
765 writerec((char *)&spclu_spcl.s_spcl, 1);
766}
767
768union dinode *
769getino(ino_t inum, int *modep)
770{
771 static ino_t minino, maxino;
772 static void *inoblock;
773 struct ufs1_dinode *dp1;
774 struct ufs2_dinode *dp2;
775
776 if (inoblock == NULL((void *)0) && (inoblock = malloc(sblock->fs_bsize)) == NULL((void *)0))
777 quit("cannot allocate inode memory.\n");
778 curino = inum;
779 if (inum >= minino && inum < maxino)
780 goto gotit;
781 bread(fsbtodb(sblock, ino_to_fsba(sblock, inum))((((daddr_t)(((((daddr_t)(sblock)->fs_fpg * (((inum) / (sblock
)->fs_ipg))) + (sblock)->fs_cgoffset * ((((inum) / (sblock
)->fs_ipg)) & ~((sblock)->fs_cgmask))) + (sblock)->
fs_iblkno) + ((((((inum) % (sblock)->fs_ipg) / ((sblock)->
fs_inopb))) << ((sblock))->fs_fragshift))))) <<
(sblock)->fs_fsbtodb)
, inoblock,
782 (int)sblock->fs_bsize);
783 minino = inum - (inum % INOPB(sblock)((sblock)->fs_inopb));
784 maxino = minino + INOPB(sblock)((sblock)->fs_inopb);
785gotit:
786 if (sblock->fs_magic == FS_UFS1_MAGIC0x011954) {
787 dp1 = &((struct ufs1_dinode *)inoblock)[inum - minino];
788 *modep = (dp1->di_mode & IFMT0170000);
789 return ((union dinode *)dp1);
790 }
791 dp2 = &((struct ufs2_dinode *)inoblock)[inum - minino];
792 *modep = (dp2->di_mode & IFMT0170000);
793 return ((union dinode *)dp2);
794}
795
796/*
797 * Read a chunk of data from the disk.
798 * Try to recover from hard errors by reading in sector sized pieces.
799 * Error recovery is attempted at most BREADEMAX times before seeking
800 * consent from the operator to continue.
801 */
802int breaderrors = 0;
803#define BREADEMAX32 32
804
805void
806bread(daddr_t blkno, char *buf, int size)
807{
808 static char *mybuf = NULL((void *)0);
25
'mybuf' initialized to a null pointer value
809 char *mybufp, *bufp, *np;
810 static size_t mybufsz = 0;
811 off_t offset;
812 int cnt, i;
813 u_int64_t secno, seccount;
814 u_int32_t secoff, secsize = lab.d_secsize;
815
816 /*
817 * We must read an integral number of sectors large enough to contain
818 * all the requested data. The read must begin at a sector.
819 */
820 if (DL_BLKOFFSET(&lab, blkno)(((blkno) % ((&lab)->d_secsize / (1 << 9))) * (1
<< 9))
== 0
&& size % secsize == 0) {
26
Assuming the condition is false
821 secno = DL_BLKTOSEC(&lab, blkno)((blkno) / ((&lab)->d_secsize / (1 << 9)));
822 secoff = 0;
823 seccount = size / secsize;
824 bufp = buf;
825 } else {
826 secno = DL_BLKTOSEC(&lab, blkno)((blkno) / ((&lab)->d_secsize / (1 << 9)));
827 secoff = DL_BLKOFFSET(&lab, blkno)(((blkno) % ((&lab)->d_secsize / (1 << 9))) * (1
<< 9))
;
828 seccount = DL_BLKTOSEC(&lab, (size + secoff) / DEV_BSIZE)(((size + secoff) / (1 << 9)) / ((&lab)->d_secsize
/ (1 << 9)))
;
829 if (seccount * secsize < (size + secoff))
27
Assuming the condition is false
28
Taking false branch
830 seccount++;
831 if (mybufsz < seccount * secsize) {
29
Assuming the condition is false
30
Taking false branch
832 np = reallocarray(mybuf, seccount, secsize);
833 if (np == NULL((void *)0)) {
834 msg("No memory to read %llu %u-byte sectors",
835 seccount, secsize);
836 dumpabort(0);
837 }
838 mybufsz = seccount * secsize;
839 mybuf = np;
840 }
841 bufp = mybuf;
31
Null pointer value stored to 'bufp'
842 }
843
844 offset = secno * secsize;
845
846loop:
847 if ((cnt = pread(diskfd, bufp, seccount * secsize, offset)) ==
32
Assuming the condition is true
33
Taking true branch
848 seccount * secsize)
849 goto done;
34
Control jumps to line 907
850 if (blkno + (size / DEV_BSIZE(1 << 9)) >
851 fsbtodb(sblock, sblock->fs_ffs1_size)((sblock->fs_ffs1_size) << (sblock)->fs_fsbtodb)) {
852 /*
853 * Trying to read the final fragment.
854 *
855 * NB - dump only works in TP_BSIZE blocks, hence
856 * rounds `DEV_BSIZE' fragments up to TP_BSIZE pieces.
857 * It should be smarter about not actually trying to
858 * read more than it can get, but for the time being
859 * we punt and scale back the read only when it gets
860 * us into trouble. (mkm 9/25/83)
861 */
862 size -= secsize;
863 seccount--;
864 goto loop;
865 }
866 if (cnt == -1)
867 msg("read error from %s: %s: [block %lld]: count=%d\n",
868 disk, strerror(errno(*__errno())), (long long)blkno, size);
869 else
870 msg("short read error from %s: [block %lld]: count=%d, "
871 "got=%d\n", disk, (long long)blkno, size, cnt);
872 if (++breaderrors > BREADEMAX32) {
873 msg("More than %d block read errors from %s\n",
874 BREADEMAX32, disk);
875 broadcast("DUMP IS AILING!\n");
876 msg("This is an unrecoverable error.\n");
877 if (!query("Do you want to attempt to continue?")){
878 dumpabort(0);
879 /*NOTREACHED*/
880 } else
881 breaderrors = 0;
882 }
883 /*
884 * Zero buffer, then try to read each sector of buffer separately.
885 */
886 if (bufp == mybuf)
887 memset(bufp, 0, mybufsz);
888 else
889 memset(bufp, 0, size);
890 for (i = 0, mybufp = bufp; i < size; i += secsize, mybufp += secsize) {
891 if ((cnt = pread(diskfd, mybufp, secsize, offset + i)) ==
892 secsize)
893 continue;
894 if (cnt == -1) {
895 msg("read error from %s: %s: [block %lld]: "
896 "count=%u\n", disk, strerror(errno(*__errno())),
897 (long long)(offset + i) / DEV_BSIZE(1 << 9), secsize);
898 continue;
899 }
900 msg("short read error from %s: [block %lld]: count=%u, "
901 "got=%d\n", disk, (long long)(offset + i) / DEV_BSIZE(1 << 9),
902 secsize, cnt);
903 }
904
905done:
906 /* If necessary, copy out data that was read. */
907 if (bufp
34.1
'bufp' is equal to 'mybuf'
== mybuf)
35
Taking true branch
908 memcpy(buf, bufp + secoff, size);
36
Null pointer passed as 2nd argument to memory copy function
909}