]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - logprint/log_print_all.c
xfs_repair: skip block reservation when fixing freelist
[thirdparty/xfsprogs-dev.git] / logprint / log_print_all.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 /*
12 * Start is defined to be the block pointing to the oldest valid log record.
13 */
14 int
15 xlog_print_find_oldest(
16 struct xlog *log,
17 xfs_daddr_t *last_blk)
18 {
19 xfs_buf_t *bp;
20 xfs_daddr_t first_blk;
21 uint first_half_cycle, last_half_cycle;
22 int error = 0;
23
24 if (xlog_find_zeroed(log, &first_blk))
25 return 0;
26
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);
35
36 if (first_half_cycle == last_half_cycle) /* all cycle nos are same */
37 *last_blk = 0;
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);
41
42 xlog_put_bp(bp);
43 return error;
44 }
45
46 void
47 xlog_recover_print_data(
48 char *p,
49 int len)
50 {
51 if (print_data) {
52 uint *dp = (uint *)p;
53 int nums = len >> 2;
54 int j = 0;
55
56 while (j < nums) {
57 if ((j % 8) == 0)
58 printf("%2x ", j);
59 printf("%8x ", *dp);
60 dp++;
61 j++;
62 if ((j % 8) == 0)
63 printf("\n");
64 }
65 printf("\n");
66 }
67 }
68
69 STATIC void
70 xlog_recover_print_buffer(
71 xlog_recover_item_t *item)
72 {
73 xfs_agi_t *agi;
74 xfs_agf_t *agf;
75 xfs_buf_log_format_t *f;
76 char *p;
77 int len, num, i;
78 xfs_daddr_t blkno;
79 xfs_disk_dquot_t *ddq;
80
81 f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
82 printf(" ");
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;
87 num = f->blf_size-1;
88 i = 1;
89 while (num-- > 0) {
90 p = item->ri_buf[i].i_addr;
91 len = item->ri_buf[i].i_len;
92 i++;
93 if (blkno == 0) { /* super block */
94 printf(_(" SUPER Block Buffer:\n"));
95 if (!print_buffer)
96 continue;
97 printf(_(" icount:%llu ifree:%llu "),
98 (unsigned long long)
99 be64_to_cpu(*(__be64 *)(p)),
100 (unsigned long long)
101 be64_to_cpu(*(__be64 *)(p+8)));
102 printf(_("fdblks:%llu frext:%llu\n"),
103 (unsigned long long)
104 be64_to_cpu(*(__be64 *)(p+16)),
105 (unsigned long long)
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) {
111 int bucket, buckets;
112 agi = (xfs_agi_t *)p;
113 printf(_(" AGI Buffer: (XAGI)\n"));
114 if (!print_buffer)
115 continue;
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));
127 if (len == 128) {
128 buckets = 17;
129 } else if (len == 256) {
130 buckets = 32 + 17;
131 } else {
132 buckets = XFS_AGI_UNLINKED_BUCKETS;
133 }
134 for (bucket = 0; bucket < buckets;) {
135 int col;
136 printf(_("bucket[%d - %d]: "), bucket, bucket+3);
137 for (col = 0; col < 4; col++, bucket++) {
138 if (bucket < buckets) {
139 printf("0x%x ",
140 be32_to_cpu(agi->agi_unlinked[bucket]));
141 }
142 }
143 printf("\n");
144 }
145 } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGF_MAGIC) {
146 agf = (xfs_agf_t *)p;
147 printf(_(" AGF Buffer: (XAGF)\n"));
148 if (!print_buffer)
149 continue;
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"));
170 if (!print_buffer)
171 continue;
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);
176 } else {
177 printf(_(" BUF DATA\n"));
178 if (!print_buffer) continue;
179 xlog_recover_print_data(p, len);
180 }
181 }
182 }
183
184 STATIC void
185 xlog_recover_print_quotaoff(
186 xlog_recover_item_t *item)
187 {
188 xfs_qoff_logformat_t *qoff_f;
189 char str[32] = { 0 };
190
191 qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr;
192 ASSERT(qoff_f);
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);
201 }
202
203 STATIC void
204 xlog_recover_print_dquot(
205 xlog_recover_item_t *item)
206 {
207 xfs_dq_logformat_t *f;
208 xfs_disk_dquot_t *d;
209
210 f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr;
211 ASSERT(f);
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);
216 if (!print_quota)
217 return;
218 printf(_("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n"),
219 be16_to_cpu(d->d_magic),
220 d->d_version,
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));
237 }
238
239 STATIC void
240 xlog_recover_print_inode_core(
241 struct xfs_log_dinode *di)
242 {
243 printf(_(" CORE inode:\n"));
244 if (!print_inode)
245 return;
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 "
260 "gen:%u\n"),
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);
266 }
267 }
268
269 STATIC void
270 xlog_recover_print_inode(
271 xlog_recover_item_t *item)
272 {
273 struct xfs_inode_log_format f_buf;
274 struct xfs_inode_log_format *f;
275 int attr_index;
276 int hasdata;
277 int hasattr;
278
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);
282
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,
285 f->ilf_dsize);
286
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);
292
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)) {
297 case XFS_ILOG_DEXT:
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);
303 break;
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);
310 break;
311 case XFS_ILOG_DDATA:
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);
317 break;
318 case XFS_ILOG_DEV:
319 ASSERT(f->ilf_size == 2 + hasattr);
320 printf(_(" DEV inode: no extra region\n"));
321 break;
322 case XFS_ILOG_UUID:
323 ASSERT(f->ilf_size == 2 + hasattr);
324 printf(_(" UUID inode: no extra region\n"));
325 break;
326
327 case 0:
328 ASSERT(f->ilf_size == 2 + hasattr);
329 break;
330 default:
331 xlog_panic("xlog_print_trans_inode: illegal inode type");
332 }
333
334 if (hasattr) {
335 attr_index = 2 + hasdata;
336 switch (f->ilf_fields & XFS_ILOG_AFORK) {
337 case XFS_ILOG_AEXT:
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);
344 break;
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);
352 break;
353 case XFS_ILOG_ADATA:
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);
360 break;
361 default:
362 xlog_panic("%s: illegal inode log flag", __FUNCTION__);
363 }
364 }
365 }
366
367
368 STATIC void
369 xlog_recover_print_icreate(
370 struct xlog_recover_item *item)
371 {
372 struct xfs_icreate_log *icl;
373
374 icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
375
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));
381 }
382
383 void
384 xlog_recover_print_logitem(
385 xlog_recover_item_t *item)
386 {
387 switch (ITEM_TYPE(item)) {
388 case XFS_LI_BUF:
389 xlog_recover_print_buffer(item);
390 break;
391 case XFS_LI_ICREATE:
392 xlog_recover_print_icreate(item);
393 break;
394 case XFS_LI_INODE:
395 xlog_recover_print_inode(item);
396 break;
397 case XFS_LI_EFD:
398 xlog_recover_print_efd(item);
399 break;
400 case XFS_LI_EFI:
401 xlog_recover_print_efi(item);
402 break;
403 case XFS_LI_RUD:
404 xlog_recover_print_rud(item);
405 break;
406 case XFS_LI_RUI:
407 xlog_recover_print_rui(item);
408 break;
409 case XFS_LI_CUD:
410 xlog_recover_print_cud(item);
411 break;
412 case XFS_LI_CUI:
413 xlog_recover_print_cui(item);
414 break;
415 case XFS_LI_BUD:
416 xlog_recover_print_bud(item);
417 break;
418 case XFS_LI_BUI:
419 xlog_recover_print_bui(item);
420 break;
421 case XFS_LI_DQUOT:
422 xlog_recover_print_dquot(item);
423 break;
424 case XFS_LI_QUOTAOFF:
425 xlog_recover_print_quotaoff(item);
426 break;
427 default:
428 printf(_("xlog_recover_print_logitem: illegal type\n"));
429 break;
430 }
431 }
432
433 static void
434 xlog_recover_print_item(
435 xlog_recover_item_t *item)
436 {
437 int i;
438
439 switch (ITEM_TYPE(item)) {
440 case XFS_LI_BUF:
441 printf("BUF");
442 break;
443 case XFS_LI_ICREATE:
444 printf("ICR");
445 break;
446 case XFS_LI_INODE:
447 printf("INO");
448 break;
449 case XFS_LI_EFD:
450 printf("EFD");
451 break;
452 case XFS_LI_EFI:
453 printf("EFI");
454 break;
455 case XFS_LI_RUD:
456 printf("RUD");
457 break;
458 case XFS_LI_RUI:
459 printf("RUI");
460 break;
461 case XFS_LI_CUD:
462 printf("CUD");
463 break;
464 case XFS_LI_CUI:
465 printf("CUI");
466 break;
467 case XFS_LI_BUD:
468 printf("BUD");
469 break;
470 case XFS_LI_BUI:
471 printf("BUI");
472 break;
473 case XFS_LI_DQUOT:
474 printf("DQ ");
475 break;
476 case XFS_LI_QUOTAOFF:
477 printf("QOFF");
478 break;
479 default:
480 cmn_err(CE_PANIC, _("%s: illegal type"), __FUNCTION__);
481 break;
482 }
483
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);
487 */
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);
492 }
493 printf("\n");
494 xlog_recover_print_logitem(item);
495 }
496
497 void
498 xlog_recover_print_trans(
499 xlog_recover_t *trans,
500 struct list_head *itemq,
501 int print)
502 {
503 xlog_recover_item_t *item;
504
505 if (print < 3)
506 return;
507
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);
512 }