2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
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.
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.
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
24 * Start is defined to be the block pointing to the oldest valid log record.
27 xlog_print_find_oldest(
29 xfs_daddr_t
*last_blk
)
32 xfs_daddr_t first_blk
;
33 uint first_half_cycle
, last_half_cycle
;
36 if (xlog_find_zeroed(log
, &first_blk
))
39 first_blk
= 0; /* read first block */
40 bp
= xlog_get_bp(log
, 1);
41 xlog_bread_noalign(log
, 0, 1, bp
);
42 first_half_cycle
= xlog_get_cycle(XFS_BUF_PTR(bp
));
43 *last_blk
= log
->l_logBBsize
-1; /* read last block */
44 xlog_bread_noalign(log
, *last_blk
, 1, bp
);
45 last_half_cycle
= xlog_get_cycle(XFS_BUF_PTR(bp
));
46 ASSERT(last_half_cycle
!= 0);
48 if (first_half_cycle
== last_half_cycle
) /* all cycle nos are same */
50 else /* have 1st and last; look for middle cycle */
51 error
= xlog_find_cycle_start(log
, bp
, first_blk
,
52 last_blk
, last_half_cycle
);
59 xlog_recover_print_data(
82 xlog_recover_print_buffer(
83 xlog_recover_item_t
*item
)
87 xfs_buf_log_format_t
*f
;
91 xfs_disk_dquot_t
*ddq
;
93 f
= (xfs_buf_log_format_t
*)item
->ri_buf
[0].i_addr
;
95 ASSERT(f
->blf_type
== XFS_LI_BUF
);
96 printf(_("BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n"),
97 f
->blf_size
, (long long)f
->blf_blkno
, f
->blf_len
, f
->blf_map_size
, f
->blf_flags
);
98 blkno
= (xfs_daddr_t
)f
->blf_blkno
;
102 p
= item
->ri_buf
[i
].i_addr
;
103 len
= item
->ri_buf
[i
].i_len
;
105 if (blkno
== 0) { /* super block */
106 printf(_(" SUPER Block Buffer:\n"));
109 printf(_(" icount:%llu ifree:%llu "),
111 be64_to_cpu(*(__be64
*)(p
)),
113 be64_to_cpu(*(__be64
*)(p
+8)));
114 printf(_("fdblks:%llu frext:%llu\n"),
116 be64_to_cpu(*(__be64
*)(p
+16)),
118 be64_to_cpu(*(__be64
*)(p
+24)));
119 printf(_(" sunit:%u swidth:%u\n"),
120 be32_to_cpu(*(__be32
*)(p
+56)),
121 be32_to_cpu(*(__be32
*)(p
+60)));
122 } else if (be32_to_cpu(*(__be32
*)p
) == XFS_AGI_MAGIC
) {
124 agi
= (xfs_agi_t
*)p
;
125 printf(_(" AGI Buffer: (XAGI)\n"));
128 printf(_(" ver:%d "),
129 be32_to_cpu(agi
->agi_versionnum
));
130 printf(_("seq#:%d len:%d cnt:%d root:%d\n"),
131 be32_to_cpu(agi
->agi_seqno
),
132 be32_to_cpu(agi
->agi_length
),
133 be32_to_cpu(agi
->agi_count
),
134 be32_to_cpu(agi
->agi_root
));
135 printf(_(" level:%d free#:0x%x newino:0x%x\n"),
136 be32_to_cpu(agi
->agi_level
),
137 be32_to_cpu(agi
->agi_freecount
),
138 be32_to_cpu(agi
->agi_newino
));
141 } else if (len
== 256) {
144 buckets
= XFS_AGI_UNLINKED_BUCKETS
;
146 for (bucket
= 0; bucket
< buckets
;) {
148 printf(_("bucket[%d - %d]: "), bucket
, bucket
+3);
149 for (col
= 0; col
< 4; col
++, bucket
++) {
150 if (bucket
< buckets
) {
152 be32_to_cpu(agi
->agi_unlinked
[bucket
]));
157 } else if (be32_to_cpu(*(__be32
*)p
) == XFS_AGF_MAGIC
) {
158 agf
= (xfs_agf_t
*)p
;
159 printf(_(" AGF Buffer: (XAGF)\n"));
162 printf(_(" ver:%d seq#:%d len:%d \n"),
163 be32_to_cpu(agf
->agf_versionnum
),
164 be32_to_cpu(agf
->agf_seqno
),
165 be32_to_cpu(agf
->agf_length
));
166 printf(_(" root BNO:%d CNT:%d\n"),
167 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNOi
]),
168 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNTi
]));
169 printf(_(" level BNO:%d CNT:%d\n"),
170 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNOi
]),
171 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNTi
]));
172 printf(_(" 1st:%d last:%d cnt:%d "
173 "freeblks:%d longest:%d\n"),
174 be32_to_cpu(agf
->agf_flfirst
),
175 be32_to_cpu(agf
->agf_fllast
),
176 be32_to_cpu(agf
->agf_flcount
),
177 be32_to_cpu(agf
->agf_freeblks
),
178 be32_to_cpu(agf
->agf_longest
));
179 } else if (*(uint
*)p
== XFS_DQUOT_MAGIC
) {
180 ddq
= (xfs_disk_dquot_t
*)p
;
181 printf(_(" DQUOT Buffer:\n"));
184 printf(_(" UIDs 0x%lx-0x%lx\n"),
185 (unsigned long)be32_to_cpu(ddq
->d_id
),
186 (unsigned long)be32_to_cpu(ddq
->d_id
) +
187 (BBTOB(f
->blf_len
) / sizeof(xfs_dqblk_t
)) - 1);
189 printf(_(" BUF DATA\n"));
190 if (!print_buffer
) continue;
191 xlog_recover_print_data(p
, len
);
197 xlog_recover_print_quotaoff(
198 xlog_recover_item_t
*item
)
200 xfs_qoff_logformat_t
*qoff_f
;
201 char str
[32] = { 0 };
203 qoff_f
= (xfs_qoff_logformat_t
*)item
->ri_buf
[0].i_addr
;
205 if (qoff_f
->qf_flags
& XFS_UQUOTA_ACCT
)
206 strcat(str
, "USER QUOTA");
207 if (qoff_f
->qf_flags
& XFS_GQUOTA_ACCT
)
208 strcat(str
, "GROUP QUOTA");
209 if (qoff_f
->qf_flags
& XFS_PQUOTA_ACCT
)
210 strcat(str
, "PROJECT QUOTA");
211 printf(_("\tQUOTAOFF: #regs:%d type:%s\n"),
212 qoff_f
->qf_size
, str
);
216 xlog_recover_print_dquot(
217 xlog_recover_item_t
*item
)
219 xfs_dq_logformat_t
*f
;
222 f
= (xfs_dq_logformat_t
*)item
->ri_buf
[0].i_addr
;
224 ASSERT(f
->qlf_len
== 1);
225 d
= (xfs_disk_dquot_t
*)item
->ri_buf
[1].i_addr
;
226 printf(_("\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n"),
227 f
->qlf_size
, (long long)f
->qlf_blkno
, f
->qlf_boffset
, f
->qlf_id
);
230 printf(_("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n"),
231 be16_to_cpu(d
->d_magic
),
233 be32_to_cpu(d
->d_id
),
234 be32_to_cpu(d
->d_id
));
235 printf(_("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x"
236 "\tino_soft 0x%x\n"),
237 (int)be64_to_cpu(d
->d_blk_hardlimit
),
238 (int)be64_to_cpu(d
->d_blk_softlimit
),
239 (int)be64_to_cpu(d
->d_ino_hardlimit
),
240 (int)be64_to_cpu(d
->d_ino_softlimit
));
241 printf(_("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n"),
242 (int)be64_to_cpu(d
->d_bcount
),
243 (int)be64_to_cpu(d
->d_bcount
),
244 (int)be64_to_cpu(d
->d_icount
),
245 (int)be64_to_cpu(d
->d_icount
));
246 printf(_("\t\tbtimer 0x%x itimer 0x%x \n"),
247 (int)be32_to_cpu(d
->d_btimer
),
248 (int)be32_to_cpu(d
->d_itimer
));
252 xlog_recover_print_inode_core(
253 struct xfs_log_dinode
*di
)
255 printf(_(" CORE inode:\n"));
258 printf(_(" magic:%c%c mode:0x%x ver:%d format:%d "
260 (di
->di_magic
>>8) & 0xff, di
->di_magic
& 0xff,
261 di
->di_mode
, di
->di_version
, di
->di_format
, di
->di_onlink
);
262 printf(_(" uid:%d gid:%d nlink:%d projid:0x%04x%04x\n"),
263 di
->di_uid
, di
->di_gid
, di
->di_nlink
,
264 di
->di_projid_hi
, di
->di_projid_lo
);
265 printf(_(" atime:%d mtime:%d ctime:%d\n"),
266 di
->di_atime
.t_sec
, di
->di_mtime
.t_sec
, di
->di_ctime
.t_sec
);
267 printf(_(" flushiter:%d\n"), di
->di_flushiter
);
268 printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
269 "nextents:%d anextents:%d\n"), (unsigned long long)
270 di
->di_size
, (unsigned long long)di
->di_nblocks
,
271 di
->di_extsize
, di
->di_nextents
, (int)di
->di_anextents
);
272 printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
274 (int)di
->di_forkoff
, di
->di_dmevmask
, (int)di
->di_dmstate
,
275 (int)di
->di_flags
, di
->di_gen
);
279 xlog_recover_print_inode(
280 xlog_recover_item_t
*item
)
282 xfs_inode_log_format_t f_buf
;
283 xfs_inode_log_format_t
*f
;
288 ASSERT(item
->ri_buf
[0].i_len
== sizeof(xfs_inode_log_format_32_t
) ||
289 item
->ri_buf
[0].i_len
== sizeof(xfs_inode_log_format_64_t
));
290 f
= xfs_inode_item_format_convert(item
->ri_buf
[0].i_addr
, item
->ri_buf
[0].i_len
, &f_buf
);
292 printf(_(" INODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n"),
293 f
->ilf_size
, (unsigned long long)f
->ilf_ino
, f
->ilf_fields
,
296 /* core inode comes 2nd */
297 ASSERT(item
->ri_buf
[1].i_len
== xfs_log_dinode_size(2) ||
298 item
->ri_buf
[1].i_len
== xfs_log_dinode_size(3));
299 xlog_recover_print_inode_core((struct xfs_log_dinode
*)
300 item
->ri_buf
[1].i_addr
);
302 hasdata
= (f
->ilf_fields
& XFS_ILOG_DFORK
) != 0;
303 hasattr
= (f
->ilf_fields
& XFS_ILOG_AFORK
) != 0;
304 /* does anything come next */
305 switch (f
->ilf_fields
& (XFS_ILOG_DFORK
|XFS_ILOG_DEV
|XFS_ILOG_UUID
)) {
307 ASSERT(f
->ilf_size
== 3 + hasattr
);
308 printf(_(" DATA FORK EXTENTS inode data:\n"));
309 if (print_inode
&& print_data
)
310 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
311 item
->ri_buf
[2].i_len
);
313 case XFS_ILOG_DBROOT
:
314 ASSERT(f
->ilf_size
== 3 + hasattr
);
315 printf(_(" DATA FORK BTREE inode data:\n"));
316 if (print_inode
&& print_data
)
317 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
318 item
->ri_buf
[2].i_len
);
321 ASSERT(f
->ilf_size
== 3 + hasattr
);
322 printf(_(" DATA FORK LOCAL inode data:\n"));
323 if (print_inode
&& print_data
)
324 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
325 item
->ri_buf
[2].i_len
);
328 ASSERT(f
->ilf_size
== 2 + hasattr
);
329 printf(_(" DEV inode: no extra region\n"));
332 ASSERT(f
->ilf_size
== 2 + hasattr
);
333 printf(_(" UUID inode: no extra region\n"));
337 ASSERT(f
->ilf_size
== 2 + hasattr
);
340 xlog_panic("xlog_print_trans_inode: illegal inode type");
344 attr_index
= 2 + hasdata
;
345 switch (f
->ilf_fields
& XFS_ILOG_AFORK
) {
347 ASSERT(f
->ilf_size
== 3 + hasdata
);
348 printf(_(" ATTR FORK EXTENTS inode data:\n"));
349 if (print_inode
&& print_data
)
350 xlog_recover_print_data(
351 item
->ri_buf
[attr_index
].i_addr
,
352 item
->ri_buf
[attr_index
].i_len
);
354 case XFS_ILOG_ABROOT
:
355 ASSERT(f
->ilf_size
== 3 + hasdata
);
356 printf(_(" ATTR FORK BTREE inode data:\n"));
357 if (print_inode
&& print_data
)
358 xlog_recover_print_data(
359 item
->ri_buf
[attr_index
].i_addr
,
360 item
->ri_buf
[attr_index
].i_len
);
363 ASSERT(f
->ilf_size
== 3 + hasdata
);
364 printf(_(" ATTR FORK LOCAL inode data:\n"));
365 if (print_inode
&& print_data
)
366 xlog_recover_print_data(
367 item
->ri_buf
[attr_index
].i_addr
,
368 item
->ri_buf
[attr_index
].i_len
);
371 xlog_panic("%s: illegal inode log flag", __FUNCTION__
);
377 xlog_recover_print_efd(
378 xlog_recover_item_t
*item
)
380 xfs_efd_log_format_t
*f
;
382 f
= (xfs_efd_log_format_t
*)item
->ri_buf
[0].i_addr
;
384 * An xfs_efd_log_format structure contains a variable length array
386 * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
387 * However, the extents are never used and won't be printed.
389 printf(_(" EFD: #regs: %d num_extents: %d id: 0x%llx\n"),
390 f
->efd_size
, f
->efd_nextents
, (unsigned long long)f
->efd_efi_id
);
395 xlog_recover_print_efi(
396 xlog_recover_item_t
*item
)
398 xfs_efi_log_format_t
*f
, *src_f
;
401 uint src_len
, dst_len
;
403 src_f
= (xfs_efi_log_format_t
*)item
->ri_buf
[0].i_addr
;
404 src_len
= item
->ri_buf
[0].i_len
;
406 * An xfs_efi_log_format structure contains a variable length array
408 * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
409 * Need to convert to native format.
411 dst_len
= sizeof(xfs_efi_log_format_t
) + (src_f
->efi_nextents
- 1) * sizeof(xfs_extent_t
);
412 if ((f
= (xfs_efi_log_format_t
*)malloc(dst_len
)) == NULL
) {
413 fprintf(stderr
, _("%s: xlog_recover_print_efi: malloc failed\n"), progname
);
416 if (xfs_efi_copy_format((char*)src_f
, src_len
, f
, 0)) {
421 printf(_(" EFI: #regs:%d num_extents:%d id:0x%llx\n"),
422 f
->efi_size
, f
->efi_nextents
, (unsigned long long)f
->efi_id
);
425 for (i
=0; i
< f
->efi_nextents
; i
++) {
426 printf("(s: 0x%llx, l: %d) ",
427 (unsigned long long)ex
->ext_start
, ex
->ext_len
);
438 xlog_recover_print_icreate(
439 struct xlog_recover_item
*item
)
441 struct xfs_icreate_log
*icl
;
443 icl
= (struct xfs_icreate_log
*)item
->ri_buf
[0].i_addr
;
445 printf(_(" ICR: #ag: %d agbno: 0x%x len: %d\n"
446 " cnt: %d isize: %d gen: 0x%x\n"),
447 be32_to_cpu(icl
->icl_ag
), be32_to_cpu(icl
->icl_agbno
),
448 be32_to_cpu(icl
->icl_length
), be32_to_cpu(icl
->icl_count
),
449 be32_to_cpu(icl
->icl_isize
), be32_to_cpu(icl
->icl_gen
));
453 xlog_recover_print_logitem(
454 xlog_recover_item_t
*item
)
456 switch (ITEM_TYPE(item
)) {
458 xlog_recover_print_buffer(item
);
461 xlog_recover_print_icreate(item
);
464 xlog_recover_print_inode(item
);
467 xlog_recover_print_efd(item
);
470 xlog_recover_print_efi(item
);
473 xlog_recover_print_dquot(item
);
475 case XFS_LI_QUOTAOFF
:
476 xlog_recover_print_quotaoff(item
);
479 printf(_("xlog_recover_print_logitem: illegal type\n"));
485 xlog_recover_print_item(
486 xlog_recover_item_t
*item
)
490 switch (ITEM_TYPE(item
)) {
509 case XFS_LI_QUOTAOFF
:
513 cmn_err(CE_PANIC
, _("%s: illegal type"), __FUNCTION__
);
517 /* type isn't filled in yet
518 printf(_("ITEM: type: %d cnt: %d total: %d "),
519 item->ri_type, item->ri_cnt, item->ri_total);
521 printf(_(": cnt:%d total:%d "), item
->ri_cnt
, item
->ri_total
);
522 for (i
=0; i
<item
->ri_cnt
; i
++) {
523 printf(_("a:0x%lx len:%d "),
524 (long)item
->ri_buf
[i
].i_addr
, item
->ri_buf
[i
].i_len
);
527 xlog_recover_print_logitem(item
);
531 xlog_recover_print_trans(
532 xlog_recover_t
*trans
,
533 struct list_head
*itemq
,
536 xlog_recover_item_t
*item
;
541 print_xlog_record_line();
542 xlog_recover_print_trans_head(trans
);
543 list_for_each_entry(item
, itemq
, ri_list
)
544 xlog_recover_print_item(item
);