]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - logprint/log_print_all.c
Update copyright dates (again)
[thirdparty/xfsprogs-dev.git] / logprint / log_print_all.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include "logprint.h"
34
35
36 /*
37 * Start is defined to be the block pointing to the oldest valid log record.
38 * Used by log print code. Don't put in cmd/xfs/logprint/xfs_log_print.c
39 * since most of the bread routines live in kern/fs/xfs/xfs_log_recover only.
40 */
41 int
42 xlog_print_find_oldest(
43 struct log *log,
44 xfs_daddr_t *last_blk)
45 {
46 xfs_buf_t *bp;
47 xfs_daddr_t first_blk;
48 uint first_half_cycle, last_half_cycle;
49 int error;
50
51 if (xlog_find_zeroed(log, &first_blk))
52 return 0;
53
54 first_blk = 0; /* read first block */
55 bp = xlog_get_bp(1, log->l_mp);
56 xlog_bread(log, 0, 1, bp);
57 first_half_cycle = GET_CYCLE(XFS_BUF_PTR(bp), ARCH_CONVERT);
58 *last_blk = log->l_logBBsize-1; /* read last block */
59 xlog_bread(log, *last_blk, 1, bp);
60 last_half_cycle = GET_CYCLE(XFS_BUF_PTR(bp), ARCH_CONVERT);
61 ASSERT(last_half_cycle != 0);
62
63 if (first_half_cycle == last_half_cycle) { /* all cycle nos are same */
64 *last_blk = 0;
65 } else { /* have 1st and last; look for middle cycle */
66 error = xlog_find_cycle_start(log, bp, first_blk,
67 last_blk, last_half_cycle);
68 if (error)
69 return error;
70 }
71
72 xlog_put_bp(bp);
73 return 0;
74 } /* xlog_print_find_oldest */
75
76
77 void
78 xlog_recover_print_data(
79 xfs_caddr_t p,
80 int len)
81 {
82 if (print_data) {
83 uint *dp = (uint *)p;
84 int nums = len >> 2;
85 int j = 0;
86
87 while (j < nums) {
88 if ((j % 8) == 0)
89 printf("%2x ", j);
90 printf("%8x ", *dp);
91 dp++;
92 j++;
93 if ((j % 8) == 0)
94 printf("\n");
95 }
96 printf("\n");
97 }
98 } /* xlog_recover_print_data */
99
100
101 STATIC void
102 xlog_recover_print_buffer(
103 xlog_recover_item_t *item)
104 {
105 xfs_agi_t *agi;
106 xfs_agf_t *agf;
107 xfs_buf_log_format_v1_t *old_f;
108 xfs_buf_log_format_t *f;
109 xfs_caddr_t p;
110 int len, num, i;
111 xfs_daddr_t blkno;
112 xfs_disk_dquot_t *ddq;
113
114 f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
115 old_f = (xfs_buf_log_format_v1_t *)f;
116 len = item->ri_buf[0].i_len;
117 printf(" ");
118 switch (f->blf_type) {
119 case XFS_LI_BUF: {
120 printf("BUF: ");
121 break;
122 }
123 case XFS_LI_6_1_BUF: {
124 printf("6.1 BUF: ");
125 break;
126 }
127 case XFS_LI_5_3_BUF: {
128 printf("5.3 BUF: ");
129 break;
130 }
131 }
132 if (f->blf_type == XFS_LI_BUF) {
133 printf("#regs:%d start blkno:0x%llx len:%d bmap size:%d\n",
134 f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size);
135 blkno = (xfs_daddr_t)f->blf_blkno;
136 } else {
137 printf("#regs:%d start blkno:0x%x len:%d bmap size:%d\n",
138 old_f->blf_size, old_f->blf_blkno, old_f->blf_len,
139 old_f->blf_map_size);
140 blkno = (xfs_daddr_t)old_f->blf_blkno;
141 }
142 num = f->blf_size-1;
143 i = 1;
144 while (num-- > 0) {
145 p = item->ri_buf[i].i_addr;
146 len = item->ri_buf[i].i_len;
147 i++;
148 if (blkno == 0) { /* super block */
149 printf(" SUPER Block Buffer:\n");
150 if (!print_buffer) continue;
151 printf(" icount:%Ld ifree:%Ld ",
152 INT_GET(*(long long *)(p), ARCH_CONVERT),
153 INT_GET(*(long long *)(p+8), ARCH_CONVERT));
154 printf("fdblks:%Ld frext:%Ld\n",
155 INT_GET(*(long long *)(p+16), ARCH_CONVERT),
156 INT_GET(*(long long *)(p+24), ARCH_CONVERT));
157 printf(" sunit:%u swidth:%u\n",
158 INT_GET(*(uint *)(p+56), ARCH_CONVERT),
159 INT_GET(*(uint *)(p+60), ARCH_CONVERT));
160 } else if (INT_GET(*(uint *)p, ARCH_CONVERT) == XFS_AGI_MAGIC) {
161 agi = (xfs_agi_t *)p;
162 printf(" AGI Buffer: (XAGI)\n");
163 if (!print_buffer) continue;
164 printf(" ver:%d ",
165 INT_GET(agi->agi_versionnum, ARCH_CONVERT));
166 printf("seq#:%d len:%d cnt:%d root:%d\n",
167 INT_GET(agi->agi_seqno, ARCH_CONVERT),
168 INT_GET(agi->agi_length, ARCH_CONVERT),
169 INT_GET(agi->agi_count, ARCH_CONVERT),
170 INT_GET(agi->agi_root, ARCH_CONVERT));
171 printf(" level:%d free#:0x%x newino:0x%x\n",
172 INT_GET(agi->agi_level, ARCH_CONVERT),
173 INT_GET(agi->agi_freecount, ARCH_CONVERT),
174 INT_GET(agi->agi_newino, ARCH_CONVERT));
175 } else if (INT_GET(*(uint *)p, ARCH_CONVERT) == XFS_AGF_MAGIC) {
176 agf = (xfs_agf_t *)p;
177 printf(" AGF Buffer: (XAGF)\n");
178 if (!print_buffer) continue;
179 printf(" ver:%d seq#:%d len:%d \n",
180 INT_GET(agf->agf_versionnum, ARCH_CONVERT),
181 INT_GET(agf->agf_seqno, ARCH_CONVERT),
182 INT_GET(agf->agf_length, ARCH_CONVERT));
183 printf(" root BNO:%d CNT:%d\n",
184 INT_GET(agf->agf_roots[XFS_BTNUM_BNOi],
185 ARCH_CONVERT),
186 INT_GET(agf->agf_roots[XFS_BTNUM_CNTi],
187 ARCH_CONVERT));
188 printf(" level BNO:%d CNT:%d\n",
189 INT_GET(agf->agf_levels[XFS_BTNUM_BNOi],
190 ARCH_CONVERT),
191 INT_GET(agf->agf_levels[XFS_BTNUM_CNTi],
192 ARCH_CONVERT));
193 printf(" 1st:%d last:%d cnt:%d "
194 "freeblks:%d longest:%d\n",
195 INT_GET(agf->agf_flfirst, ARCH_CONVERT),
196 INT_GET(agf->agf_fllast, ARCH_CONVERT),
197 INT_GET(agf->agf_flcount, ARCH_CONVERT),
198 INT_GET(agf->agf_freeblks, ARCH_CONVERT),
199 INT_GET(agf->agf_longest, ARCH_CONVERT));
200 } else if (*(uint *)p == XFS_DQUOT_MAGIC) {
201 ddq = (xfs_disk_dquot_t *)p;
202 printf(" DQUOT Buffer:\n");
203 if (!print_buffer) continue;
204 printf(" UIDs 0x%lx-0x%lx\n",
205 (unsigned long)INT_GET(ddq->d_id, ARCH_CONVERT),
206 (unsigned long)INT_GET(ddq->d_id, ARCH_CONVERT) +
207 (BBTOB(f->blf_len) / sizeof(xfs_dqblk_t)) - 1);
208 } else {
209 printf(" BUF DATA\n");
210 if (!print_buffer) continue;
211 xlog_recover_print_data(p, len);
212 }
213 }
214 } /* xlog_recover_print_buffer */
215
216 STATIC void
217 xlog_recover_print_quotaoff(
218 xlog_recover_item_t *item)
219 {
220 xfs_qoff_logformat_t *qoff_f;
221 char str[20];
222
223 qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr;
224 ASSERT(qoff_f);
225 if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
226 strcpy(str, "USER QUOTA");
227 if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
228 strcat(str, "GROUP QUOTA");
229 printf("\tQUOTAOFF: #regs:%d type:%s\n",
230 qoff_f->qf_size, str);
231 }
232
233
234 STATIC void
235 xlog_recover_print_dquot(
236 xlog_recover_item_t *item)
237 {
238 xfs_dq_logformat_t *f;
239 xfs_disk_dquot_t *d;
240
241 f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr;
242 ASSERT(f);
243 ASSERT(f->qlf_len == 1);
244 d = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
245 printf("\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n",
246 f->qlf_size, (long long)f->qlf_blkno, f->qlf_boffset, f->qlf_id);
247 if (!print_quota)
248 return;
249 printf("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n",
250 INT_GET(d->d_magic, ARCH_CONVERT),
251 INT_GET(d->d_version, ARCH_CONVERT),
252 INT_GET(d->d_id, ARCH_CONVERT),
253 INT_GET(d->d_id, ARCH_CONVERT));
254 printf("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x"
255 "\tino_soft 0x%x\n",
256 (int)INT_GET(d->d_blk_hardlimit, ARCH_CONVERT),
257 (int)INT_GET(d->d_blk_softlimit, ARCH_CONVERT),
258 (int)INT_GET(d->d_ino_hardlimit, ARCH_CONVERT),
259 (int)INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
260 printf("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n",
261 (int)INT_GET(d->d_bcount, ARCH_CONVERT),
262 (int)INT_GET(d->d_bcount, ARCH_CONVERT),
263 (int)INT_GET(d->d_icount, ARCH_CONVERT),
264 (int)INT_GET(d->d_icount, ARCH_CONVERT));
265 printf("\t\tbtimer 0x%x itimer 0x%x \n",
266 (int)INT_GET(d->d_btimer, ARCH_CONVERT),
267 (int)INT_GET(d->d_itimer, ARCH_CONVERT));
268 }
269
270 STATIC void
271 xlog_recover_print_inode_core(
272 xfs_dinode_core_t *di)
273 {
274 printf(" CORE inode:\n");
275 if (!print_inode)
276 return;
277 printf(" magic:%c%c mode:0x%x ver:%d format:%d "
278 "onlink:%d\n",
279 (di->di_magic>>8) & 0xff, di->di_magic & 0xff,
280 di->di_mode, di->di_version, di->di_format, di->di_onlink);
281 printf(" uid:%d gid:%d nlink:%d projid:%d\n",
282 di->di_uid, di->di_gid, di->di_nlink, (uint)di->di_projid);
283 printf(" atime:%d mtime:%d ctime:%d\n",
284 di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec);
285 printf(" size:0x%llx nblks:0x%llx exsize:%d "
286 "nextents:%d anextents:%d\n", (unsigned long long)
287 di->di_size, (unsigned long long)di->di_nblocks,
288 di->di_extsize, di->di_nextents, (int)di->di_anextents);
289 printf(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
290 "gen:%d\n",
291 (int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
292 (int)di->di_flags, di->di_gen);
293 } /* xlog_recover_print_inode_core */
294
295
296 STATIC void
297 xlog_recover_print_inode(
298 xlog_recover_item_t *item)
299 {
300 xfs_inode_log_format_t *f;
301 int attr_index;
302 int hasdata;
303 int hasattr;
304
305 f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
306 ASSERT(item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t));
307 printf(" INODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n",
308 f->ilf_size, (unsigned long long)f->ilf_ino, f->ilf_fields,
309 f->ilf_dsize);
310
311 /* core inode comes 2nd */
312 ASSERT(item->ri_buf[1].i_len == sizeof(xfs_dinode_core_t));
313 xlog_recover_print_inode_core((xfs_dinode_core_t *)
314 item->ri_buf[1].i_addr);
315
316 hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0;
317 hasattr = (f->ilf_fields & XFS_ILOG_AFORK) != 0;
318 /* does anything come next */
319 switch (f->ilf_fields & (XFS_ILOG_DFORK | XFS_ILOG_DEV | XFS_ILOG_UUID)) {
320 case XFS_ILOG_DEXT: {
321 ASSERT(f->ilf_size == 3 + hasattr);
322 printf(" DATA FORK EXTENTS inode data:\n");
323 if (print_inode && print_data) {
324 xlog_recover_print_data(item->ri_buf[2].i_addr,
325 item->ri_buf[2].i_len);
326 }
327 break;
328 }
329 case XFS_ILOG_DBROOT: {
330 ASSERT(f->ilf_size == 3 + hasattr);
331 printf(" DATA FORK BTREE inode data:\n");
332 if (print_inode && print_data) {
333 xlog_recover_print_data(item->ri_buf[2].i_addr,
334 item->ri_buf[2].i_len);
335 }
336 break;
337 }
338 case XFS_ILOG_DDATA: {
339 ASSERT(f->ilf_size == 3 + hasattr);
340 printf(" DATA FORK LOCAL inode data:\n");
341 if (print_inode && print_data) {
342 xlog_recover_print_data(item->ri_buf[2].i_addr,
343 item->ri_buf[2].i_len);
344 }
345 break;
346 }
347 case XFS_ILOG_DEV: {
348 ASSERT(f->ilf_size == 2 + hasattr);
349 printf(" DEV inode: no extra region\n");
350 break;
351 }
352 case XFS_ILOG_UUID: {
353 ASSERT(f->ilf_size == 2 + hasattr);
354 printf(" UUID inode: no extra region\n");
355 break;
356 }
357
358
359 case 0: {
360 ASSERT(f->ilf_size == 2 + hasattr);
361 break;
362 }
363 default: {
364 xlog_panic("xlog_print_trans_inode: illegal inode type");
365 }
366 }
367
368 if (hasattr) {
369 attr_index = 2 + hasdata;
370 switch (f->ilf_fields & XFS_ILOG_AFORK) {
371 case XFS_ILOG_AEXT: {
372 ASSERT(f->ilf_size == 3 + hasdata);
373 printf(" ATTR FORK EXTENTS inode data:\n");
374 if (print_inode && print_data) {
375 xlog_recover_print_data(
376 item->ri_buf[attr_index].i_addr,
377 item->ri_buf[attr_index].i_len);
378 }
379 break;
380 }
381 case XFS_ILOG_ABROOT: {
382 ASSERT(f->ilf_size == 3 + hasdata);
383 printf(" ATTR FORK BTREE inode data:\n");
384 if (print_inode && print_data) {
385 xlog_recover_print_data(
386 item->ri_buf[attr_index].i_addr,
387 item->ri_buf[attr_index].i_len);
388 }
389 break;
390 }
391 case XFS_ILOG_ADATA: {
392 ASSERT(f->ilf_size == 3 + hasdata);
393 printf(" ATTR FORK LOCAL inode data:\n");
394 if (print_inode && print_data) {
395 xlog_recover_print_data(
396 item->ri_buf[attr_index].i_addr,
397 item->ri_buf[attr_index].i_len);
398 }
399 break;
400 }
401 default: {
402 xlog_panic("xlog_print_trans_inode: "
403 "illegal inode log flag");
404 }
405 }
406 }
407
408 } /* xlog_recover_print_inode */
409
410
411 STATIC void
412 xlog_recover_print_efd(
413 xlog_recover_item_t *item)
414 {
415 xfs_efd_log_format_t *f;
416 xfs_extent_t *ex;
417 int i;
418
419 f = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
420 /*
421 * An xfs_efd_log_format structure contains a variable length array
422 * as the last field. Each element is of size xfs_extent_t.
423 */
424 ASSERT(item->ri_buf[0].i_len ==
425 sizeof(xfs_efd_log_format_t) + sizeof(xfs_extent_t) *
426 (f->efd_nextents-1));
427 printf(" EFD: #regs: %d num_extents: %d id: 0x%llx\n",
428 f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id);
429 ex = f->efd_extents;
430 printf(" ");
431 for (i=0; i < f->efd_size; i++) {
432 printf("(s: 0x%llx, l: %d) ",
433 (unsigned long long) ex->ext_start, ex->ext_len);
434 if (i % 4 == 3)
435 printf("\n");
436 ex++;
437 }
438 if (i % 4 != 0) printf("\n");
439 return;
440 } /* xlog_recover_print_efd */
441
442
443 STATIC void
444 xlog_recover_print_efi(
445 xlog_recover_item_t *item)
446 {
447 xfs_efi_log_format_t *f;
448 xfs_extent_t *ex;
449 int i;
450
451 f = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
452 /*
453 * An xfs_efi_log_format structure contains a variable length array
454 * as the last field. Each element is of size xfs_extent_t.
455 */
456 ASSERT(item->ri_buf[0].i_len ==
457 sizeof(xfs_efi_log_format_t) + sizeof(xfs_extent_t) *
458 (f->efi_nextents-1));
459
460 printf(" EFI: #regs:%d num_extents:%d id:0x%llx\n",
461 f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
462 ex = f->efi_extents;
463 printf(" ");
464 for (i=0; i< f->efi_nextents; i++) {
465 printf("(s: 0x%llx, l: %d) ",
466 (unsigned long long)ex->ext_start, ex->ext_len);
467 if (i % 4 == 3) printf("\n");
468 ex++;
469 }
470 if (i % 4 != 0) printf("\n");
471 return;
472 } /* xlog_recover_print_efi */
473
474 void
475 xlog_recover_print_logitem(
476 xlog_recover_item_t *item)
477 {
478 switch (ITEM_TYPE(item)) {
479 case XFS_LI_BUF:
480 case XFS_LI_6_1_BUF:
481 case XFS_LI_5_3_BUF: {
482 xlog_recover_print_buffer(item);
483 break;
484 }
485 case XFS_LI_INODE:
486 case XFS_LI_6_1_INODE:
487 case XFS_LI_5_3_INODE: {
488 xlog_recover_print_inode(item);
489 break;
490 }
491 case XFS_LI_EFD: {
492 xlog_recover_print_efd(item);
493 break;
494 }
495 case XFS_LI_EFI: {
496 xlog_recover_print_efi(item);
497 break;
498 }
499 case XFS_LI_DQUOT: {
500 xlog_recover_print_dquot(item);
501 break;
502 }
503 case XFS_LI_QUOTAOFF: {
504 xlog_recover_print_quotaoff(item);
505 break;
506 }
507 default: {
508 printf("xlog_recover_print_logitem: illegal type\n");
509 break;
510 }
511 }
512 } /* xlog_recover_print_logitem */
513
514 void
515 xlog_recover_print_item(xlog_recover_item_t *item)
516 {
517 int i;
518
519 switch (ITEM_TYPE(item)) {
520 case XFS_LI_BUF: {
521 printf("BUF");
522 break;
523 }
524 case XFS_LI_INODE: {
525 printf("INO");
526 break;
527 }
528 case XFS_LI_EFD: {
529 printf("EFD");
530 break;
531 }
532 case XFS_LI_EFI: {
533 printf("EFI");
534 break;
535 }
536 case XFS_LI_6_1_BUF: {
537 printf("6.1 BUF");
538 break;
539 }
540 case XFS_LI_5_3_BUF: {
541 printf("5.3 BUF");
542 break;
543 }
544 case XFS_LI_6_1_INODE: {
545 printf("6.1 INO");
546 break;
547 }
548 case XFS_LI_5_3_INODE: {
549 printf("5.3 INO");
550 break;
551 }
552 case XFS_LI_DQUOT: {
553 printf("DQ ");
554 break;
555 }
556 case XFS_LI_QUOTAOFF: {
557 printf("QOFF");
558 break;
559 }
560 default: {
561 cmn_err(CE_PANIC, "xlog_recover_print_item: illegal type");
562 break;
563 }
564 }
565
566 /* type isn't filled in yet
567 printf("ITEM: type: %d cnt: %d total: %d ",
568 item->ri_type, item->ri_cnt, item->ri_total);
569 */
570 printf(": cnt:%d total:%d ", item->ri_cnt, item->ri_total);
571 for (i=0; i<item->ri_cnt; i++) {
572 printf("a:0x%lx len:%d ",
573 (long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len);
574 }
575 printf("\n");
576 xlog_recover_print_logitem(item);
577 } /* xlog_recover_print_item */
578
579 void
580 xlog_recover_print_trans(xlog_recover_t *trans,
581 xlog_recover_item_t *itemq,
582 int print)
583 {
584 xlog_recover_item_t *first_item, *item;
585
586 if (print < 3)
587 return;
588
589 print_xlog_record_line();
590 xlog_recover_print_trans_head(trans);
591 item = first_item = itemq;
592 do {
593 xlog_recover_print_item(item);
594 item = item->ri_next;
595 } while (first_item != item);
596 } /* xlog_recover_print_trans */