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