1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
12 * Start is defined to be the block pointing to the oldest valid log record.
15 xlog_print_find_oldest(
17 xfs_daddr_t
*last_blk
)
20 xfs_daddr_t first_blk
;
21 uint first_half_cycle
, last_half_cycle
;
24 if (xlog_find_zeroed(log
, &first_blk
))
27 first_blk
= 0; /* read first block */
28 bp
= xlog_get_bp(log
, 1);
29 xlog_bread_noalign(log
, 0, 1, bp
);
30 first_half_cycle
= xlog_get_cycle(bp
->b_addr
);
31 *last_blk
= log
->l_logBBsize
-1; /* read last block */
32 xlog_bread_noalign(log
, *last_blk
, 1, bp
);
33 last_half_cycle
= xlog_get_cycle(bp
->b_addr
);
34 ASSERT(last_half_cycle
!= 0);
36 if (first_half_cycle
== last_half_cycle
) /* all cycle nos are same */
38 else /* have 1st and last; look for middle cycle */
39 error
= xlog_find_cycle_start(log
, bp
, first_blk
,
40 last_blk
, last_half_cycle
);
47 xlog_recover_print_data(
70 xlog_recover_print_buffer(
71 xlog_recover_item_t
*item
)
75 xfs_buf_log_format_t
*f
;
79 xfs_disk_dquot_t
*ddq
;
81 f
= (xfs_buf_log_format_t
*)item
->ri_buf
[0].i_addr
;
83 ASSERT(f
->blf_type
== XFS_LI_BUF
);
84 printf(_("BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n"),
85 f
->blf_size
, (long long)f
->blf_blkno
, f
->blf_len
, f
->blf_map_size
, f
->blf_flags
);
86 blkno
= (xfs_daddr_t
)f
->blf_blkno
;
90 p
= item
->ri_buf
[i
].i_addr
;
91 len
= item
->ri_buf
[i
].i_len
;
93 if (blkno
== 0) { /* super block */
94 printf(_(" SUPER Block Buffer:\n"));
97 printf(_(" icount:%llu ifree:%llu "),
99 be64_to_cpu(*(__be64
*)(p
)),
101 be64_to_cpu(*(__be64
*)(p
+8)));
102 printf(_("fdblks:%llu frext:%llu\n"),
104 be64_to_cpu(*(__be64
*)(p
+16)),
106 be64_to_cpu(*(__be64
*)(p
+24)));
107 printf(_(" sunit:%u swidth:%u\n"),
108 be32_to_cpu(*(__be32
*)(p
+56)),
109 be32_to_cpu(*(__be32
*)(p
+60)));
110 } else if (be32_to_cpu(*(__be32
*)p
) == XFS_AGI_MAGIC
) {
112 agi
= (xfs_agi_t
*)p
;
113 printf(_(" AGI Buffer: (XAGI)\n"));
116 printf(_(" ver:%d "),
117 be32_to_cpu(agi
->agi_versionnum
));
118 printf(_("seq#:%d len:%d cnt:%d root:%d\n"),
119 be32_to_cpu(agi
->agi_seqno
),
120 be32_to_cpu(agi
->agi_length
),
121 be32_to_cpu(agi
->agi_count
),
122 be32_to_cpu(agi
->agi_root
));
123 printf(_(" level:%d free#:0x%x newino:0x%x\n"),
124 be32_to_cpu(agi
->agi_level
),
125 be32_to_cpu(agi
->agi_freecount
),
126 be32_to_cpu(agi
->agi_newino
));
129 } else if (len
== 256) {
132 buckets
= XFS_AGI_UNLINKED_BUCKETS
;
134 for (bucket
= 0; bucket
< buckets
;) {
136 printf(_("bucket[%d - %d]: "), bucket
, bucket
+3);
137 for (col
= 0; col
< 4; col
++, bucket
++) {
138 if (bucket
< buckets
) {
140 be32_to_cpu(agi
->agi_unlinked
[bucket
]));
145 } else if (be32_to_cpu(*(__be32
*)p
) == XFS_AGF_MAGIC
) {
146 agf
= (xfs_agf_t
*)p
;
147 printf(_(" AGF Buffer: (XAGF)\n"));
150 printf(_(" ver:%d seq#:%d len:%d \n"),
151 be32_to_cpu(agf
->agf_versionnum
),
152 be32_to_cpu(agf
->agf_seqno
),
153 be32_to_cpu(agf
->agf_length
));
154 printf(_(" root BNO:%d CNT:%d\n"),
155 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNOi
]),
156 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNTi
]));
157 printf(_(" level BNO:%d CNT:%d\n"),
158 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNOi
]),
159 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNTi
]));
160 printf(_(" 1st:%d last:%d cnt:%d "
161 "freeblks:%d longest:%d\n"),
162 be32_to_cpu(agf
->agf_flfirst
),
163 be32_to_cpu(agf
->agf_fllast
),
164 be32_to_cpu(agf
->agf_flcount
),
165 be32_to_cpu(agf
->agf_freeblks
),
166 be32_to_cpu(agf
->agf_longest
));
167 } else if (*(uint
*)p
== XFS_DQUOT_MAGIC
) {
168 ddq
= (xfs_disk_dquot_t
*)p
;
169 printf(_(" DQUOT Buffer:\n"));
172 printf(_(" UIDs 0x%lx-0x%lx\n"),
173 (unsigned long)be32_to_cpu(ddq
->d_id
),
174 (unsigned long)be32_to_cpu(ddq
->d_id
) +
175 (BBTOB(f
->blf_len
) / sizeof(xfs_dqblk_t
)) - 1);
177 printf(_(" BUF DATA\n"));
178 if (!print_buffer
) continue;
179 xlog_recover_print_data(p
, len
);
185 xlog_recover_print_quotaoff(
186 xlog_recover_item_t
*item
)
188 xfs_qoff_logformat_t
*qoff_f
;
189 char str
[32] = { 0 };
191 qoff_f
= (xfs_qoff_logformat_t
*)item
->ri_buf
[0].i_addr
;
193 if (qoff_f
->qf_flags
& XFS_UQUOTA_ACCT
)
194 strcat(str
, "USER QUOTA");
195 if (qoff_f
->qf_flags
& XFS_GQUOTA_ACCT
)
196 strcat(str
, "GROUP QUOTA");
197 if (qoff_f
->qf_flags
& XFS_PQUOTA_ACCT
)
198 strcat(str
, "PROJECT QUOTA");
199 printf(_("\tQUOTAOFF: #regs:%d type:%s\n"),
200 qoff_f
->qf_size
, str
);
204 xlog_recover_print_dquot(
205 xlog_recover_item_t
*item
)
207 xfs_dq_logformat_t
*f
;
210 f
= (xfs_dq_logformat_t
*)item
->ri_buf
[0].i_addr
;
212 ASSERT(f
->qlf_len
== 1);
213 d
= (xfs_disk_dquot_t
*)item
->ri_buf
[1].i_addr
;
214 printf(_("\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n"),
215 f
->qlf_size
, (long long)f
->qlf_blkno
, f
->qlf_boffset
, f
->qlf_id
);
218 printf(_("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n"),
219 be16_to_cpu(d
->d_magic
),
221 be32_to_cpu(d
->d_id
),
222 be32_to_cpu(d
->d_id
));
223 printf(_("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x"
224 "\tino_soft 0x%x\n"),
225 (int)be64_to_cpu(d
->d_blk_hardlimit
),
226 (int)be64_to_cpu(d
->d_blk_softlimit
),
227 (int)be64_to_cpu(d
->d_ino_hardlimit
),
228 (int)be64_to_cpu(d
->d_ino_softlimit
));
229 printf(_("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n"),
230 (int)be64_to_cpu(d
->d_bcount
),
231 (int)be64_to_cpu(d
->d_bcount
),
232 (int)be64_to_cpu(d
->d_icount
),
233 (int)be64_to_cpu(d
->d_icount
));
234 printf(_("\t\tbtimer 0x%x itimer 0x%x \n"),
235 (int)be32_to_cpu(d
->d_btimer
),
236 (int)be32_to_cpu(d
->d_itimer
));
240 xlog_recover_print_inode_core(
241 struct xfs_log_dinode
*di
)
243 printf(_(" CORE inode:\n"));
246 printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"),
247 (di
->di_magic
>>8) & 0xff, di
->di_magic
& 0xff,
248 di
->di_mode
, di
->di_version
, di
->di_format
);
249 printf(_(" uid:%d gid:%d nlink:%d projid:0x%04x%04x\n"),
250 di
->di_uid
, di
->di_gid
, di
->di_nlink
,
251 di
->di_projid_hi
, di
->di_projid_lo
);
252 printf(_(" atime:%d mtime:%d ctime:%d\n"),
253 di
->di_atime
.t_sec
, di
->di_mtime
.t_sec
, di
->di_ctime
.t_sec
);
254 printf(_(" flushiter:%d\n"), di
->di_flushiter
);
255 printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
256 "nextents:%d anextents:%d\n"), (unsigned long long)
257 di
->di_size
, (unsigned long long)di
->di_nblocks
,
258 di
->di_extsize
, di
->di_nextents
, (int)di
->di_anextents
);
259 printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
261 (int)di
->di_forkoff
, di
->di_dmevmask
, (int)di
->di_dmstate
,
262 (int)di
->di_flags
, di
->di_gen
);
263 if (di
->di_version
== 3) {
264 printf(_(" flags2 0x%llx cowextsize 0x%x\n"),
265 (unsigned long long)di
->di_flags2
, di
->di_cowextsize
);
270 xlog_recover_print_inode(
271 xlog_recover_item_t
*item
)
273 struct xfs_inode_log_format f_buf
;
274 struct xfs_inode_log_format
*f
;
279 ASSERT(item
->ri_buf
[0].i_len
== sizeof(struct xfs_inode_log_format_32
) ||
280 item
->ri_buf
[0].i_len
== sizeof(struct xfs_inode_log_format
));
281 f
= xfs_inode_item_format_convert(item
->ri_buf
[0].i_addr
, item
->ri_buf
[0].i_len
, &f_buf
);
283 printf(_(" INODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n"),
284 f
->ilf_size
, (unsigned long long)f
->ilf_ino
, f
->ilf_fields
,
287 /* core inode comes 2nd */
288 ASSERT(item
->ri_buf
[1].i_len
== xfs_log_dinode_size(2) ||
289 item
->ri_buf
[1].i_len
== xfs_log_dinode_size(3));
290 xlog_recover_print_inode_core((struct xfs_log_dinode
*)
291 item
->ri_buf
[1].i_addr
);
293 hasdata
= (f
->ilf_fields
& XFS_ILOG_DFORK
) != 0;
294 hasattr
= (f
->ilf_fields
& XFS_ILOG_AFORK
) != 0;
295 /* does anything come next */
296 switch (f
->ilf_fields
& (XFS_ILOG_DFORK
|XFS_ILOG_DEV
|XFS_ILOG_UUID
)) {
298 ASSERT(f
->ilf_size
== 3 + hasattr
);
299 printf(_(" DATA FORK EXTENTS inode data:\n"));
300 if (print_inode
&& print_data
)
301 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
302 item
->ri_buf
[2].i_len
);
304 case XFS_ILOG_DBROOT
:
305 ASSERT(f
->ilf_size
== 3 + hasattr
);
306 printf(_(" DATA FORK BTREE inode data:\n"));
307 if (print_inode
&& print_data
)
308 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
309 item
->ri_buf
[2].i_len
);
312 ASSERT(f
->ilf_size
== 3 + hasattr
);
313 printf(_(" DATA FORK LOCAL inode data:\n"));
314 if (print_inode
&& print_data
)
315 xlog_recover_print_data(item
->ri_buf
[2].i_addr
,
316 item
->ri_buf
[2].i_len
);
319 ASSERT(f
->ilf_size
== 2 + hasattr
);
320 printf(_(" DEV inode: no extra region\n"));
323 ASSERT(f
->ilf_size
== 2 + hasattr
);
324 printf(_(" UUID inode: no extra region\n"));
328 ASSERT(f
->ilf_size
== 2 + hasattr
);
331 xlog_panic("xlog_print_trans_inode: illegal inode type");
335 attr_index
= 2 + hasdata
;
336 switch (f
->ilf_fields
& XFS_ILOG_AFORK
) {
338 ASSERT(f
->ilf_size
== 3 + hasdata
);
339 printf(_(" ATTR FORK EXTENTS inode data:\n"));
340 if (print_inode
&& print_data
)
341 xlog_recover_print_data(
342 item
->ri_buf
[attr_index
].i_addr
,
343 item
->ri_buf
[attr_index
].i_len
);
345 case XFS_ILOG_ABROOT
:
346 ASSERT(f
->ilf_size
== 3 + hasdata
);
347 printf(_(" ATTR FORK BTREE inode data:\n"));
348 if (print_inode
&& print_data
)
349 xlog_recover_print_data(
350 item
->ri_buf
[attr_index
].i_addr
,
351 item
->ri_buf
[attr_index
].i_len
);
354 ASSERT(f
->ilf_size
== 3 + hasdata
);
355 printf(_(" ATTR FORK LOCAL inode data:\n"));
356 if (print_inode
&& print_data
)
357 xlog_recover_print_data(
358 item
->ri_buf
[attr_index
].i_addr
,
359 item
->ri_buf
[attr_index
].i_len
);
362 xlog_panic("%s: illegal inode log flag", __FUNCTION__
);
369 xlog_recover_print_icreate(
370 struct xlog_recover_item
*item
)
372 struct xfs_icreate_log
*icl
;
374 icl
= (struct xfs_icreate_log
*)item
->ri_buf
[0].i_addr
;
376 printf(_(" ICR: #ag: %d agbno: 0x%x len: %d\n"
377 " cnt: %d isize: %d gen: 0x%x\n"),
378 be32_to_cpu(icl
->icl_ag
), be32_to_cpu(icl
->icl_agbno
),
379 be32_to_cpu(icl
->icl_length
), be32_to_cpu(icl
->icl_count
),
380 be32_to_cpu(icl
->icl_isize
), be32_to_cpu(icl
->icl_gen
));
384 xlog_recover_print_logitem(
385 xlog_recover_item_t
*item
)
387 switch (ITEM_TYPE(item
)) {
389 xlog_recover_print_buffer(item
);
392 xlog_recover_print_icreate(item
);
395 xlog_recover_print_inode(item
);
398 xlog_recover_print_efd(item
);
401 xlog_recover_print_efi(item
);
404 xlog_recover_print_rud(item
);
407 xlog_recover_print_rui(item
);
410 xlog_recover_print_cud(item
);
413 xlog_recover_print_cui(item
);
416 xlog_recover_print_bud(item
);
419 xlog_recover_print_bui(item
);
422 xlog_recover_print_dquot(item
);
424 case XFS_LI_QUOTAOFF
:
425 xlog_recover_print_quotaoff(item
);
428 printf(_("xlog_recover_print_logitem: illegal type\n"));
434 xlog_recover_print_item(
435 xlog_recover_item_t
*item
)
439 switch (ITEM_TYPE(item
)) {
476 case XFS_LI_QUOTAOFF
:
480 cmn_err(CE_PANIC
, _("%s: illegal type"), __FUNCTION__
);
484 /* type isn't filled in yet
485 printf(_("ITEM: type: %d cnt: %d total: %d "),
486 item->ri_type, item->ri_cnt, item->ri_total);
488 printf(_(": cnt:%d total:%d "), item
->ri_cnt
, item
->ri_total
);
489 for (i
=0; i
<item
->ri_cnt
; i
++) {
490 printf(_("a:0x%lx len:%d "),
491 (long)item
->ri_buf
[i
].i_addr
, item
->ri_buf
[i
].i_len
);
494 xlog_recover_print_logitem(item
);
498 xlog_recover_print_trans(
499 xlog_recover_t
*trans
,
500 struct list_head
*itemq
,
503 xlog_recover_item_t
*item
;
508 print_xlog_record_line();
509 xlog_recover_print_trans_head(trans
);
510 list_for_each_entry(item
, itemq
, ri_list
)
511 xlog_recover_print_item(item
);