]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - logprint/log_misc.c
xfsprogs: remove xfs_caddr_t
[thirdparty/xfsprogs-dev.git] / logprint / log_misc.c
1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include "xfs/libxfs.h"
19 #include "xfs/libxlog.h"
20
21 #include "logprint.h"
22
23 #define CLEARED_BLKS (-5)
24 #define ZEROED_LOG (-4)
25 #define FULL_READ (-3)
26 #define PARTIAL_READ (-2)
27 #define BAD_HEADER (-1)
28 #define NO_ERROR (0)
29
30 static int logBBsize;
31 char *trans_type[] = {
32 "",
33 "SETATTR",
34 "SETATTR_SIZE",
35 "INACTIVE",
36 "CREATE",
37 "CREATE_TRUNC",
38 "TRUNCATE_FILE",
39 "REMOVE",
40 "LINK",
41 "RENAME",
42 "MKDIR",
43 "RMDIR",
44 "SYMLINK",
45 "SET_DMATTRS",
46 "GROWFS",
47 "STRAT_WRITE",
48 "DIOSTRAT",
49 "WRITE_SYNC",
50 "WRITEID",
51 "ADDAFORK",
52 "ATTRINVAL",
53 "ATRUNCATE",
54 "ATTR_SET",
55 "ATTR_RM",
56 "ATTR_FLAG",
57 "CLEAR_AGI_BUCKET",
58 "QM_SBCHANGE",
59 "DUMMY1",
60 "DUMMY2",
61 "QM_QUOTAOFF",
62 "QM_DQALLOC",
63 "QM_SETQLIM",
64 "QM_DQCLUSTER",
65 "QM_QINOCREATE",
66 "QM_QUOTAOFF_END",
67 "SB_UNIT",
68 "FSYNC_TS",
69 "GROWFSRT_ALLOC",
70 "GROWFSRT_ZERO",
71 "GROWFSRT_FREE",
72 "SWAPEXT",
73 "SB_COUNT",
74 "CHECKPOINT",
75 "ICREATE",
76 };
77
78 typedef struct xlog_split_item {
79 struct xlog_split_item *si_next;
80 struct xlog_split_item *si_prev;
81 xlog_tid_t si_tid;
82 int si_skip;
83 } xlog_split_item_t;
84
85 xlog_split_item_t *split_list = NULL;
86
87 void
88 print_xlog_op_line(void)
89 {
90 printf("--------------------------------------"
91 "--------------------------------------\n");
92 } /* print_xlog_op_line */
93
94 void
95 print_xlog_xhdr_line(void)
96 {
97 printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
98 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
99 } /* print_xlog_xhdr_line */
100
101 void
102 print_xlog_record_line(void)
103 {
104 printf("======================================"
105 "======================================\n");
106 } /* print_xlog_record_line */
107
108 void
109 print_stars(void)
110 {
111 printf("***********************************"
112 "***********************************\n");
113 } /* print_stars */
114
115 /*
116 * Given a pointer to a data segment, print out the data as if it were
117 * a log operation header.
118 */
119 void
120 xlog_print_op_header(xlog_op_header_t *op_head,
121 int i,
122 char **ptr)
123 {
124 xlog_op_header_t hbuf;
125
126 /*
127 * memmove because on 64/n32, partial reads can cause the op_head
128 * pointer to come in pointing to an odd-numbered byte
129 */
130 memmove(&hbuf, op_head, sizeof(xlog_op_header_t));
131 op_head = &hbuf;
132 *ptr += sizeof(xlog_op_header_t);
133 printf(_("Oper (%d): tid: %x len: %d clientid: %s "), i,
134 be32_to_cpu(op_head->oh_tid),
135 be32_to_cpu(op_head->oh_len),
136 (op_head->oh_clientid == XFS_TRANSACTION ? "TRANS" :
137 (op_head->oh_clientid == XFS_LOG ? "LOG" : "ERROR")));
138 printf(_("flags: "));
139 if (op_head->oh_flags) {
140 if (op_head->oh_flags & XLOG_START_TRANS)
141 printf("START ");
142 if (op_head->oh_flags & XLOG_COMMIT_TRANS)
143 printf("COMMIT ");
144 if (op_head->oh_flags & XLOG_WAS_CONT_TRANS)
145 printf("WAS_CONT ");
146 if (op_head->oh_flags & XLOG_UNMOUNT_TRANS)
147 printf("UNMOUNT ");
148 if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
149 printf("CONTINUE ");
150 if (op_head->oh_flags & XLOG_END_TRANS)
151 printf("END ");
152 } else {
153 printf(_("none"));
154 }
155 printf("\n");
156 } /* xlog_print_op_header */
157
158
159 void
160 xlog_print_add_to_trans(xlog_tid_t tid,
161 int skip)
162 {
163 xlog_split_item_t *item;
164
165 item = (xlog_split_item_t *)calloc(sizeof(xlog_split_item_t), 1);
166 item->si_tid = tid;
167 item->si_skip = skip;
168 item->si_next = split_list;
169 item->si_prev = NULL;
170 if (split_list)
171 split_list->si_prev = item;
172 split_list = item;
173 } /* xlog_print_add_to_trans */
174
175
176 int
177 xlog_print_find_tid(xlog_tid_t tid, uint was_cont)
178 {
179 xlog_split_item_t *listp = split_list;
180
181 if (!split_list) {
182 if (was_cont != 0) /* Not first time we have used this tid */
183 return 1;
184 else
185 return 0;
186 }
187 while (listp) {
188 if (listp->si_tid == tid)
189 break;
190 listp = listp->si_next;
191 }
192 if (!listp) {
193 return 0;
194 }
195 if (--listp->si_skip == 0) {
196 if (listp == split_list) { /* delete at head */
197 split_list = listp->si_next;
198 if (split_list)
199 split_list->si_prev = NULL;
200 } else {
201 if (listp->si_next)
202 listp->si_next->si_prev = listp->si_prev;
203 listp->si_prev->si_next = listp->si_next;
204 }
205 free(listp);
206 }
207 return 1;
208 } /* xlog_print_find_tid */
209
210 int
211 xlog_print_trans_header(char **ptr, int len)
212 {
213 xfs_trans_header_t *h;
214 char *cptr = *ptr;
215 __uint32_t magic;
216 char *magic_c = (char *)&magic;
217
218 *ptr += len;
219
220 magic=*(__uint32_t*)cptr; /* XXX be32_to_cpu soon */
221
222 if (len >= 4) {
223 #if __BYTE_ORDER == __LITTLE_ENDIAN
224 printf("%c%c%c%c:",
225 magic_c[3], magic_c[2], magic_c[1], magic_c[0]);
226 #else
227 printf("%c%c%c%c:",
228 magic_c[0], magic_c[1], magic_c[2], magic_c[3]);
229 #endif
230 }
231 if (len != sizeof(xfs_trans_header_t)) {
232 printf(_(" Not enough data to decode further\n"));
233 return 1;
234 }
235 h = (xfs_trans_header_t *)cptr;
236 printf(_(" type: %s tid: %x num_items: %d\n"),
237 trans_type[h->th_type], h->th_tid, h->th_num_items);
238 return 0;
239 } /* xlog_print_trans_header */
240
241
242 int
243 xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops)
244 {
245 xfs_buf_log_format_t *f;
246 xfs_agi_t *agi;
247 xfs_agf_t *agf;
248 xfs_disk_dquot_t *dq;
249 xlog_op_header_t *head = NULL;
250 int num, skip;
251 int super_block = 0;
252 int bucket, col, buckets;
253 __int64_t blkno;
254 xfs_buf_log_format_t lbuf;
255 int size, blen, map_size, struct_size;
256 __be64 x, y;
257 ushort flags;
258
259 /*
260 * memmove to ensure 8-byte alignment for the long longs in
261 * buf_log_format_t structure
262 */
263 memmove(&lbuf, *ptr, MIN(sizeof(xfs_buf_log_format_t), len));
264 f = &lbuf;
265 *ptr += len;
266
267 ASSERT(f->blf_type == XFS_LI_BUF);
268 printf("BUF: ");
269 blkno = f->blf_blkno;
270 size = f->blf_size;
271 blen = f->blf_len;
272 map_size = f->blf_map_size;
273 flags = f->blf_flags;
274
275 /*
276 * size of the format header is dependent on the size of the bitmap, not
277 * the size of the in-memory structure. Hence the slightly obtuse
278 * calculation.
279 */
280 struct_size = offsetof(struct xfs_buf_log_format, blf_map_size) + map_size;
281
282 if (len >= struct_size) {
283 ASSERT((len - sizeof(struct_size)) % sizeof(int) == 0);
284 printf(_("#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n"),
285 size, (long long)blkno, (unsigned long long)blkno, blen, map_size, flags);
286 if (blkno == 0)
287 super_block = 1;
288 } else {
289 ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */
290 printf(_("#regs: %d Not printing rest of data\n"), f->blf_size);
291 return size;
292 }
293 num = size-1;
294
295 /* Check if all regions in this log item were in the given LR ptr */
296 if (*i+num > num_ops-1) {
297 skip = num - (num_ops-1-*i);
298 num = num_ops-1-*i;
299 } else {
300 skip = 0;
301 }
302 while (num-- > 0) {
303 (*i)++;
304 head = (xlog_op_header_t *)*ptr;
305 xlog_print_op_header(head, *i, ptr);
306 if (super_block) {
307 printf(_("SUPER BLOCK Buffer: "));
308 if (be32_to_cpu(head->oh_len) < 4*8) {
309 printf(_("Out of space\n"));
310 } else {
311 printf("\n");
312 /*
313 * memmove because *ptr may not be 8-byte aligned
314 */
315 memmove(&x, *ptr, sizeof(__be64));
316 memmove(&y, *ptr+8, sizeof(__be64));
317 printf(_("icount: %llu ifree: %llu "),
318 (unsigned long long) be64_to_cpu(x),
319 (unsigned long long) be64_to_cpu(y));
320 memmove(&x, *ptr+16, sizeof(__be64));
321 memmove(&y, *ptr+24, sizeof(__be64));
322 printf(_("fdblks: %llu frext: %llu\n"),
323 (unsigned long long) be64_to_cpu(x),
324 (unsigned long long) be64_to_cpu(y));
325 }
326 super_block = 0;
327 } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) {
328 agi = (xfs_agi_t *)(*ptr);
329 printf(_("AGI Buffer: XAGI "));
330 /*
331 * v4 filesystems only contain the fields before the uuid.
332 * Even v5 filesystems don't log any field beneath it. That
333 * means that the size that is logged is almost always going to
334 * be smaller than the structure itself. Hence we need to make
335 * sure that the buffer contains all the data we want to print
336 * rather than just check against the structure size.
337 */
338 if (be32_to_cpu(head->oh_len) < offsetof(xfs_agi_t, agi_uuid) -
339 XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) {
340 printf(_("out of space\n"));
341 } else {
342 printf("\n");
343 printf(_("ver: %d "),
344 be32_to_cpu(agi->agi_versionnum));
345 printf(_("seq#: %d len: %d cnt: %d root: %d\n"),
346 be32_to_cpu(agi->agi_seqno),
347 be32_to_cpu(agi->agi_length),
348 be32_to_cpu(agi->agi_count),
349 be32_to_cpu(agi->agi_root));
350 printf(_("level: %d free#: 0x%x newino: 0x%x\n"),
351 be32_to_cpu(agi->agi_level),
352 be32_to_cpu(agi->agi_freecount),
353 be32_to_cpu(agi->agi_newino));
354 if (be32_to_cpu(head->oh_len) == 128) {
355 buckets = 17;
356 } else if (be32_to_cpu(head->oh_len) == 256) {
357 buckets = 32 + 17;
358 } else {
359 if (head->oh_flags & XLOG_CONTINUE_TRANS) {
360 printf(_("AGI unlinked data skipped "));
361 printf(_("(CONTINUE set, no space)\n"));
362 continue;
363 }
364 buckets = XFS_AGI_UNLINKED_BUCKETS;
365 }
366 for (bucket = 0; bucket < buckets;) {
367 printf(_("bucket[%d - %d]: "), bucket, bucket+3);
368 for (col = 0; col < 4; col++, bucket++) {
369 if (bucket < buckets) {
370 printf("0x%x ",
371 be32_to_cpu(agi->agi_unlinked[bucket]));
372 }
373 }
374 printf("\n");
375 }
376 }
377 } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) {
378 agf = (xfs_agf_t *)(*ptr);
379 printf(_("AGF Buffer: XAGF "));
380 /*
381 * v4 filesystems only contain the fields before the uuid.
382 * Even v5 filesystems don't log any field beneath it. That
383 * means that the size that is logged is almost always going to
384 * be smaller than the structure itself. Hence we need to make
385 * sure that the buffer contains all the data we want to print
386 * rather than just check against the structure size.
387 */
388 if (be32_to_cpu(head->oh_len) < offsetof(xfs_agf_t, agf_uuid)) {
389 printf(_("Out of space\n"));
390 } else {
391 printf("\n");
392 printf(_("ver: %d seq#: %d len: %d \n"),
393 be32_to_cpu(agf->agf_versionnum),
394 be32_to_cpu(agf->agf_seqno),
395 be32_to_cpu(agf->agf_length));
396 printf(_("root BNO: %d CNT: %d\n"),
397 be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]),
398 be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
399 printf(_("level BNO: %d CNT: %d\n"),
400 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]),
401 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
402 printf(_("1st: %d last: %d cnt: %d "
403 "freeblks: %d longest: %d\n"),
404 be32_to_cpu(agf->agf_flfirst),
405 be32_to_cpu(agf->agf_fllast),
406 be32_to_cpu(agf->agf_flcount),
407 be32_to_cpu(agf->agf_freeblks),
408 be32_to_cpu(agf->agf_longest));
409 }
410 } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) {
411 dq = (xfs_disk_dquot_t *)(*ptr);
412 printf(_("DQUOT Buffer: DQ "));
413 if (be32_to_cpu(head->oh_len) <
414 sizeof(xfs_disk_dquot_t)) {
415 printf(_("Out of space\n"));
416 }
417 else {
418 printf("\n");
419 printf(_("ver: %d flags: 0x%x id: %d \n"),
420 dq->d_version, dq->d_flags,
421 be32_to_cpu(dq->d_id));
422 printf(_("blk limits hard: %llu soft: %llu\n"),
423 (unsigned long long)
424 be64_to_cpu(dq->d_blk_hardlimit),
425 (unsigned long long)
426 be64_to_cpu(dq->d_blk_softlimit));
427 printf(_("blk count: %llu warns: %d timer: %d\n"),
428 (unsigned long long) be64_to_cpu(dq->d_bcount),
429 (int) be16_to_cpu(dq->d_bwarns),
430 be32_to_cpu(dq->d_btimer));
431 printf(_("ino limits hard: %llu soft: %llu\n"),
432 (unsigned long long)
433 be64_to_cpu(dq->d_ino_hardlimit),
434 (unsigned long long)
435 be64_to_cpu(dq->d_ino_softlimit));
436 printf(_("ino count: %llu warns: %d timer: %d\n"),
437 (unsigned long long) be64_to_cpu(dq->d_icount),
438 (int) be16_to_cpu(dq->d_iwarns),
439 be32_to_cpu(dq->d_itimer));
440 }
441 } else {
442 printf(_("BUF DATA\n"));
443 if (print_data) {
444 uint *dp = (uint *)*ptr;
445 int nums = be32_to_cpu(head->oh_len) >> 2;
446 int i = 0;
447
448 while (i < nums) {
449 if ((i % 8) == 0)
450 printf("%2x ", i);
451 printf("%8x ", *dp);
452 dp++;
453 i++;
454 if ((i % 8) == 0)
455 printf("\n");
456 }
457 printf("\n");
458 }
459 }
460 *ptr += be32_to_cpu(head->oh_len);
461 }
462 if (head && head->oh_flags & XLOG_CONTINUE_TRANS)
463 skip++;
464 return skip;
465 } /* xlog_print_trans_buffer */
466
467
468 int
469 xlog_print_trans_efd(char **ptr, uint len)
470 {
471 xfs_efd_log_format_t *f;
472 xfs_efd_log_format_t lbuf;
473 /* size without extents at end */
474 uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t);
475
476 /*
477 * memmove to ensure 8-byte alignment for the long longs in
478 * xfs_efd_log_format_t structure
479 */
480 memmove(&lbuf, *ptr, MIN(core_size, len));
481 f = &lbuf;
482 *ptr += len;
483 if (len >= core_size) {
484 printf(_("EFD: #regs: %d num_extents: %d id: 0x%llx\n"),
485 f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id);
486
487 /* don't print extents as they are not used */
488
489 return 0;
490 } else {
491 printf(_("EFD: Not enough data to decode further\n"));
492 return 1;
493 }
494 } /* xlog_print_trans_efd */
495
496
497 int
498 xlog_print_trans_efi(
499 char **ptr,
500 uint src_len,
501 int continued)
502 {
503 xfs_efi_log_format_t *src_f, *f = NULL;
504 uint dst_len;
505 xfs_extent_t *ex;
506 int i;
507 int error = 0;
508 int core_size = offsetof(xfs_efi_log_format_t, efi_extents);
509
510 /*
511 * memmove to ensure 8-byte alignment for the long longs in
512 * xfs_efi_log_format_t structure
513 */
514 if ((src_f = (xfs_efi_log_format_t *)malloc(src_len)) == NULL) {
515 fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
516 exit(1);
517 }
518 memmove((char*)src_f, *ptr, src_len);
519 *ptr += src_len;
520
521 /* convert to native format */
522 dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t);
523
524 if (continued && src_len < core_size) {
525 printf(_("EFI: Not enough data to decode further\n"));
526 error = 1;
527 goto error;
528 }
529
530 if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) {
531 fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
532 exit(1);
533 }
534 if (xfs_efi_copy_format((char*)src_f, src_len, f, continued)) {
535 error = 1;
536 goto error;
537 }
538
539 printf(_("EFI: #regs: %d num_extents: %d id: 0x%llx\n"),
540 f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
541
542 if (continued) {
543 printf(_("EFI free extent data skipped (CONTINUE set, no space)\n"));
544 goto error;
545 }
546
547 ex = f->efi_extents;
548 for (i=0; i < f->efi_nextents; i++) {
549 printf("(s: 0x%llx, l: %d) ",
550 (unsigned long long)ex->ext_start, ex->ext_len);
551 if (i % 4 == 3) printf("\n");
552 ex++;
553 }
554 if (i % 4 != 0) printf("\n");
555 error:
556 free(src_f);
557 free(f);
558 return error;
559 } /* xlog_print_trans_efi */
560
561
562 int
563 xlog_print_trans_qoff(char **ptr, uint len)
564 {
565 xfs_qoff_logformat_t *f;
566 xfs_qoff_logformat_t lbuf;
567
568 memmove(&lbuf, *ptr, MIN(sizeof(xfs_qoff_logformat_t), len));
569 f = &lbuf;
570 *ptr += len;
571 if (len >= sizeof(xfs_qoff_logformat_t)) {
572 printf(_("QOFF: #regs: %d flags: 0x%x\n"), f->qf_size, f->qf_flags);
573 return 0;
574 } else {
575 printf(_("QOFF: Not enough data to decode further\n"));
576 return 1;
577 }
578 } /* xlog_print_trans_qoff */
579
580
581 void
582 xlog_print_trans_inode_core(xfs_icdinode_t *ip)
583 {
584 printf(_("INODE CORE\n"));
585 printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
586 ip->di_magic, ip->di_mode, (int)ip->di_version,
587 (int)ip->di_format);
588 printf(_("nlink %hd uid %d gid %d\n"),
589 ip->di_nlink, ip->di_uid, ip->di_gid);
590 printf(_("atime 0x%x mtime 0x%x ctime 0x%x\n"),
591 ip->di_atime.t_sec, ip->di_mtime.t_sec, ip->di_ctime.t_sec);
592 printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
593 (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
594 ip->di_extsize, ip->di_nextents);
595 printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
596 ip->di_anextents, (int)ip->di_forkoff, ip->di_dmevmask,
597 ip->di_dmstate);
598 printf(_("flags 0x%x gen 0x%x\n"),
599 ip->di_flags, ip->di_gen);
600 }
601
602 void
603 xlog_print_dir2_sf(
604 struct xlog *log,
605 xfs_dir2_sf_hdr_t *sfp,
606 int size)
607 {
608 xfs_ino_t ino;
609 int count;
610 int i;
611 char namebuf[257];
612 xfs_dir2_sf_entry_t *sfep;
613
614 printf(_("SHORTFORM DIRECTORY size %d\n"),
615 size);
616 /* bail out for now */
617
618 return;
619
620 printf(_("SHORTFORM DIRECTORY size %d count %d\n"),
621 size, sfp->count);
622 memmove(&ino, &(sfp->parent), sizeof(ino));
623 printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(ino));
624
625 count = sfp->count;
626 sfep = xfs_dir2_sf_firstentry(sfp);
627 for (i = 0; i < count; i++) {
628 ino = M_DIROPS(log->l_mp)->sf_get_ino(sfp, sfep);
629 memmove(namebuf, (sfep->name), sfep->namelen);
630 namebuf[sfep->namelen] = '\0';
631 printf(_("%s ino 0x%llx namelen %d\n"),
632 namebuf, (unsigned long long)ino, sfep->namelen);
633 sfep = M_DIROPS(log->l_mp)->sf_nextentry(sfp, sfep);
634 }
635 }
636
637 int
638 xlog_print_trans_inode(
639 struct xlog *log,
640 char **ptr,
641 int len,
642 int *i,
643 int num_ops,
644 int continued)
645 {
646 xfs_icdinode_t dino;
647 xlog_op_header_t *op_head;
648 xfs_inode_log_format_t dst_lbuf;
649 xfs_inode_log_format_64_t src_lbuf; /* buffer of biggest one */
650 xfs_inode_log_format_t *f;
651 int mode;
652 int size;
653
654 /*
655 * print inode type header region
656 *
657 * memmove to ensure 8-byte alignment for the long longs in
658 * xfs_inode_log_format_t structure
659 *
660 * len can be smaller than xfs_inode_log_format_32|64_t
661 * if format data is split over operations
662 */
663 memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len));
664 (*i)++; /* bump index */
665 *ptr += len;
666 if (!continued &&
667 (len == sizeof(xfs_inode_log_format_32_t) ||
668 len == sizeof(xfs_inode_log_format_64_t))) {
669 f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf);
670 printf(_("INODE: "));
671 printf(_("#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n"),
672 f->ilf_size, (unsigned long long)f->ilf_ino,
673 f->ilf_fields, f->ilf_dsize);
674 printf(_(" blkno: %lld len: %d boff: %d\n"),
675 (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset);
676 } else {
677 ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */
678 f = (xfs_inode_log_format_t *)&src_lbuf;
679 printf(_("INODE: #regs: %d Not printing rest of data\n"),
680 f->ilf_size);
681 return f->ilf_size;
682 }
683
684 if (*i >= num_ops) /* end of LR */
685 return f->ilf_size-1;
686
687 /* core inode comes 2nd */
688 op_head = (xlog_op_header_t *)*ptr;
689 xlog_print_op_header(op_head, *i, ptr);
690
691 if (op_head->oh_flags & XLOG_CONTINUE_TRANS) {
692 return f->ilf_size-1;
693 }
694
695 memmove(&dino, *ptr, sizeof(dino));
696 mode = dino.di_mode & S_IFMT;
697 size = (int)dino.di_size;
698 xlog_print_trans_inode_core(&dino);
699 *ptr += xfs_icdinode_size(dino.di_version);
700
701 if (*i == num_ops-1 && f->ilf_size == 3) {
702 return 1;
703 }
704
705 /* does anything come next */
706 op_head = (xlog_op_header_t *)*ptr;
707
708 switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
709 case XFS_ILOG_DEV:
710 printf(_("DEV inode: no extra region\n"));
711 break;
712 case XFS_ILOG_UUID:
713 printf(_("UUID inode: no extra region\n"));
714 break;
715 }
716
717 /* Only the inode core is logged */
718 if (f->ilf_size == 2)
719 return 0;
720
721 ASSERT(f->ilf_size <= 4);
722 ASSERT((f->ilf_size == 3) || (f->ilf_fields & XFS_ILOG_AFORK));
723
724 if (f->ilf_fields & XFS_ILOG_DFORK) {
725 (*i)++;
726 xlog_print_op_header(op_head, *i, ptr);
727
728 switch (f->ilf_fields & XFS_ILOG_DFORK) {
729 case XFS_ILOG_DEXT:
730 printf(_("EXTENTS inode data\n"));
731 break;
732 case XFS_ILOG_DBROOT:
733 printf(_("BTREE inode data\n"));
734 break;
735 case XFS_ILOG_DDATA:
736 printf(_("LOCAL inode data\n"));
737 if (mode == S_IFDIR)
738 xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
739 break;
740 default:
741 ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0);
742 break;
743 }
744
745 *ptr += be32_to_cpu(op_head->oh_len);
746 if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
747 return 1;
748 op_head = (xlog_op_header_t *)*ptr;
749 }
750
751 if (f->ilf_fields & XFS_ILOG_AFORK) {
752 (*i)++;
753 xlog_print_op_header(op_head, *i, ptr);
754
755 switch (f->ilf_fields & XFS_ILOG_AFORK) {
756 case XFS_ILOG_AEXT:
757 printf(_("EXTENTS attr data\n"));
758 break;
759 case XFS_ILOG_ABROOT:
760 printf(_("BTREE attr data\n"));
761 break;
762 case XFS_ILOG_ADATA:
763 printf(_("LOCAL attr data\n"));
764 if (mode == S_IFDIR)
765 xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
766 break;
767 default:
768 ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0);
769 break;
770 }
771 *ptr += be32_to_cpu(op_head->oh_len);
772 if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
773 return 1;
774 }
775
776 return 0;
777 } /* xlog_print_trans_inode */
778
779
780 int
781 xlog_print_trans_dquot(char **ptr, int len, int *i, int num_ops)
782 {
783 xfs_dq_logformat_t *f;
784 xfs_dq_logformat_t lbuf = {0};
785 xfs_disk_dquot_t ddq;
786 xlog_op_header_t *head = NULL;
787 int num, skip;
788
789 /*
790 * print dquot header region
791 *
792 * memmove to ensure 8-byte alignment for the long longs in
793 * xfs_dq_logformat_t structure
794 */
795 memmove(&lbuf, *ptr, MIN(sizeof(xfs_dq_logformat_t), len));
796 f = &lbuf;
797 (*i)++; /* bump index */
798 *ptr += len;
799
800 if (len == sizeof(xfs_dq_logformat_t)) {
801 printf(_("#regs: %d id: 0x%x"), f->qlf_size, f->qlf_id);
802 printf(_(" blkno: %lld len: %d boff: %d\n"),
803 (long long)f->qlf_blkno, f->qlf_len, f->qlf_boffset);
804 } else {
805 ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */
806 printf(_("DQUOT: #regs: %d Not printing rest of data\n"),
807 f->qlf_size);
808 return f->qlf_size;
809 }
810 num = f->qlf_size-1;
811
812 /* Check if all regions in this log item were in the given LR ptr */
813 if (*i+num > num_ops-1) {
814 skip = num - (num_ops-1-*i);
815 num = num_ops-1-*i;
816 } else {
817 skip = 0;
818 }
819
820 while (num-- > 0) {
821 head = (xlog_op_header_t *)*ptr;
822 xlog_print_op_header(head, *i, ptr);
823 ASSERT(be32_to_cpu(head->oh_len) == sizeof(xfs_disk_dquot_t));
824 memmove(&ddq, *ptr, sizeof(xfs_disk_dquot_t));
825 printf(_("DQUOT: magic 0x%hx flags 0%ho\n"),
826 be16_to_cpu(ddq.d_magic), ddq.d_flags);
827 *ptr += be32_to_cpu(head->oh_len);
828 }
829 if (head && head->oh_flags & XLOG_CONTINUE_TRANS)
830 skip++;
831 return skip;
832 } /* xlog_print_trans_dquot */
833
834
835 STATIC int
836 xlog_print_trans_icreate(
837 char **ptr,
838 int len,
839 int *i,
840 int num_ops)
841 {
842 struct xfs_icreate_log icl_buf = {0};
843 struct xfs_icreate_log *icl;
844
845 memmove(&icl_buf, *ptr, MIN(sizeof(struct xfs_icreate_log), len));
846 icl = &icl_buf;
847 *ptr += len;
848
849 /* handle complete header only */
850 if (len != sizeof(struct xfs_icreate_log)) {
851 printf(_("ICR: split header, not printing\n"));
852 return 1; /* to skip leftover in next region */
853 }
854
855 printf(_("ICR: #ag: %d agbno: 0x%x len: %d\n"
856 " cnt: %d isize: %d gen: 0x%x\n"),
857 be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno),
858 be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count),
859 be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen));
860 return 0;
861 }
862
863 /******************************************************************************
864 *
865 * Log print routines
866 *
867 ******************************************************************************
868 */
869
870 void
871 xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence)
872 {
873 #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT)
874 xfs_off_t offset;
875
876 if (whence == SEEK_SET)
877 offset = BBTOOFF64(blkno+log->l_logBBstart);
878 else
879 offset = BBTOOFF64(blkno);
880 if (lseek64(fd, offset, whence) < 0) {
881 fprintf(stderr, _("%s: lseek64 to %lld failed: %s\n"),
882 progname, (long long)offset, strerror(errno));
883 exit(1);
884 }
885 } /* xlog_print_lseek */
886
887
888 void
889 print_lsn(char *string,
890 __be64 *lsn)
891 {
892 printf("%s: %u,%u", string,
893 CYCLE_LSN(be64_to_cpu(*lsn)), BLOCK_LSN(be64_to_cpu(*lsn)));
894 }
895
896
897 int
898 xlog_print_record(
899 struct xlog *log,
900 int fd,
901 int num_ops,
902 int len,
903 int *read_type,
904 char **partial_buf,
905 xlog_rec_header_t *rhead,
906 xlog_rec_ext_header_t *xhdrs,
907 int bad_hdr_warn)
908 {
909 char *buf, *ptr;
910 int read_len, skip, lost_context = 0;
911 int ret, n, i, j, k;
912
913 if (print_no_print)
914 return NO_ERROR;
915
916 if (!len) {
917 printf("\n");
918 return NO_ERROR;
919 }
920
921 /* read_len must read up to some block boundary */
922 read_len = (int) BBTOB(BTOBB(len));
923
924 /* read_type => don't malloc() new buffer, use old one */
925 if (*read_type == FULL_READ) {
926 if ((ptr = buf = malloc(read_len)) == NULL) {
927 fprintf(stderr, _("%s: xlog_print_record: malloc failed\n"), progname);
928 exit(1);
929 }
930 } else {
931 read_len -= *read_type;
932 buf = (char *)((intptr_t)(*partial_buf) + (intptr_t)(*read_type));
933 ptr = *partial_buf;
934 }
935 if ((ret = (int) read(fd, buf, read_len)) == -1) {
936 fprintf(stderr, _("%s: xlog_print_record: read error\n"), progname);
937 exit(1);
938 }
939 /* Did we overflow the end? */
940 if (*read_type == FULL_READ &&
941 BLOCK_LSN(be64_to_cpu(rhead->h_lsn)) + BTOBB(read_len) >=
942 logBBsize) {
943 *read_type = BBTOB(logBBsize - BLOCK_LSN(be64_to_cpu(rhead->h_lsn))-1);
944 *partial_buf = buf;
945 return PARTIAL_READ;
946 }
947
948 /* Did we read everything? */
949 if ((ret == 0 && read_len != 0) || ret != read_len) {
950 *read_type = ret;
951 *partial_buf = buf;
952 return PARTIAL_READ;
953 }
954 if (*read_type != FULL_READ)
955 read_len += *read_type;
956
957 /* Everything read in. Start from beginning of buffer
958 * Unpack the data, by putting the saved cycle-data back
959 * into the first word of each BB.
960 * Do some checks.
961 */
962 buf = ptr;
963 for (i = 0; ptr < buf + read_len; ptr += BBSIZE, i++) {
964 xlog_rec_header_t *rechead = (xlog_rec_header_t *)ptr;
965
966 /* sanity checks */
967 if (be32_to_cpu(rechead->h_magicno) == XLOG_HEADER_MAGIC_NUM) {
968 /* data should not have magicno as first word
969 * as it should by cycle#
970 */
971 free(buf);
972 return -1;
973 } else {
974 /* verify cycle#
975 * FIXME: cycle+1 should be a macro pv#900369
976 */
977 if (be32_to_cpu(rhead->h_cycle) !=
978 be32_to_cpu(*(__be32 *)ptr)) {
979 if ((*read_type == FULL_READ) ||
980 (be32_to_cpu(rhead->h_cycle) + 1 !=
981 be32_to_cpu(*(__be32 *)ptr))) {
982 free(buf);
983 return -1;
984 }
985 }
986 }
987
988 /* copy back the data from the header */
989 if (i < XLOG_HEADER_CYCLE_SIZE / BBSIZE) {
990 /* from 1st header */
991 *(__be32 *)ptr = rhead->h_cycle_data[i];
992 }
993 else {
994 ASSERT(xhdrs != NULL);
995 /* from extra headers */
996 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
997 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
998 *(__be32 *)ptr = xhdrs[j-1].xh_cycle_data[k];
999 }
1000
1001 }
1002
1003 ptr = buf;
1004 for (i=0; i<num_ops; i++) {
1005 int continued;
1006
1007 xlog_op_header_t *op_head = (xlog_op_header_t *)ptr;
1008
1009 print_xlog_op_line();
1010 xlog_print_op_header(op_head, i, &ptr);
1011 continued = ((op_head->oh_flags & XLOG_WAS_CONT_TRANS) ||
1012 (op_head->oh_flags & XLOG_CONTINUE_TRANS));
1013
1014 if (continued && be32_to_cpu(op_head->oh_len) == 0)
1015 continue;
1016
1017 if (print_no_data) {
1018 for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) {
1019 printf("0x%02x ", (unsigned int)*ptr);
1020 if (n % 16 == 15)
1021 printf("\n");
1022 ptr++;
1023 }
1024 printf("\n");
1025 continue;
1026 }
1027
1028 /* print transaction data */
1029 if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid),
1030 op_head->oh_flags & XLOG_WAS_CONT_TRANS)) {
1031 printf(_("Left over region from split log item\n"));
1032 /* Skip this leftover bit */
1033 ptr += be32_to_cpu(op_head->oh_len);
1034 /* We've lost context; don't complain if next one looks bad too */
1035 lost_context = 1;
1036 continue;
1037 }
1038
1039 if (be32_to_cpu(op_head->oh_len) != 0) {
1040 if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) {
1041 skip = xlog_print_trans_header(&ptr,
1042 be32_to_cpu(op_head->oh_len));
1043 } else {
1044 switch (*(unsigned short *)ptr) {
1045 case XFS_LI_BUF: {
1046 skip = xlog_print_trans_buffer(&ptr,
1047 be32_to_cpu(op_head->oh_len),
1048 &i, num_ops);
1049 break;
1050 }
1051 case XFS_LI_ICREATE: {
1052 skip = xlog_print_trans_icreate(&ptr,
1053 be32_to_cpu(op_head->oh_len),
1054 &i, num_ops);
1055 break;
1056 }
1057 case XFS_LI_INODE: {
1058 skip = xlog_print_trans_inode(log, &ptr,
1059 be32_to_cpu(op_head->oh_len),
1060 &i, num_ops, continued);
1061 break;
1062 }
1063 case XFS_LI_DQUOT: {
1064 skip = xlog_print_trans_dquot(&ptr,
1065 be32_to_cpu(op_head->oh_len),
1066 &i, num_ops);
1067 break;
1068 }
1069 case XFS_LI_EFI: {
1070 skip = xlog_print_trans_efi(&ptr,
1071 be32_to_cpu(op_head->oh_len),
1072 continued);
1073 break;
1074 }
1075 case XFS_LI_EFD: {
1076 skip = xlog_print_trans_efd(&ptr,
1077 be32_to_cpu(op_head->oh_len));
1078 break;
1079 }
1080 case XFS_LI_QUOTAOFF: {
1081 skip = xlog_print_trans_qoff(&ptr,
1082 be32_to_cpu(op_head->oh_len));
1083 break;
1084 }
1085 case XLOG_UNMOUNT_TYPE: {
1086 printf(_("Unmount filesystem\n"));
1087 skip = 0;
1088 break;
1089 }
1090 default: {
1091 if (bad_hdr_warn && !lost_context) {
1092 fprintf(stderr,
1093 _("%s: unknown log operation type (%x)\n"),
1094 progname, *(unsigned short *)ptr);
1095 if (print_exit) {
1096 free(buf);
1097 return BAD_HEADER;
1098 }
1099 } else {
1100 printf(
1101 _("Left over region from split log item\n"));
1102 }
1103 skip = 0;
1104 ptr += be32_to_cpu(op_head->oh_len);
1105 lost_context = 0;
1106 }
1107 } /* switch */
1108 } /* else */
1109 if (skip != 0)
1110 xlog_print_add_to_trans(be32_to_cpu(op_head->oh_tid), skip);
1111 }
1112 }
1113 printf("\n");
1114 free(buf);
1115 return NO_ERROR;
1116 } /* xlog_print_record */
1117
1118
1119 int
1120 xlog_print_rec_head(xlog_rec_header_t *head, int *len, int bad_hdr_warn)
1121 {
1122 int i;
1123 char uub[64];
1124 int datalen,bbs;
1125
1126 if (print_no_print)
1127 return be32_to_cpu(head->h_num_logops);
1128
1129 if (!head->h_magicno)
1130 return ZEROED_LOG;
1131
1132 if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) {
1133 if (bad_hdr_warn)
1134 printf(_("Header 0x%x wanted 0x%x\n"),
1135 be32_to_cpu(head->h_magicno),
1136 XLOG_HEADER_MAGIC_NUM);
1137 return BAD_HEADER;
1138 }
1139
1140 /* check for cleared blocks written by xlog_clear_stale_blocks() */
1141 if (!head->h_len && !head->h_crc && !head->h_prev_block &&
1142 !head->h_num_logops && !head->h_size)
1143 return CLEARED_BLKS;
1144
1145 datalen=be32_to_cpu(head->h_len);
1146 bbs=BTOBB(datalen);
1147
1148 printf(_("cycle: %d version: %d "),
1149 be32_to_cpu(head->h_cycle),
1150 be32_to_cpu(head->h_version));
1151 print_lsn(" lsn", &head->h_lsn);
1152 print_lsn(" tail_lsn", &head->h_tail_lsn);
1153 printf("\n");
1154 printf(_("length of Log Record: %d prev offset: %d num ops: %d\n"),
1155 datalen,
1156 be32_to_cpu(head->h_prev_block),
1157 be32_to_cpu(head->h_num_logops));
1158
1159 if (print_overwrite) {
1160 printf(_("cycle num overwrites: "));
1161 for (i=0; i< MIN(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++)
1162 printf("%d - 0x%x ",
1163 i,
1164 be32_to_cpu(head->h_cycle_data[i]));
1165 printf("\n");
1166 }
1167
1168 platform_uuid_unparse(&head->h_fs_uuid, uub);
1169 printf(_("uuid: %s format: "), uub);
1170 switch (be32_to_cpu(head->h_fmt)) {
1171 case XLOG_FMT_UNKNOWN:
1172 printf(_("unknown\n"));
1173 break;
1174 case XLOG_FMT_LINUX_LE:
1175 printf(_("little endian linux\n"));
1176 break;
1177 case XLOG_FMT_LINUX_BE:
1178 printf(_("big endian linux\n"));
1179 break;
1180 case XLOG_FMT_IRIX_BE:
1181 printf(_("big endian irix\n"));
1182 break;
1183 default:
1184 printf("? (%d)\n", be32_to_cpu(head->h_fmt));
1185 break;
1186 }
1187 printf(_("h_size: %d\n"), be32_to_cpu(head->h_size));
1188
1189 *len = be32_to_cpu(head->h_len);
1190 return(be32_to_cpu(head->h_num_logops));
1191 } /* xlog_print_rec_head */
1192
1193 void
1194 xlog_print_rec_xhead(xlog_rec_ext_header_t *head, int coverage)
1195 {
1196 int i;
1197
1198 print_xlog_xhdr_line();
1199 printf(_("extended-header: cycle: %d\n"), be32_to_cpu(head->xh_cycle));
1200
1201 if (print_overwrite) {
1202 printf(_("cycle num overwrites: "));
1203 for (i = 0; i < coverage; i++)
1204 printf("%d - 0x%x ",
1205 i,
1206 be32_to_cpu(head->xh_cycle_data[i]));
1207 printf("\n");
1208 }
1209 } /* xlog_print_rec_xhead */
1210
1211 static void
1212 print_xlog_bad_zeroed(xfs_daddr_t blkno)
1213 {
1214 print_stars();
1215 printf(_("* ERROR: found data after zeroed blocks block=%-21lld *\n"),
1216 (long long)blkno);
1217 print_stars();
1218 if (print_exit)
1219 xlog_exit("Bad log - data after zeroed blocks");
1220 } /* print_xlog_bad_zeroed */
1221
1222 static void
1223 print_xlog_bad_header(xfs_daddr_t blkno, char *buf)
1224 {
1225 print_stars();
1226 printf(_("* ERROR: header cycle=%-11d block=%-21lld *\n"),
1227 xlog_get_cycle(buf), (long long)blkno);
1228 print_stars();
1229 if (print_exit)
1230 xlog_exit("Bad log record header");
1231 } /* print_xlog_bad_header */
1232
1233 void
1234 print_xlog_bad_data(xfs_daddr_t blkno)
1235 {
1236 print_stars();
1237 printf(_("* ERROR: data block=%-21lld *\n"),
1238 (long long)blkno);
1239 print_stars();
1240 if (print_exit)
1241 xlog_exit("Bad data in log");
1242 } /* print_xlog_bad_data */
1243
1244 static void
1245 print_xlog_bad_reqd_hdrs(xfs_daddr_t blkno, int num_reqd, int num_hdrs)
1246 {
1247 print_stars();
1248 printf(_("* ERROR: for header block=%lld\n"
1249 "* not enough hdrs for data length, "
1250 "required num = %d, hdr num = %d\n"),
1251 (long long)blkno, num_reqd, num_hdrs);
1252 print_stars();
1253 if (print_exit)
1254 xlog_exit(_("Not enough headers for data length."));
1255 } /* print_xlog_bad_reqd_hdrs */
1256
1257 static void
1258 xlog_reallocate_xhdrs(int num_hdrs, xlog_rec_ext_header_t **ret_xhdrs)
1259 {
1260 int len = (num_hdrs-1) * sizeof(xlog_rec_ext_header_t);
1261
1262 *ret_xhdrs = (xlog_rec_ext_header_t *)realloc(*ret_xhdrs, len);
1263 if (*ret_xhdrs == NULL) {
1264 fprintf(stderr, _("%s: xlog_print: malloc failed for ext hdrs\n"), progname);
1265 exit(1);
1266 }
1267 }
1268
1269 /* for V2 logs read each extra hdr and print it out */
1270 static int
1271 xlog_print_extended_headers(
1272 int fd,
1273 int len,
1274 xfs_daddr_t *blkno,
1275 xlog_rec_header_t *hdr,
1276 int *ret_num_hdrs,
1277 xlog_rec_ext_header_t **ret_xhdrs)
1278 {
1279 int i, j;
1280 int coverage_bb;
1281 int num_hdrs;
1282 int num_required;
1283 char xhbuf[XLOG_HEADER_SIZE];
1284 xlog_rec_ext_header_t *x;
1285
1286 num_required = howmany(len, XLOG_HEADER_CYCLE_SIZE);
1287 num_hdrs = be32_to_cpu(hdr->h_size) / XLOG_HEADER_CYCLE_SIZE;
1288
1289 if (num_required > num_hdrs) {
1290 print_xlog_bad_reqd_hdrs((*blkno)-1, num_required, num_hdrs);
1291 }
1292
1293 if (num_hdrs == 1) {
1294 free(*ret_xhdrs);
1295 *ret_xhdrs = NULL;
1296 *ret_num_hdrs = 1;
1297 return 0;
1298 }
1299
1300 if (*ret_xhdrs == NULL || num_hdrs > *ret_num_hdrs) {
1301 xlog_reallocate_xhdrs(num_hdrs, ret_xhdrs);
1302 }
1303
1304 *ret_num_hdrs = num_hdrs;
1305
1306 /* don't include 1st header */
1307 for (i = 1, x = *ret_xhdrs; i < num_hdrs; i++, (*blkno)++, x++) {
1308 /* read one extra header blk */
1309 if (read(fd, xhbuf, 512) == 0) {
1310 printf(_("%s: physical end of log\n"), progname);
1311 print_xlog_record_line();
1312 /* reached the end so return 1 */
1313 return 1;
1314 }
1315 if (print_only_data) {
1316 printf(_("BLKNO: %lld\n"), (long long)*blkno);
1317 xlog_recover_print_data(xhbuf, 512);
1318 }
1319 else {
1320 if (i == num_hdrs - 1) {
1321 /* last header */
1322 coverage_bb = BTOBB(len) %
1323 (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
1324 }
1325 else {
1326 /* earliear header */
1327 coverage_bb = XLOG_HEADER_CYCLE_SIZE / BBSIZE;
1328 }
1329 xlog_print_rec_xhead((xlog_rec_ext_header_t*)xhbuf, coverage_bb);
1330 }
1331
1332 /* Copy from buffer into xhdrs array for later.
1333 * Could endian convert here but then code later on
1334 * will look asymmetric with the 1 hdr normal case
1335 * which does endian coversion on access.
1336 */
1337 x->xh_cycle = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle;
1338 for (j = 0; j < XLOG_HEADER_CYCLE_SIZE / BBSIZE; j++) {
1339 x->xh_cycle_data[j] =
1340 ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle_data[j];
1341 }
1342 }
1343 return 0;
1344 }
1345
1346
1347 /*
1348 * This code is gross and needs to be rewritten.
1349 */
1350 void xfs_log_print(struct xlog *log,
1351 int fd,
1352 int print_block_start)
1353 {
1354 char hbuf[XLOG_HEADER_SIZE];
1355 xlog_rec_header_t *hdr = (xlog_rec_header_t *)&hbuf[0];
1356 xlog_rec_ext_header_t *xhdrs = NULL;
1357 int num_ops, len, num_hdrs = 1;
1358 xfs_daddr_t block_end = 0, block_start, blkno, error;
1359 xfs_daddr_t zeroed_blkno = 0, cleared_blkno = 0;
1360 int read_type = FULL_READ;
1361 char *partial_buf;
1362 int zeroed = 0;
1363 int cleared = 0;
1364 int first_hdr_found = 0;
1365
1366 logBBsize = log->l_logBBsize;
1367
1368 /*
1369 * Normally, block_start and block_end are the same value since we
1370 * are printing the entire log. However, if the start block is given,
1371 * we still end at the end of the logical log.
1372 */
1373 if ((error = xlog_print_find_oldest(log, &block_end))) {
1374 fprintf(stderr, _("%s: problem finding oldest LR\n"), progname);
1375 return;
1376 }
1377 if (print_block_start == -1)
1378 block_start = block_end;
1379 else
1380 block_start = print_block_start;
1381 xlog_print_lseek(log, fd, block_start, SEEK_SET);
1382 blkno = block_start;
1383
1384 for (;;) {
1385 if (read(fd, hbuf, 512) == 0) {
1386 printf(_("%s: physical end of log\n"), progname);
1387 print_xlog_record_line();
1388 break;
1389 }
1390 if (print_only_data) {
1391 printf(_("BLKNO: %lld\n"), (long long)blkno);
1392 xlog_recover_print_data(hbuf, 512);
1393 blkno++;
1394 goto loop;
1395 }
1396 num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
1397 blkno++;
1398
1399 if (zeroed && num_ops != ZEROED_LOG) {
1400 printf(_("%s: after %d zeroed blocks\n"), progname, zeroed);
1401 /* once we find zeroed blocks - that's all we expect */
1402 print_xlog_bad_zeroed(blkno-1);
1403 /* reset count since we're assuming previous zeroed blocks
1404 * were bad
1405 */
1406 zeroed = 0;
1407 }
1408
1409 if (num_ops == ZEROED_LOG ||
1410 num_ops == CLEARED_BLKS ||
1411 num_ops == BAD_HEADER) {
1412 if (num_ops == ZEROED_LOG) {
1413 if (zeroed == 0)
1414 zeroed_blkno = blkno-1;
1415 zeroed++;
1416 }
1417 else if (num_ops == CLEARED_BLKS) {
1418 if (cleared == 0)
1419 cleared_blkno = blkno-1;
1420 cleared++;
1421 } else {
1422 if (!first_hdr_found)
1423 block_start = blkno;
1424 else
1425 print_xlog_bad_header(blkno-1, hbuf);
1426 }
1427
1428 goto loop;
1429 }
1430
1431 if (be32_to_cpu(hdr->h_version) == 2) {
1432 if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0)
1433 break;
1434 }
1435
1436 error = xlog_print_record(log, fd, num_ops, len, &read_type, &partial_buf,
1437 hdr, xhdrs, first_hdr_found);
1438 first_hdr_found++;
1439 switch (error) {
1440 case 0: {
1441 blkno += BTOBB(len);
1442 if (print_block_start != -1 &&
1443 blkno >= block_end) /* If start specified, we */
1444 goto end; /* end early */
1445 break;
1446 }
1447 case -1: {
1448 print_xlog_bad_data(blkno-1);
1449 if (print_block_start != -1 &&
1450 blkno >= block_end) /* If start specified, */
1451 goto end; /* we end early */
1452 xlog_print_lseek(log, fd, blkno, SEEK_SET);
1453 goto loop;
1454 }
1455 case PARTIAL_READ: {
1456 print_xlog_record_line();
1457 printf(_("%s: physical end of log\n"), progname);
1458 print_xlog_record_line();
1459 blkno = 0;
1460 xlog_print_lseek(log, fd, 0, SEEK_SET);
1461 /*
1462 * We may have hit the end of the log when we started at 0.
1463 * In this case, just end.
1464 */
1465 if (block_start == 0)
1466 goto end;
1467 goto partial_log_read;
1468 }
1469 default: xlog_panic(_("illegal value"));
1470 }
1471 print_xlog_record_line();
1472 loop:
1473 if (blkno >= logBBsize) {
1474 if (cleared) {
1475 printf(_("%s: skipped %d cleared blocks in range: %lld - %lld\n"),
1476 progname, cleared,
1477 (long long)(cleared_blkno),
1478 (long long)(cleared + cleared_blkno - 1));
1479 if (cleared == logBBsize)
1480 printf(_("%s: totally cleared log\n"), progname);
1481
1482 cleared=0;
1483 }
1484 if (zeroed) {
1485 printf(_("%s: skipped %d zeroed blocks in range: %lld - %lld\n"),
1486 progname, zeroed,
1487 (long long)(zeroed_blkno),
1488 (long long)(zeroed + zeroed_blkno - 1));
1489 if (zeroed == logBBsize)
1490 printf(_("%s: totally zeroed log\n"), progname);
1491
1492 zeroed=0;
1493 }
1494 printf(_("%s: physical end of log\n"), progname);
1495 print_xlog_record_line();
1496 break;
1497 }
1498 }
1499
1500 /* Do we need to print the first part of physical log? */
1501 if (block_start != 0) {
1502 blkno = 0;
1503 xlog_print_lseek(log, fd, 0, SEEK_SET);
1504 for (;;) {
1505 if (read(fd, hbuf, 512) == 0) {
1506 xlog_panic(_("xlog_find_head: bad read"));
1507 }
1508 if (print_only_data) {
1509 printf(_("BLKNO: %lld\n"), (long long)blkno);
1510 xlog_recover_print_data(hbuf, 512);
1511 blkno++;
1512 goto loop2;
1513 }
1514 num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
1515 blkno++;
1516
1517 if (num_ops == ZEROED_LOG ||
1518 num_ops == CLEARED_BLKS ||
1519 num_ops == BAD_HEADER) {
1520 /* we only expect zeroed log entries or cleared log
1521 * entries at the end of the _physical_ log,
1522 * so treat them the same as bad blocks here
1523 */
1524 print_xlog_bad_header(blkno-1, hbuf);
1525
1526 if (blkno >= block_end)
1527 break;
1528 continue;
1529 }
1530
1531 if (be32_to_cpu(hdr->h_version) == 2) {
1532 if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0)
1533 break;
1534 }
1535
1536 partial_log_read:
1537 error= xlog_print_record(log, fd, num_ops, len, &read_type,
1538 &partial_buf, (xlog_rec_header_t *)hbuf,
1539 xhdrs, first_hdr_found);
1540 if (read_type != FULL_READ)
1541 len -= read_type;
1542 read_type = FULL_READ;
1543 if (!error)
1544 blkno += BTOBB(len);
1545 else {
1546 print_xlog_bad_data(blkno-1);
1547 xlog_print_lseek(log, fd, blkno, SEEK_SET);
1548 goto loop2;
1549 }
1550 print_xlog_record_line();
1551 loop2:
1552 if (blkno >= block_end)
1553 break;
1554 }
1555 }
1556
1557 end:
1558 printf(_("%s: logical end of log\n"), progname);
1559 print_xlog_record_line();
1560 }
1561
1562 /*
1563 * if necessary, convert an xfs_inode_log_format struct from 32bit or 64 bit versions
1564 * (which can have different field alignments) to the native version
1565 */
1566 xfs_inode_log_format_t *
1567 xfs_inode_item_format_convert(char *src_buf, uint len, xfs_inode_log_format_t *in_f)
1568 {
1569 /* if we have native format then just return buf without copying data */
1570 if (len == sizeof(xfs_inode_log_format_t)) {
1571 return (xfs_inode_log_format_t *)src_buf;
1572 }
1573
1574 if (len == sizeof(xfs_inode_log_format_32_t)) {
1575 xfs_inode_log_format_32_t *in_f32;
1576
1577 in_f32 = (xfs_inode_log_format_32_t *)src_buf;
1578 in_f->ilf_type = in_f32->ilf_type;
1579 in_f->ilf_size = in_f32->ilf_size;
1580 in_f->ilf_fields = in_f32->ilf_fields;
1581 in_f->ilf_asize = in_f32->ilf_asize;
1582 in_f->ilf_dsize = in_f32->ilf_dsize;
1583 in_f->ilf_ino = in_f32->ilf_ino;
1584 /* copy biggest */
1585 memcpy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid, sizeof(uuid_t));
1586 in_f->ilf_blkno = in_f32->ilf_blkno;
1587 in_f->ilf_len = in_f32->ilf_len;
1588 in_f->ilf_boffset = in_f32->ilf_boffset;
1589 } else {
1590 xfs_inode_log_format_64_t *in_f64;
1591
1592 ASSERT(len == sizeof(xfs_inode_log_format_64_t));
1593 in_f64 = (xfs_inode_log_format_64_t *)src_buf;
1594 in_f->ilf_type = in_f64->ilf_type;
1595 in_f->ilf_size = in_f64->ilf_size;
1596 in_f->ilf_fields = in_f64->ilf_fields;
1597 in_f->ilf_asize = in_f64->ilf_asize;
1598 in_f->ilf_dsize = in_f64->ilf_dsize;
1599 in_f->ilf_ino = in_f64->ilf_ino;
1600 /* copy biggest */
1601 memcpy(&in_f->ilf_u.ilfu_uuid, &in_f64->ilf_u.ilfu_uuid, sizeof(uuid_t));
1602 in_f->ilf_blkno = in_f64->ilf_blkno;
1603 in_f->ilf_len = in_f64->ilf_len;
1604 in_f->ilf_boffset = in_f64->ilf_boffset;
1605 }
1606 return in_f;
1607 }
1608
1609 int
1610 xfs_efi_copy_format(
1611 char *buf,
1612 uint len,
1613 struct xfs_efi_log_format *dst_efi_fmt,
1614 int continued)
1615 {
1616 uint i;
1617 uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents;
1618 uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents - 1) * sizeof(xfs_extent_t);
1619 uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t);
1620 uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t);
1621
1622 if (len == dst_len || continued) {
1623 memcpy((char *)dst_efi_fmt, buf, len);
1624 return 0;
1625 } else if (len == len32) {
1626 xfs_efi_log_format_32_t *src_efi_fmt_32 = (xfs_efi_log_format_32_t *)buf;
1627
1628 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
1629 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
1630 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
1631 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
1632 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
1633 dst_efi_fmt->efi_extents[i].ext_start =
1634 src_efi_fmt_32->efi_extents[i].ext_start;
1635 dst_efi_fmt->efi_extents[i].ext_len =
1636 src_efi_fmt_32->efi_extents[i].ext_len;
1637 }
1638 return 0;
1639 } else if (len == len64) {
1640 xfs_efi_log_format_64_t *src_efi_fmt_64 = (xfs_efi_log_format_64_t *)buf;
1641
1642 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
1643 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
1644 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
1645 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
1646 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
1647 dst_efi_fmt->efi_extents[i].ext_start =
1648 src_efi_fmt_64->efi_extents[i].ext_start;
1649 dst_efi_fmt->efi_extents[i].ext_len =
1650 src_efi_fmt_64->efi_extents[i].ext_len;
1651 }
1652 return 0;
1653 }
1654 fprintf(stderr, _("%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n"),
1655 progname, len, len32, len64, nextents);
1656 return 1;
1657 }