1 | /* $NetBSD: lfs_debug.c,v 1.54 2015/09/01 06:12:04 dholland Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Konrad E. Schroder <perseant@hhhh.org>. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | /* |
32 | * Copyright (c) 1991, 1993 |
33 | * The Regents of the University of California. All rights reserved. |
34 | * |
35 | * Redistribution and use in source and binary forms, with or without |
36 | * modification, are permitted provided that the following conditions |
37 | * are met: |
38 | * 1. Redistributions of source code must retain the above copyright |
39 | * notice, this list of conditions and the following disclaimer. |
40 | * 2. Redistributions in binary form must reproduce the above copyright |
41 | * notice, this list of conditions and the following disclaimer in the |
42 | * documentation and/or other materials provided with the distribution. |
43 | * 3. Neither the name of the University nor the names of its contributors |
44 | * may be used to endorse or promote products derived from this software |
45 | * without specific prior written permission. |
46 | * |
47 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
48 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
49 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
50 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
51 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
52 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
53 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
54 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
55 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
56 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
57 | * SUCH DAMAGE. |
58 | * |
59 | * @(#)lfs_debug.c 8.1 (Berkeley) 6/11/93 |
60 | */ |
61 | |
62 | #include <sys/cdefs.h> |
63 | __KERNEL_RCSID(0, "$NetBSD: lfs_debug.c,v 1.54 2015/09/01 06:12:04 dholland Exp $" ); |
64 | |
65 | #ifdef DEBUG |
66 | |
67 | #include <sys/param.h> |
68 | #include <sys/systm.h> |
69 | #include <sys/namei.h> |
70 | #include <sys/vnode.h> |
71 | #include <sys/mount.h> |
72 | #include <sys/buf.h> |
73 | #include <sys/syslog.h> |
74 | #include <sys/proc.h> |
75 | |
76 | #include <ufs/lfs/ulfs_inode.h> |
77 | #include <ufs/lfs/lfs.h> |
78 | #include <ufs/lfs/lfs_accessors.h> |
79 | #include <ufs/lfs/lfs_extern.h> |
80 | |
81 | int lfs_lognum; |
82 | struct lfs_log_entry lfs_log[LFS_LOGLENGTH]; |
83 | |
84 | int |
85 | lfs_bwrite_log(struct buf *bp, const char *file, int line) |
86 | { |
87 | struct vop_bwrite_args a; |
88 | |
89 | a.a_desc = VDESC(vop_bwrite); |
90 | a.a_bp = bp; |
91 | |
92 | if (!(bp->b_flags & B_GATHERED) && !(bp->b_oflags & BO_DELWRI)) { |
93 | LFS_ENTER_LOG("write" , file, line, bp->b_lblkno, bp->b_flags, |
94 | curproc->p_pid); |
95 | } |
96 | return (VCALL(bp->b_vp, VOFFSET(vop_bwrite), &a)); |
97 | } |
98 | |
99 | void |
100 | lfs_dumplog(void) |
101 | { |
102 | int i; |
103 | const char *cp; |
104 | |
105 | for (i = lfs_lognum; i != (lfs_lognum - 1) % LFS_LOGLENGTH; |
106 | i = (i + 1) % LFS_LOGLENGTH) |
107 | if (lfs_log[i].file) { |
108 | /* Only print out basename, for readability */ |
109 | cp = lfs_log[i].file; |
110 | while(*cp) |
111 | ++cp; |
112 | while(*cp != '/' && cp > lfs_log[i].file) |
113 | --cp; |
114 | |
115 | printf("lbn %" PRId64 " %s %lx %d, %d %s\n" , |
116 | lfs_log[i].block, |
117 | lfs_log[i].op, |
118 | lfs_log[i].flags, |
119 | lfs_log[i].pid, |
120 | lfs_log[i].line, |
121 | cp); |
122 | } |
123 | } |
124 | |
125 | void |
126 | lfs_dump_super(struct lfs *lfsp) |
127 | { |
128 | int i; |
129 | |
130 | printf("%s%x\t%s%x\t%s%ju\t%s%d\n" , |
131 | "magic " , lfsp->lfs_is64 ? |
132 | lfsp->lfs_dlfs_u.u_64.dlfs_magic : |
133 | lfsp->lfs_dlfs_u.u_32.dlfs_magic, |
134 | "version " , lfs_sb_getversion(lfsp), |
135 | "size " , (uintmax_t)lfs_sb_getsize(lfsp), |
136 | "ssize " , lfs_sb_getssize(lfsp)); |
137 | printf("%s%ju\t%s%d\t%s%d\t%s%d\n" , |
138 | "dsize " , (uintmax_t)lfs_sb_getdsize(lfsp), |
139 | "bsize " , lfs_sb_getbsize(lfsp), |
140 | "fsize " , lfs_sb_getfsize(lfsp), |
141 | "frag " , lfs_sb_getfrag(lfsp)); |
142 | |
143 | printf("%s%d\t%s%d\t%s%d\t%s%d\n" , |
144 | "minfree " , lfs_sb_getminfree(lfsp), |
145 | "inopb " , lfs_sb_getinopb(lfsp), |
146 | "ifpb " , lfs_sb_getifpb(lfsp), |
147 | "nindir " , lfs_sb_getnindir(lfsp)); |
148 | |
149 | printf("%s%d\t%s%d\t%s%d\t%s%d\n" , |
150 | "nseg " , lfs_sb_getnseg(lfsp), |
151 | "nspf " , lfs_sb_getnspf(lfsp), |
152 | "cleansz " , lfs_sb_getcleansz(lfsp), |
153 | "segtabsz " , lfs_sb_getsegtabsz(lfsp)); |
154 | |
155 | printf("%s%x\t%s%d\t%s%lx\t%s%d\n" , |
156 | "segmask " , lfs_sb_getsegmask(lfsp), |
157 | "segshift " , lfs_sb_getsegshift(lfsp), |
158 | "bmask " , (unsigned long)lfs_sb_getbmask(lfsp), |
159 | "bshift " , lfs_sb_getbshift(lfsp)); |
160 | |
161 | printf("%s%lu\t%s%d\t%s%lx\t%s%u\n" , |
162 | "ffmask " , (unsigned long)lfs_sb_getffmask(lfsp), |
163 | "ffshift " , lfs_sb_getffshift(lfsp), |
164 | "fbmask " , (unsigned long)lfs_sb_getfbmask(lfsp), |
165 | "fbshift " , lfs_sb_getfbshift(lfsp)); |
166 | |
167 | printf("%s%d\t%s%d\t%s%x\t%s%jx\n" , |
168 | "sushift " , lfs_sb_getsushift(lfsp), |
169 | "fsbtodb " , lfs_sb_getfsbtodb(lfsp), |
170 | "cksum " , lfs_sb_getcksum(lfsp), |
171 | "maxfilesize " , (uintmax_t)lfs_sb_getmaxfilesize(lfsp)); |
172 | |
173 | printf("Superblock disk addresses:" ); |
174 | for (i = 0; i < LFS_MAXNUMSB; i++) |
175 | printf(" %jx" , (intmax_t)lfs_sb_getsboff(lfsp, i)); |
176 | printf("\n" ); |
177 | |
178 | printf("Checkpoint Info\n" ); |
179 | printf("%s%ju\t%s%jx\n" , |
180 | "freehd " , (uintmax_t)lfs_sb_getfreehd(lfsp), |
181 | "idaddr " , (intmax_t)lfs_sb_getidaddr(lfsp)); |
182 | printf("%s%jx\t%s%ju\t%s%jx\t%s%jx\t%s%jx\t%s%jx\n" , |
183 | "bfree " , (intmax_t)lfs_sb_getbfree(lfsp), |
184 | "nfiles " , (uintmax_t)lfs_sb_getnfiles(lfsp), |
185 | "lastseg " , (intmax_t)lfs_sb_getlastseg(lfsp), |
186 | "nextseg " , (intmax_t)lfs_sb_getnextseg(lfsp), |
187 | "curseg " , (intmax_t)lfs_sb_getcurseg(lfsp), |
188 | "offset " , (intmax_t)lfs_sb_getoffset(lfsp)); |
189 | printf("tstamp %llx\n" , (long long)lfs_sb_gettstamp(lfsp)); |
190 | |
191 | if (!lfsp->lfs_is64) { |
192 | printf("32-bit only derived or constant fields\n" ); |
193 | printf("%s%u\n" , |
194 | "ifile " , lfs_sb_getifile(lfsp)); |
195 | } |
196 | } |
197 | |
198 | void |
199 | lfs_dump_dinode(struct lfs *fs, union lfs_dinode *dip) |
200 | { |
201 | int i; |
202 | |
203 | printf("%s%u\t%s%d\t%s%u\t%s%u\t%s%ju\t%s%ju\n" , |
204 | "mode " , lfs_dino_getmode(fs, dip), |
205 | "nlink " , lfs_dino_getnlink(fs, dip), |
206 | "uid " , lfs_dino_getuid(fs, dip), |
207 | "gid " , lfs_dino_getgid(fs, dip), |
208 | "size " , (uintmax_t)lfs_dino_getsize(fs, dip), |
209 | "blocks " , (uintmax_t)lfs_dino_getblocks(fs, dip)); |
210 | printf("inum %ju\n" , (uintmax_t)lfs_dino_getinumber(fs, dip)); |
211 | printf("Direct Addresses\n" ); |
212 | for (i = 0; i < ULFS_NDADDR; i++) { |
213 | printf("\t%jx" , (intmax_t)lfs_dino_getdb(fs, dip, i)); |
214 | if ((i % 6) == 5) |
215 | printf("\n" ); |
216 | } |
217 | for (i = 0; i < ULFS_NIADDR; i++) |
218 | printf("\t%jx" , (intmax_t)lfs_dino_getib(fs, dip, i)); |
219 | printf("\n" ); |
220 | } |
221 | |
222 | void |
223 | lfs_check_segsum(struct lfs *fs, struct segment *sp, char *file, int line) |
224 | { |
225 | int actual; |
226 | #if 0 |
227 | static int offset; |
228 | #endif |
229 | |
230 | if ((actual = 1) == 1) |
231 | return; /* XXXX not checking this anymore, really */ |
232 | |
233 | if (sp->sum_bytes_left >= FINFOSIZE(fs) |
234 | && lfs_fi_getnblocks(fs, sp->fip) > 512) { |
235 | printf("%s:%d: fi_nblocks = %d\n" , file, line, |
236 | lfs_fi_getnblocks(fs, sp->fip)); |
237 | #ifdef DDB |
238 | Debugger(); |
239 | #endif |
240 | } |
241 | |
242 | if (sp->sum_bytes_left > 484) { |
243 | printf("%s:%d: bad value (%d = -%d) for sum_bytes_left\n" , |
244 | file, line, sp->sum_bytes_left, lfs_sb_getsumsize(fs)-sp->sum_bytes_left); |
245 | panic("too many bytes" ); |
246 | } |
247 | |
248 | actual = lfs_sb_getsumsize(fs) |
249 | /* amount taken up by FINFOs */ |
250 | - ((char *)NEXT_FINFO(fs, sp->fip) - (char *)(sp->segsum)) |
251 | /* amount taken up by inode blocks */ |
252 | /* XXX should this be INUMSIZE or BLKPTRSIZE? */ |
253 | - LFS_INUMSIZE(fs)*((sp->ninodes+LFS_INOPB(fs)-1) / LFS_INOPB(fs)); |
254 | #if 0 |
255 | if (actual - sp->sum_bytes_left < offset) |
256 | { |
257 | printf("%s:%d: offset changed %d -> %d\n" , file, line, |
258 | offset, actual-sp->sum_bytes_left); |
259 | offset = actual - sp->sum_bytes_left; |
260 | /* panic("byte mismatch"); */ |
261 | } |
262 | #endif |
263 | #if 0 |
264 | if (actual != sp->sum_bytes_left) |
265 | printf("%s:%d: warning: segsum miscalc at %d (-%d => %d)\n" , |
266 | file, line, sp->sum_bytes_left, |
267 | lfs_sb_getsumsize(fs)-sp->sum_bytes_left, |
268 | actual); |
269 | #endif |
270 | if (sp->sum_bytes_left > 0 |
271 | && ((char *)(sp->segsum))[lfs_sb_getsumsize(fs) |
272 | - sizeof(int32_t) * ((sp->ninodes+LFS_INOPB(fs)-1) / LFS_INOPB(fs)) |
273 | - sp->sum_bytes_left] != '\0') { |
274 | printf("%s:%d: warning: segsum overwrite at %d (-%d => %d)\n" , |
275 | file, line, sp->sum_bytes_left, |
276 | lfs_sb_getsumsize(fs)-sp->sum_bytes_left, |
277 | actual); |
278 | #ifdef DDB |
279 | Debugger(); |
280 | #endif |
281 | } |
282 | } |
283 | |
284 | void |
285 | lfs_check_bpp(struct lfs *fs, struct segment *sp, char *file, int line) |
286 | { |
287 | daddr_t blkno; |
288 | struct buf **bpp; |
289 | struct vnode *devvp; |
290 | |
291 | devvp = VTOI(fs->lfs_ivnode)->i_devvp; |
292 | blkno = (*(sp->bpp))->b_blkno; |
293 | for (bpp = sp->bpp; bpp < sp->cbpp; bpp++) { |
294 | if ((*bpp)->b_blkno != blkno) { |
295 | if ((*bpp)->b_vp == devvp) { |
296 | printf("Oops, would misplace raw block " |
297 | "0x%" PRIx64 " at 0x%" PRIx64 "\n" , |
298 | (*bpp)->b_blkno, |
299 | blkno); |
300 | } else { |
301 | printf("%s:%d: misplace ino %llu lbn %" PRId64 |
302 | " at 0x%" PRIx64 " instead of " |
303 | "0x%" PRIx64 "\n" , |
304 | file, line, |
305 | (unsigned long long) |
306 | VTOI((*bpp)->b_vp)->i_number, |
307 | (*bpp)->b_lblkno, |
308 | blkno, |
309 | (*bpp)->b_blkno); |
310 | } |
311 | } |
312 | blkno += LFS_FSBTODB(fs, lfs_btofsb(fs, (*bpp)->b_bcount)); |
313 | } |
314 | } |
315 | |
316 | int lfs_debug_log_subsys[DLOG_MAX]; |
317 | |
318 | /* |
319 | * Log events from various debugging areas of LFS, depending on what |
320 | * the user has enabled. |
321 | */ |
322 | void |
323 | lfs_debug_log(int subsys, const char *fmt, ...) |
324 | { |
325 | va_list ap; |
326 | |
327 | /* If not debugging this subsys, exit */ |
328 | if (lfs_debug_log_subsys[subsys] == 0) |
329 | return; |
330 | |
331 | va_start(ap, fmt); |
332 | vlog(LOG_DEBUG, fmt, ap); |
333 | va_end(ap); |
334 | } |
335 | #endif /* DEBUG */ |
336 | |