1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
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)
20 typedef struct xlog_split_item
{
21 struct xlog_split_item
*si_next
;
22 struct xlog_split_item
*si_prev
;
27 static xlog_split_item_t
*split_list
= NULL
;
30 print_xlog_op_line(void)
32 printf("--------------------------------------"
33 "--------------------------------------\n");
34 } /* print_xlog_op_line */
37 print_xlog_xhdr_line(void)
39 printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
40 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
41 } /* print_xlog_xhdr_line */
44 print_xlog_record_line(void)
46 printf("======================================"
47 "======================================\n");
48 } /* print_xlog_record_line */
53 printf("***********************************"
54 "***********************************\n");
58 * Given a pointer to a data segment, print out the data as if it were
59 * a log operation header.
62 xlog_print_op_header(xlog_op_header_t
*op_head
,
66 xlog_op_header_t hbuf
;
69 * memmove because on 64/n32, partial reads can cause the op_head
70 * pointer to come in pointing to an odd-numbered byte
72 memmove(&hbuf
, op_head
, sizeof(xlog_op_header_t
));
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")));
81 if (op_head
->oh_flags
) {
82 if (op_head
->oh_flags
& XLOG_START_TRANS
)
84 if (op_head
->oh_flags
& XLOG_COMMIT_TRANS
)
86 if (op_head
->oh_flags
& XLOG_WAS_CONT_TRANS
)
88 if (op_head
->oh_flags
& XLOG_UNMOUNT_TRANS
)
90 if (op_head
->oh_flags
& XLOG_CONTINUE_TRANS
)
92 if (op_head
->oh_flags
& XLOG_END_TRANS
)
98 } /* xlog_print_op_header */
102 xlog_print_add_to_trans(xlog_tid_t tid
,
105 xlog_split_item_t
*item
;
107 item
= (xlog_split_item_t
*)calloc(sizeof(xlog_split_item_t
), 1);
109 item
->si_skip
= skip
;
110 item
->si_next
= split_list
;
111 item
->si_prev
= NULL
;
113 split_list
->si_prev
= item
;
115 } /* xlog_print_add_to_trans */
119 xlog_print_find_tid(xlog_tid_t tid
, uint was_cont
)
121 xlog_split_item_t
*listp
= split_list
;
124 if (was_cont
!= 0) /* Not first time we have used this tid */
130 if (listp
->si_xtid
== tid
)
132 listp
= listp
->si_next
;
137 if (--listp
->si_skip
== 0) {
138 if (listp
== split_list
) { /* delete at head */
139 split_list
= listp
->si_next
;
141 split_list
->si_prev
= NULL
;
144 listp
->si_next
->si_prev
= listp
->si_prev
;
145 listp
->si_prev
->si_next
= listp
->si_next
;
150 } /* xlog_print_find_tid */
153 xlog_print_trans_header(char **ptr
, int len
)
155 xfs_trans_header_t
*h
;
158 char *magic_c
= (char *)&magic
;
162 magic
= *(uint32_t *)cptr
; /* XXX be32_to_cpu soon */
165 #if __BYTE_ORDER == __LITTLE_ENDIAN
167 magic_c
[3], magic_c
[2], magic_c
[1], magic_c
[0]);
170 magic_c
[0], magic_c
[1], magic_c
[2], magic_c
[3]);
173 if (len
!= sizeof(xfs_trans_header_t
)) {
174 printf(_(" Not enough data to decode further\n"));
177 h
= (xfs_trans_header_t
*)cptr
;
178 printf(_(" tid: %x num_items: %d\n"),
179 h
->th_tid
, h
->th_num_items
);
181 } /* xlog_print_trans_header */
185 xlog_print_trans_buffer(char **ptr
, int len
, int *i
, int num_ops
)
187 xfs_buf_log_format_t
*f
;
188 xlog_op_header_t
*head
= NULL
;
191 int bucket
, col
, buckets
;
193 xfs_buf_log_format_t lbuf
;
194 int size
, blen
, map_size
, struct_size
;
195 unsigned short flags
;
198 * memmove to ensure 8-byte alignment for the long longs in
199 * buf_log_format_t structure
201 memmove(&lbuf
, *ptr
, min(sizeof(xfs_buf_log_format_t
), len
));
205 ASSERT(f
->blf_type
== XFS_LI_BUF
);
207 blkno
= f
->blf_blkno
;
210 map_size
= f
->blf_map_size
;
211 flags
= f
->blf_flags
;
214 * size of the format header is dependent on the size of the bitmap, not
215 * the size of the in-memory structure. Hence the slightly obtuse
218 struct_size
= offsetof(struct xfs_buf_log_format
, blf_map_size
) + map_size
;
220 if (len
>= struct_size
) {
221 ASSERT((len
- sizeof(struct_size
)) % sizeof(int) == 0);
222 printf(_("#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n"),
223 size
, (long long)blkno
, (unsigned long long)blkno
, blen
, map_size
, flags
);
227 ASSERT(len
>= 4); /* must have at least 4 bytes if != 0 */
228 printf(_("#regs: %d Not printing rest of data\n"), f
->blf_size
);
233 /* Check if all regions in this log item were in the given LR ptr */
234 if (*i
+num
> num_ops
-1) {
235 skip
= num
- (num_ops
-1-*i
);
242 head
= (xlog_op_header_t
*)*ptr
;
243 xlog_print_op_header(head
, *i
, ptr
);
245 printf(_("SUPER BLOCK Buffer: "));
246 if (be32_to_cpu(head
->oh_len
) < 4*8) {
247 printf(_("Out of space\n"));
253 * memmove because *ptr may not be 8-byte aligned
255 memmove(&a
, *ptr
, sizeof(__be64
));
256 memmove(&b
, *ptr
+8, sizeof(__be64
));
257 printf(_("icount: %llu ifree: %llu "),
258 (unsigned long long) be64_to_cpu(a
),
259 (unsigned long long) be64_to_cpu(b
));
260 memmove(&a
, *ptr
+16, sizeof(__be64
));
261 memmove(&b
, *ptr
+24, sizeof(__be64
));
262 printf(_("fdblks: %llu frext: %llu\n"),
263 (unsigned long long) be64_to_cpu(a
),
264 (unsigned long long) be64_to_cpu(b
));
267 } else if (be32_to_cpu(*(__be32
*)(*ptr
)) == XFS_AGI_MAGIC
) {
268 struct xfs_agi
*agi
, agi_s
;
270 /* memmove because *ptr may not be 8-byte aligned */
272 memmove(agi
, *ptr
, sizeof(struct xfs_agi
));
273 printf(_("AGI Buffer: XAGI "));
275 * v4 filesystems only contain the fields before the uuid.
276 * Even v5 filesystems don't log any field beneath it. That
277 * means that the size that is logged is almost always going to
278 * be smaller than the structure itself. Hence we need to make
279 * sure that the buffer contains all the data we want to print
280 * rather than just check against the structure size.
282 if (be32_to_cpu(head
->oh_len
) < offsetof(xfs_agi_t
, agi_uuid
) -
283 XFS_AGI_UNLINKED_BUCKETS
*sizeof(xfs_agino_t
)) {
284 printf(_("out of space\n"));
287 printf(_("ver: %d "),
288 be32_to_cpu(agi
->agi_versionnum
));
289 printf(_("seq#: %d len: %d cnt: %d root: %d\n"),
290 be32_to_cpu(agi
->agi_seqno
),
291 be32_to_cpu(agi
->agi_length
),
292 be32_to_cpu(agi
->agi_count
),
293 be32_to_cpu(agi
->agi_root
));
294 printf(_("level: %d free#: 0x%x newino: 0x%x\n"),
295 be32_to_cpu(agi
->agi_level
),
296 be32_to_cpu(agi
->agi_freecount
),
297 be32_to_cpu(agi
->agi_newino
));
298 if (be32_to_cpu(head
->oh_len
) == 128) {
300 } else if (be32_to_cpu(head
->oh_len
) == 256) {
303 if (head
->oh_flags
& XLOG_CONTINUE_TRANS
) {
304 printf(_("AGI unlinked data skipped "));
305 printf(_("(CONTINUE set, no space)\n"));
308 buckets
= XFS_AGI_UNLINKED_BUCKETS
;
310 for (bucket
= 0; bucket
< buckets
;) {
311 printf(_("bucket[%d - %d]: "), bucket
, bucket
+3);
312 for (col
= 0; col
< 4; col
++, bucket
++) {
313 if (bucket
< buckets
) {
315 be32_to_cpu(agi
->agi_unlinked
[bucket
]));
321 } else if (be32_to_cpu(*(__be32
*)(*ptr
)) == XFS_AGF_MAGIC
) {
322 struct xfs_agf
*agf
, agf_s
;
324 /* memmove because *ptr may not be 8-byte aligned */
326 memmove(agf
, *ptr
, sizeof(struct xfs_agf
));
327 printf(_("AGF Buffer: XAGF "));
329 * v4 filesystems only contain the fields before the uuid.
330 * Even v5 filesystems don't log any field beneath it. That
331 * means that the size that is logged is almost always going to
332 * be smaller than the structure itself. Hence we need to make
333 * sure that the buffer contains all the data we want to print
334 * rather than just check against the structure size.
336 if (be32_to_cpu(head
->oh_len
) < offsetof(xfs_agf_t
, agf_uuid
)) {
337 printf(_("Out of space\n"));
340 printf(_("ver: %d seq#: %d len: %d \n"),
341 be32_to_cpu(agf
->agf_versionnum
),
342 be32_to_cpu(agf
->agf_seqno
),
343 be32_to_cpu(agf
->agf_length
));
344 printf(_("root BNO: %d CNT: %d\n"),
345 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNOi
]),
346 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNTi
]));
347 printf(_("level BNO: %d CNT: %d\n"),
348 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNOi
]),
349 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNTi
]));
350 printf(_("1st: %d last: %d cnt: %d "
351 "freeblks: %d longest: %d\n"),
352 be32_to_cpu(agf
->agf_flfirst
),
353 be32_to_cpu(agf
->agf_fllast
),
354 be32_to_cpu(agf
->agf_flcount
),
355 be32_to_cpu(agf
->agf_freeblks
),
356 be32_to_cpu(agf
->agf_longest
));
358 } else if (be32_to_cpu(*(__be32
*)(*ptr
)) == XFS_DQUOT_MAGIC
) {
359 struct xfs_disk_dquot
*dq
, dq_s
;
361 /* memmove because *ptr may not be 8-byte aligned */
363 memmove(dq
, *ptr
, sizeof(struct xfs_disk_dquot
));
364 printf(_("DQUOT Buffer: DQ "));
365 if (be32_to_cpu(head
->oh_len
) <
366 sizeof(xfs_disk_dquot_t
)) {
367 printf(_("Out of space\n"));
371 printf(_("ver: %d flags: 0x%x id: %d \n"),
372 dq
->d_version
, dq
->d_flags
,
373 be32_to_cpu(dq
->d_id
));
374 printf(_("blk limits hard: %llu soft: %llu\n"),
376 be64_to_cpu(dq
->d_blk_hardlimit
),
378 be64_to_cpu(dq
->d_blk_softlimit
));
379 printf(_("blk count: %llu warns: %d timer: %d\n"),
380 (unsigned long long) be64_to_cpu(dq
->d_bcount
),
381 (int) be16_to_cpu(dq
->d_bwarns
),
382 be32_to_cpu(dq
->d_btimer
));
383 printf(_("ino limits hard: %llu soft: %llu\n"),
385 be64_to_cpu(dq
->d_ino_hardlimit
),
387 be64_to_cpu(dq
->d_ino_softlimit
));
388 printf(_("ino count: %llu warns: %d timer: %d\n"),
389 (unsigned long long) be64_to_cpu(dq
->d_icount
),
390 (int) be16_to_cpu(dq
->d_iwarns
),
391 be32_to_cpu(dq
->d_itimer
));
394 printf(_("BUF DATA\n"));
396 uint
*dp
= (uint
*)*ptr
;
397 int nums
= be32_to_cpu(head
->oh_len
) >> 2;
412 *ptr
+= be32_to_cpu(head
->oh_len
);
414 if (head
&& head
->oh_flags
& XLOG_CONTINUE_TRANS
)
417 } /* xlog_print_trans_buffer */
421 xlog_print_trans_qoff(char **ptr
, uint len
)
423 xfs_qoff_logformat_t
*f
;
424 xfs_qoff_logformat_t lbuf
;
426 memmove(&lbuf
, *ptr
, min(sizeof(xfs_qoff_logformat_t
), len
));
429 if (len
>= sizeof(xfs_qoff_logformat_t
)) {
430 printf(_("QOFF: #regs: %d flags: 0x%x\n"), f
->qf_size
, f
->qf_flags
);
433 printf(_("QOFF: Not enough data to decode further\n"));
436 } /* xlog_print_trans_qoff */
440 xlog_print_trans_inode_core(
441 struct xfs_log_dinode
*ip
)
443 printf(_("INODE CORE\n"));
444 printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
445 ip
->di_magic
, ip
->di_mode
, (int)ip
->di_version
,
447 printf(_("nlink %hd uid %d gid %d\n"),
448 ip
->di_nlink
, ip
->di_uid
, ip
->di_gid
);
449 printf(_("atime 0x%x mtime 0x%x ctime 0x%x\n"),
450 ip
->di_atime
.t_sec
, ip
->di_mtime
.t_sec
, ip
->di_ctime
.t_sec
);
451 printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
452 (unsigned long long)ip
->di_size
, (unsigned long long)ip
->di_nblocks
,
453 ip
->di_extsize
, ip
->di_nextents
);
454 printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
455 ip
->di_anextents
, (int)ip
->di_forkoff
, ip
->di_dmevmask
,
457 printf(_("flags 0x%x gen 0x%x\n"),
458 ip
->di_flags
, ip
->di_gen
);
459 if (ip
->di_version
== 3) {
460 printf(_("flags2 0x%llx cowextsize 0x%x\n"),
461 (unsigned long long)ip
->di_flags2
, ip
->di_cowextsize
);
468 xfs_dir2_sf_hdr_t
*sfp
,
471 __be64 pino
; /* parent inode nr */
476 xfs_dir2_sf_entry_t
*sfep
;
478 printf(_("SHORTFORM DIRECTORY size %d\n"),
480 /* bail out for now */
484 printf(_("SHORTFORM DIRECTORY size %d count %d\n"),
486 memmove(&pino
, &(sfp
->parent
), sizeof(pino
));
487 printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(pino
));
490 sfep
= xfs_dir2_sf_firstentry(sfp
);
491 for (i
= 0; i
< count
; i
++) {
492 ino
= M_DIROPS(log
->l_mp
)->sf_get_ino(sfp
, sfep
);
493 memmove(namebuf
, (sfep
->name
), sfep
->namelen
);
494 namebuf
[sfep
->namelen
] = '\0';
495 printf(_("%s ino 0x%llx namelen %d\n"),
496 namebuf
, (unsigned long long)ino
, sfep
->namelen
);
497 sfep
= M_DIROPS(log
->l_mp
)->sf_nextentry(sfp
, sfep
);
502 xlog_print_trans_inode(
510 struct xfs_log_dinode dino
;
511 struct xlog_op_header
*op_head
;
512 struct xfs_inode_log_format dst_lbuf
;
513 struct xfs_inode_log_format src_lbuf
;
514 struct xfs_inode_log_format
*f
;
520 * print inode type header region
522 * memmove to ensure 8-byte alignment for the long longs in
523 * struct xfs_inode_log_format structure
525 * len can be smaller than struct xfs_inode_log_format
526 * if format data is split over operations
528 memmove(&src_lbuf
, *ptr
, min(sizeof(src_lbuf
), len
));
529 (*i
)++; /* bump index */
532 (len
== sizeof(struct xfs_inode_log_format_32
) ||
533 len
== sizeof(struct xfs_inode_log_format
))) {
534 f
= xfs_inode_item_format_convert((char*)&src_lbuf
, len
, &dst_lbuf
);
535 printf(_("INODE: "));
536 printf(_("#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n"),
537 f
->ilf_size
, (unsigned long long)f
->ilf_ino
,
538 f
->ilf_fields
, f
->ilf_dsize
);
539 printf(_(" blkno: %lld len: %d boff: %d\n"),
540 (long long)f
->ilf_blkno
, f
->ilf_len
, f
->ilf_boffset
);
542 ASSERT(len
>= 4); /* must have at least 4 bytes if != 0 */
543 f
= (struct xfs_inode_log_format
*)&src_lbuf
;
544 printf(_("INODE: #regs: %d Not printing rest of data\n"),
549 skip_count
= f
->ilf_size
-1;
551 if (*i
>= num_ops
) /* end of LR */
554 /* core inode comes 2nd */
555 op_head
= (xlog_op_header_t
*)*ptr
;
556 xlog_print_op_header(op_head
, *i
, ptr
);
558 if (op_head
->oh_flags
& XLOG_CONTINUE_TRANS
) {
562 memmove(&dino
, *ptr
, sizeof(dino
));
563 mode
= dino
.di_mode
& S_IFMT
;
564 size
= (int)dino
.di_size
;
565 xlog_print_trans_inode_core(&dino
);
566 *ptr
+= xfs_log_dinode_size(dino
.di_version
);
569 switch (f
->ilf_fields
& (XFS_ILOG_DEV
| XFS_ILOG_UUID
)) {
571 printf(_("DEV inode: no extra region\n"));
574 printf(_("UUID inode: no extra region\n"));
578 /* Only the inode core is logged */
579 if (f
->ilf_size
== 2)
582 ASSERT(f
->ilf_size
<= 4);
583 ASSERT((f
->ilf_size
== 3) || (f
->ilf_fields
& XFS_ILOG_AFORK
));
585 /* does anything come next */
586 op_head
= (xlog_op_header_t
*)*ptr
;
588 if (f
->ilf_fields
& XFS_ILOG_DFORK
) {
592 xlog_print_op_header(op_head
, *i
, ptr
);
594 switch (f
->ilf_fields
& XFS_ILOG_DFORK
) {
596 printf(_("EXTENTS inode data\n"));
598 case XFS_ILOG_DBROOT
:
599 printf(_("BTREE inode data\n"));
602 printf(_("LOCAL inode data\n"));
604 xlog_print_dir2_sf(log
, (xfs_dir2_sf_hdr_t
*)*ptr
, size
);
607 ASSERT((f
->ilf_fields
& XFS_ILOG_DFORK
) == 0);
611 *ptr
+= be32_to_cpu(op_head
->oh_len
);
612 if (op_head
->oh_flags
& XLOG_CONTINUE_TRANS
)
614 op_head
= (xlog_op_header_t
*)*ptr
;
618 if (f
->ilf_fields
& XFS_ILOG_AFORK
) {
622 xlog_print_op_header(op_head
, *i
, ptr
);
624 switch (f
->ilf_fields
& XFS_ILOG_AFORK
) {
626 printf(_("EXTENTS attr data\n"));
628 case XFS_ILOG_ABROOT
:
629 printf(_("BTREE attr data\n"));
632 printf(_("LOCAL attr data\n"));
634 xlog_print_dir2_sf(log
, (xfs_dir2_sf_hdr_t
*)*ptr
, size
);
637 ASSERT((f
->ilf_fields
& XFS_ILOG_AFORK
) == 0);
640 *ptr
+= be32_to_cpu(op_head
->oh_len
);
641 if (op_head
->oh_flags
& XLOG_CONTINUE_TRANS
)
646 ASSERT(skip_count
== 0);
649 } /* xlog_print_trans_inode */
653 xlog_print_trans_dquot(char **ptr
, int len
, int *i
, int num_ops
)
655 xfs_dq_logformat_t
*f
;
656 xfs_dq_logformat_t lbuf
= {0};
657 xfs_disk_dquot_t ddq
;
658 xlog_op_header_t
*head
= NULL
;
662 * print dquot header region
664 * memmove to ensure 8-byte alignment for the long longs in
665 * xfs_dq_logformat_t structure
667 memmove(&lbuf
, *ptr
, min(sizeof(xfs_dq_logformat_t
), len
));
669 (*i
)++; /* bump index */
672 if (len
== sizeof(xfs_dq_logformat_t
)) {
673 printf(_("#regs: %d id: 0x%x"), f
->qlf_size
, f
->qlf_id
);
674 printf(_(" blkno: %lld len: %d boff: %d\n"),
675 (long long)f
->qlf_blkno
, f
->qlf_len
, f
->qlf_boffset
);
677 ASSERT(len
>= 4); /* must have at least 4 bytes if != 0 */
678 printf(_("DQUOT: #regs: %d Not printing rest of data\n"),
684 /* Check if all regions in this log item were in the given LR ptr */
685 if (*i
+num
> num_ops
-1) {
686 skip
= num
- (num_ops
-1-*i
);
693 head
= (xlog_op_header_t
*)*ptr
;
694 xlog_print_op_header(head
, *i
, ptr
);
695 ASSERT(be32_to_cpu(head
->oh_len
) == sizeof(xfs_disk_dquot_t
));
696 memmove(&ddq
, *ptr
, sizeof(xfs_disk_dquot_t
));
697 printf(_("DQUOT: magic 0x%hx flags 0%ho\n"),
698 be16_to_cpu(ddq
.d_magic
), ddq
.d_flags
);
699 *ptr
+= be32_to_cpu(head
->oh_len
);
701 if (head
&& head
->oh_flags
& XLOG_CONTINUE_TRANS
)
704 } /* xlog_print_trans_dquot */
708 xlog_print_trans_icreate(
714 struct xfs_icreate_log icl_buf
= {0};
715 struct xfs_icreate_log
*icl
;
717 memmove(&icl_buf
, *ptr
, min(sizeof(struct xfs_icreate_log
), len
));
721 /* handle complete header only */
722 if (len
!= sizeof(struct xfs_icreate_log
)) {
723 printf(_("ICR: split header, not printing\n"));
724 return 1; /* to skip leftover in next region */
727 printf(_("ICR: #ag: %d agbno: 0x%x len: %d\n"
728 " cnt: %d isize: %d gen: 0x%x\n"),
729 be32_to_cpu(icl
->icl_ag
), be32_to_cpu(icl
->icl_agbno
),
730 be32_to_cpu(icl
->icl_length
), be32_to_cpu(icl
->icl_count
),
731 be32_to_cpu(icl
->icl_isize
), be32_to_cpu(icl
->icl_gen
));
735 /******************************************************************************
739 ******************************************************************************
743 xlog_print_lseek(struct xlog
*log
, int fd
, xfs_daddr_t blkno
, int whence
)
745 #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT)
748 if (whence
== SEEK_SET
)
749 offset
= BBTOOFF64(blkno
+log
->l_logBBstart
);
751 offset
= BBTOOFF64(blkno
);
752 if (lseek(fd
, offset
, whence
) < 0) {
753 fprintf(stderr
, _("%s: lseek to %lld failed: %s\n"),
754 progname
, (long long)offset
, strerror(errno
));
757 } /* xlog_print_lseek */
761 print_lsn(char *string
,
764 printf("%s: %u,%u", string
,
765 CYCLE_LSN(be64_to_cpu(*lsn
)), BLOCK_LSN(be64_to_cpu(*lsn
)));
777 xlog_rec_header_t
*rhead
,
778 xlog_rec_ext_header_t
*xhdrs
,
782 int read_len
, skip
, lost_context
= 0;
793 /* read_len must read up to some block boundary */
794 read_len
= (int) BBTOB(BTOBB(len
));
796 /* read_type => don't malloc() new buffer, use old one */
797 if (*read_type
== FULL_READ
) {
798 if ((ptr
= buf
= malloc(read_len
)) == NULL
) {
799 fprintf(stderr
, _("%s: xlog_print_record: malloc failed\n"), progname
);
803 read_len
-= *read_type
;
804 buf
= (char *)((intptr_t)(*partial_buf
) + (intptr_t)(*read_type
));
807 if ((ret
= (int) read(fd
, buf
, read_len
)) == -1) {
808 fprintf(stderr
, _("%s: xlog_print_record: read error\n"), progname
);
811 /* Did we overflow the end? */
812 if (*read_type
== FULL_READ
&&
813 BLOCK_LSN(be64_to_cpu(rhead
->h_lsn
)) + BTOBB(read_len
) >=
815 *read_type
= BBTOB(logBBsize
- BLOCK_LSN(be64_to_cpu(rhead
->h_lsn
))-1);
820 /* Did we read everything? */
821 if ((ret
== 0 && read_len
!= 0) || ret
!= read_len
) {
826 if (*read_type
!= FULL_READ
)
827 read_len
+= *read_type
;
829 /* Everything read in. Start from beginning of buffer
830 * Unpack the data, by putting the saved cycle-data back
831 * into the first word of each BB.
835 for (i
= 0; ptr
< buf
+ read_len
; ptr
+= BBSIZE
, i
++) {
836 xlog_rec_header_t
*rechead
= (xlog_rec_header_t
*)ptr
;
839 if (be32_to_cpu(rechead
->h_magicno
) == XLOG_HEADER_MAGIC_NUM
) {
840 /* data should not have magicno as first word
841 * as it should by cycle#
847 * FIXME: cycle+1 should be a macro pv#900369
849 if (be32_to_cpu(rhead
->h_cycle
) !=
850 be32_to_cpu(*(__be32
*)ptr
)) {
851 if ((*read_type
== FULL_READ
) ||
852 (be32_to_cpu(rhead
->h_cycle
) + 1 !=
853 be32_to_cpu(*(__be32
*)ptr
))) {
860 /* copy back the data from the header */
861 if (i
< XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
) {
862 /* from 1st header */
863 *(__be32
*)ptr
= rhead
->h_cycle_data
[i
];
866 ASSERT(xhdrs
!= NULL
);
867 /* from extra headers */
868 j
= i
/ (XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
);
869 k
= i
% (XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
);
870 *(__be32
*)ptr
= xhdrs
[j
-1].xh_cycle_data
[k
];
876 for (i
=0; i
<num_ops
; i
++) {
879 xlog_op_header_t
*op_head
= (xlog_op_header_t
*)ptr
;
881 print_xlog_op_line();
882 xlog_print_op_header(op_head
, i
, &ptr
);
883 continued
= ((op_head
->oh_flags
& XLOG_WAS_CONT_TRANS
) ||
884 (op_head
->oh_flags
& XLOG_CONTINUE_TRANS
));
886 if (continued
&& be32_to_cpu(op_head
->oh_len
) == 0)
890 for (n
= 0; n
< be32_to_cpu(op_head
->oh_len
); n
++) {
891 printf("0x%02x ", (unsigned int)*ptr
);
900 /* print transaction data */
901 if (xlog_print_find_tid(be32_to_cpu(op_head
->oh_tid
),
902 op_head
->oh_flags
& XLOG_WAS_CONT_TRANS
)) {
903 printf(_("Left over region from split log item\n"));
904 /* Skip this leftover bit */
905 ptr
+= be32_to_cpu(op_head
->oh_len
);
906 /* We've lost context; don't complain if next one looks bad too */
911 if (be32_to_cpu(op_head
->oh_len
) != 0) {
912 if (*(uint
*)ptr
== XFS_TRANS_HEADER_MAGIC
) {
913 skip
= xlog_print_trans_header(&ptr
,
914 be32_to_cpu(op_head
->oh_len
));
916 switch (*(unsigned short *)ptr
) {
918 skip
= xlog_print_trans_buffer(&ptr
,
919 be32_to_cpu(op_head
->oh_len
),
923 case XFS_LI_ICREATE
: {
924 skip
= xlog_print_trans_icreate(&ptr
,
925 be32_to_cpu(op_head
->oh_len
),
930 skip
= xlog_print_trans_inode(log
, &ptr
,
931 be32_to_cpu(op_head
->oh_len
),
932 &i
, num_ops
, continued
);
936 skip
= xlog_print_trans_dquot(&ptr
,
937 be32_to_cpu(op_head
->oh_len
),
942 skip
= xlog_print_trans_efi(&ptr
,
943 be32_to_cpu(op_head
->oh_len
),
948 skip
= xlog_print_trans_efd(&ptr
,
949 be32_to_cpu(op_head
->oh_len
));
953 skip
= xlog_print_trans_rui(&ptr
,
954 be32_to_cpu(op_head
->oh_len
),
959 skip
= xlog_print_trans_rud(&ptr
,
960 be32_to_cpu(op_head
->oh_len
));
964 skip
= xlog_print_trans_cui(&ptr
,
965 be32_to_cpu(op_head
->oh_len
),
970 skip
= xlog_print_trans_cud(&ptr
,
971 be32_to_cpu(op_head
->oh_len
));
975 skip
= xlog_print_trans_bui(&ptr
,
976 be32_to_cpu(op_head
->oh_len
),
981 skip
= xlog_print_trans_bud(&ptr
,
982 be32_to_cpu(op_head
->oh_len
));
985 case XFS_LI_QUOTAOFF
: {
986 skip
= xlog_print_trans_qoff(&ptr
,
987 be32_to_cpu(op_head
->oh_len
));
990 case XLOG_UNMOUNT_TYPE
: {
991 printf(_("Unmount filesystem\n"));
996 if (bad_hdr_warn
&& !lost_context
) {
998 _("%s: unknown log operation type (%x)\n"),
999 progname
, *(unsigned short *)ptr
);
1006 _("Left over region from split log item\n"));
1009 ptr
+= be32_to_cpu(op_head
->oh_len
);
1015 xlog_print_add_to_trans(be32_to_cpu(op_head
->oh_tid
), skip
);
1021 } /* xlog_print_record */
1025 xlog_print_rec_head(xlog_rec_header_t
*head
, int *len
, int bad_hdr_warn
)
1032 return be32_to_cpu(head
->h_num_logops
);
1034 if (!head
->h_magicno
)
1037 if (be32_to_cpu(head
->h_magicno
) != XLOG_HEADER_MAGIC_NUM
) {
1039 printf(_("Header 0x%x wanted 0x%x\n"),
1040 be32_to_cpu(head
->h_magicno
),
1041 XLOG_HEADER_MAGIC_NUM
);
1045 /* check for cleared blocks written by xlog_clear_stale_blocks() */
1046 if (!head
->h_len
&& !head
->h_crc
&& !head
->h_prev_block
&&
1047 !head
->h_num_logops
&& !head
->h_size
)
1048 return CLEARED_BLKS
;
1050 datalen
=be32_to_cpu(head
->h_len
);
1053 printf(_("cycle: %d version: %d "),
1054 be32_to_cpu(head
->h_cycle
),
1055 be32_to_cpu(head
->h_version
));
1056 print_lsn(" lsn", &head
->h_lsn
);
1057 print_lsn(" tail_lsn", &head
->h_tail_lsn
);
1059 printf(_("length of Log Record: %d prev offset: %d num ops: %d\n"),
1061 be32_to_cpu(head
->h_prev_block
),
1062 be32_to_cpu(head
->h_num_logops
));
1064 if (print_overwrite
) {
1065 printf(_("cycle num overwrites: "));
1066 for (i
=0; i
< min(bbs
, XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
); i
++)
1067 printf("%d - 0x%x ",
1069 be32_to_cpu(head
->h_cycle_data
[i
]));
1073 platform_uuid_unparse(&head
->h_fs_uuid
, uub
);
1074 printf(_("uuid: %s format: "), uub
);
1075 switch (be32_to_cpu(head
->h_fmt
)) {
1076 case XLOG_FMT_UNKNOWN
:
1077 printf(_("unknown\n"));
1079 case XLOG_FMT_LINUX_LE
:
1080 printf(_("little endian linux\n"));
1082 case XLOG_FMT_LINUX_BE
:
1083 printf(_("big endian linux\n"));
1085 case XLOG_FMT_IRIX_BE
:
1086 printf(_("big endian irix\n"));
1089 printf("? (%d)\n", be32_to_cpu(head
->h_fmt
));
1092 printf(_("h_size: %d\n"), be32_to_cpu(head
->h_size
));
1094 *len
= be32_to_cpu(head
->h_len
);
1095 return(be32_to_cpu(head
->h_num_logops
));
1096 } /* xlog_print_rec_head */
1099 xlog_print_rec_xhead(xlog_rec_ext_header_t
*head
, int coverage
)
1103 print_xlog_xhdr_line();
1104 printf(_("extended-header: cycle: %d\n"), be32_to_cpu(head
->xh_cycle
));
1106 if (print_overwrite
) {
1107 printf(_("cycle num overwrites: "));
1108 for (i
= 0; i
< coverage
; i
++)
1109 printf("%d - 0x%x ",
1111 be32_to_cpu(head
->xh_cycle_data
[i
]));
1114 } /* xlog_print_rec_xhead */
1117 print_xlog_bad_zeroed(xfs_daddr_t blkno
)
1120 printf(_("* ERROR: found data after zeroed blocks block=%-21lld *\n"),
1124 xlog_exit("Bad log - data after zeroed blocks");
1125 } /* print_xlog_bad_zeroed */
1128 print_xlog_bad_header(xfs_daddr_t blkno
, char *buf
)
1131 printf(_("* ERROR: header cycle=%-11d block=%-21lld *\n"),
1132 xlog_get_cycle(buf
), (long long)blkno
);
1135 xlog_exit("Bad log record header");
1136 } /* print_xlog_bad_header */
1139 print_xlog_bad_data(xfs_daddr_t blkno
)
1142 printf(_("* ERROR: data block=%-21lld *\n"),
1146 xlog_exit("Bad data in log");
1147 } /* print_xlog_bad_data */
1150 print_xlog_bad_reqd_hdrs(xfs_daddr_t blkno
, int num_reqd
, int num_hdrs
)
1153 printf(_("* ERROR: for header block=%lld\n"
1154 "* not enough hdrs for data length, "
1155 "required num = %d, hdr num = %d\n"),
1156 (long long)blkno
, num_reqd
, num_hdrs
);
1159 xlog_exit(_("Not enough headers for data length."));
1160 } /* print_xlog_bad_reqd_hdrs */
1163 xlog_reallocate_xhdrs(int num_hdrs
, xlog_rec_ext_header_t
**ret_xhdrs
)
1165 int len
= (num_hdrs
-1) * sizeof(xlog_rec_ext_header_t
);
1167 *ret_xhdrs
= (xlog_rec_ext_header_t
*)realloc(*ret_xhdrs
, len
);
1168 if (*ret_xhdrs
== NULL
) {
1169 fprintf(stderr
, _("%s: xlog_print: malloc failed for ext hdrs\n"), progname
);
1174 /* for V2 logs read each extra hdr and print it out */
1176 xlog_print_extended_headers(
1180 xlog_rec_header_t
*hdr
,
1182 xlog_rec_ext_header_t
**ret_xhdrs
)
1188 char xhbuf
[XLOG_HEADER_SIZE
];
1189 xlog_rec_ext_header_t
*xhdr
;
1191 num_required
= howmany(len
, XLOG_HEADER_CYCLE_SIZE
);
1192 num_hdrs
= be32_to_cpu(hdr
->h_size
) / XLOG_HEADER_CYCLE_SIZE
;
1193 if (be32_to_cpu(hdr
->h_size
) % XLOG_HEADER_CYCLE_SIZE
)
1196 if (num_required
> num_hdrs
) {
1197 print_xlog_bad_reqd_hdrs((*blkno
)-1, num_required
, num_hdrs
);
1200 if (num_hdrs
== 1) {
1207 if (*ret_xhdrs
== NULL
|| num_hdrs
> *ret_num_hdrs
) {
1208 xlog_reallocate_xhdrs(num_hdrs
, ret_xhdrs
);
1211 *ret_num_hdrs
= num_hdrs
;
1213 /* don't include 1st header */
1214 for (i
= 1, xhdr
= *ret_xhdrs
; i
< num_hdrs
; i
++, (*blkno
)++, xhdr
++) {
1215 /* read one extra header blk */
1216 if (read(fd
, xhbuf
, 512) == 0) {
1217 printf(_("%s: physical end of log\n"), progname
);
1218 print_xlog_record_line();
1219 /* reached the end so return 1 */
1222 if (print_only_data
) {
1223 printf(_("BLKNO: %lld\n"), (long long)*blkno
);
1224 xlog_recover_print_data(xhbuf
, 512);
1227 if (i
== num_hdrs
- 1) {
1229 coverage_bb
= BTOBB(len
) %
1230 (XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
);
1233 /* earliear header */
1234 coverage_bb
= XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
;
1236 xlog_print_rec_xhead((xlog_rec_ext_header_t
*)xhbuf
, coverage_bb
);
1239 /* Copy from buffer into xhdrs array for later.
1240 * Could endian convert here but then code later on
1241 * will look asymmetric with the 1 hdr normal case
1242 * which does endian coversion on access.
1244 xhdr
->xh_cycle
= ((xlog_rec_ext_header_t
*)xhbuf
)->xh_cycle
;
1245 for (j
= 0; j
< XLOG_HEADER_CYCLE_SIZE
/ BBSIZE
; j
++) {
1246 xhdr
->xh_cycle_data
[j
] =
1247 ((xlog_rec_ext_header_t
*)xhbuf
)->xh_cycle_data
[j
];
1255 * This code is gross and needs to be rewritten.
1257 void xfs_log_print(struct xlog
*log
,
1259 int print_block_start
)
1261 char hbuf
[XLOG_HEADER_SIZE
];
1262 xlog_rec_header_t
*hdr
= (xlog_rec_header_t
*)&hbuf
[0];
1263 xlog_rec_ext_header_t
*xhdrs
= NULL
;
1264 int num_ops
, len
, num_hdrs
= 1;
1265 xfs_daddr_t block_end
= 0, block_start
, blkno
, error
;
1266 xfs_daddr_t zeroed_blkno
= 0, cleared_blkno
= 0;
1267 int read_type
= FULL_READ
;
1271 int first_hdr_found
= 0;
1273 logBBsize
= log
->l_logBBsize
;
1276 * Normally, block_start and block_end are the same value since we
1277 * are printing the entire log. However, if the start block is given,
1278 * we still end at the end of the logical log.
1280 if ((error
= xlog_print_find_oldest(log
, &block_end
))) {
1281 fprintf(stderr
, _("%s: problem finding oldest LR\n"), progname
);
1284 if (print_block_start
== -1)
1285 block_start
= block_end
;
1287 block_start
= print_block_start
;
1288 xlog_print_lseek(log
, fd
, block_start
, SEEK_SET
);
1289 blkno
= block_start
;
1292 if (read(fd
, hbuf
, 512) == 0) {
1293 printf(_("%s: physical end of log\n"), progname
);
1294 print_xlog_record_line();
1297 if (print_only_data
) {
1298 printf(_("BLKNO: %lld\n"), (long long)blkno
);
1299 xlog_recover_print_data(hbuf
, 512);
1303 num_ops
= xlog_print_rec_head(hdr
, &len
, first_hdr_found
);
1306 if (zeroed
&& num_ops
!= ZEROED_LOG
) {
1307 printf(_("%s: after %d zeroed blocks\n"), progname
, zeroed
);
1308 /* once we find zeroed blocks - that's all we expect */
1309 print_xlog_bad_zeroed(blkno
-1);
1310 /* reset count since we're assuming previous zeroed blocks
1316 if (num_ops
== ZEROED_LOG
||
1317 num_ops
== CLEARED_BLKS
||
1318 num_ops
== BAD_HEADER
) {
1319 if (num_ops
== ZEROED_LOG
) {
1321 zeroed_blkno
= blkno
-1;
1324 else if (num_ops
== CLEARED_BLKS
) {
1326 cleared_blkno
= blkno
-1;
1329 if (!first_hdr_found
)
1330 block_start
= blkno
;
1332 print_xlog_bad_header(blkno
-1, hbuf
);
1338 if (be32_to_cpu(hdr
->h_version
) == 2) {
1339 if (xlog_print_extended_headers(fd
, len
, &blkno
, hdr
, &num_hdrs
, &xhdrs
) != 0)
1343 error
= xlog_print_record(log
, fd
, num_ops
, len
, &read_type
, &partial_buf
,
1344 hdr
, xhdrs
, first_hdr_found
);
1348 blkno
+= BTOBB(len
);
1349 if (print_block_start
!= -1 &&
1350 blkno
>= block_end
) /* If start specified, we */
1351 goto end
; /* end early */
1355 print_xlog_bad_data(blkno
-1);
1356 if (print_block_start
!= -1 &&
1357 blkno
>= block_end
) /* If start specified, */
1358 goto end
; /* we end early */
1359 xlog_print_lseek(log
, fd
, blkno
, SEEK_SET
);
1362 case PARTIAL_READ
: {
1363 print_xlog_record_line();
1364 printf(_("%s: physical end of log\n"), progname
);
1365 print_xlog_record_line();
1367 xlog_print_lseek(log
, fd
, 0, SEEK_SET
);
1369 * We may have hit the end of the log when we started at 0.
1370 * In this case, just end.
1372 if (block_start
== 0)
1374 goto partial_log_read
;
1376 default: xlog_panic(_("illegal value"));
1378 print_xlog_record_line();
1380 if (blkno
>= logBBsize
) {
1382 printf(_("%s: skipped %d cleared blocks in range: %lld - %lld\n"),
1384 (long long)(cleared_blkno
),
1385 (long long)(cleared
+ cleared_blkno
- 1));
1386 if (cleared
== logBBsize
)
1387 printf(_("%s: totally cleared log\n"), progname
);
1392 printf(_("%s: skipped %d zeroed blocks in range: %lld - %lld\n"),
1394 (long long)(zeroed_blkno
),
1395 (long long)(zeroed
+ zeroed_blkno
- 1));
1396 if (zeroed
== logBBsize
)
1397 printf(_("%s: totally zeroed log\n"), progname
);
1401 printf(_("%s: physical end of log\n"), progname
);
1402 print_xlog_record_line();
1407 /* Do we need to print the first part of physical log? */
1408 if (block_start
!= 0) {
1410 xlog_print_lseek(log
, fd
, 0, SEEK_SET
);
1412 if (read(fd
, hbuf
, 512) == 0) {
1413 xlog_panic(_("xlog_find_head: bad read"));
1415 if (print_only_data
) {
1416 printf(_("BLKNO: %lld\n"), (long long)blkno
);
1417 xlog_recover_print_data(hbuf
, 512);
1421 num_ops
= xlog_print_rec_head(hdr
, &len
, first_hdr_found
);
1424 if (num_ops
== ZEROED_LOG
||
1425 num_ops
== CLEARED_BLKS
||
1426 num_ops
== BAD_HEADER
) {
1427 /* we only expect zeroed log entries or cleared log
1428 * entries at the end of the _physical_ log,
1429 * so treat them the same as bad blocks here
1431 print_xlog_bad_header(blkno
-1, hbuf
);
1433 if (blkno
>= block_end
)
1438 if (be32_to_cpu(hdr
->h_version
) == 2) {
1439 if (xlog_print_extended_headers(fd
, len
, &blkno
, hdr
, &num_hdrs
, &xhdrs
) != 0)
1444 error
= xlog_print_record(log
, fd
, num_ops
, len
, &read_type
,
1445 &partial_buf
, (xlog_rec_header_t
*)hbuf
,
1446 xhdrs
, first_hdr_found
);
1447 if (read_type
!= FULL_READ
)
1449 read_type
= FULL_READ
;
1451 blkno
+= BTOBB(len
);
1453 print_xlog_bad_data(blkno
-1);
1454 xlog_print_lseek(log
, fd
, blkno
, SEEK_SET
);
1457 print_xlog_record_line();
1459 if (blkno
>= block_end
)
1465 printf(_("%s: logical end of log\n"), progname
);
1466 print_xlog_record_line();
1470 * if necessary, convert an xfs_inode_log_format struct from the old 32bit version
1471 * (which can have different field alignments) to the native 64 bit version
1473 struct xfs_inode_log_format
*
1474 xfs_inode_item_format_convert(char *src_buf
, uint len
, struct xfs_inode_log_format
*in_f
)
1476 struct xfs_inode_log_format_32
*in_f32
;
1478 /* if we have native format then just return buf without copying data */
1479 if (len
== sizeof(struct xfs_inode_log_format
)) {
1480 return (struct xfs_inode_log_format
*)src_buf
;
1483 in_f32
= (struct xfs_inode_log_format_32
*)src_buf
;
1484 in_f
->ilf_type
= in_f32
->ilf_type
;
1485 in_f
->ilf_size
= in_f32
->ilf_size
;
1486 in_f
->ilf_fields
= in_f32
->ilf_fields
;
1487 in_f
->ilf_asize
= in_f32
->ilf_asize
;
1488 in_f
->ilf_dsize
= in_f32
->ilf_dsize
;
1489 in_f
->ilf_ino
= in_f32
->ilf_ino
;
1490 /* copy biggest field of ilf_u */
1491 memcpy(&in_f
->ilf_u
.__pad
, &in_f32
->ilf_u
.__pad
,
1492 sizeof(in_f
->ilf_u
.__pad
));
1493 in_f
->ilf_blkno
= in_f32
->ilf_blkno
;
1494 in_f
->ilf_len
= in_f32
->ilf_len
;
1495 in_f
->ilf_boffset
= in_f32
->ilf_boffset
;