]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - logprint/log_redo.c
xfsprogs: Release v4.18.0
[thirdparty/xfsprogs-dev.git] / logprint / log_redo.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
4 * Copyright (c) 2016 Oracle, Inc.
5 * All Rights Reserved.
6 */
7 #include "libxfs.h"
8 #include "libxlog.h"
9
10 #include "logprint.h"
11
12 /* Extent Free Items */
13
14 static int
15 xfs_efi_copy_format(
16 char *buf,
17 uint len,
18 struct xfs_efi_log_format *dst_efi_fmt,
19 int continued)
20 {
21 uint i;
22 uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents;
23 uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents - 1) * sizeof(xfs_extent_t);
24 uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t);
25 uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t);
26
27 if (len == dst_len || continued) {
28 memcpy((char *)dst_efi_fmt, buf, len);
29 return 0;
30 } else if (len == len32) {
31 xfs_efi_log_format_32_t *src_efi_fmt_32 = (xfs_efi_log_format_32_t *)buf;
32
33 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
34 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
35 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
36 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
37 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
38 dst_efi_fmt->efi_extents[i].ext_start =
39 src_efi_fmt_32->efi_extents[i].ext_start;
40 dst_efi_fmt->efi_extents[i].ext_len =
41 src_efi_fmt_32->efi_extents[i].ext_len;
42 }
43 return 0;
44 } else if (len == len64) {
45 xfs_efi_log_format_64_t *src_efi_fmt_64 = (xfs_efi_log_format_64_t *)buf;
46
47 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
48 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
49 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
50 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
51 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
52 dst_efi_fmt->efi_extents[i].ext_start =
53 src_efi_fmt_64->efi_extents[i].ext_start;
54 dst_efi_fmt->efi_extents[i].ext_len =
55 src_efi_fmt_64->efi_extents[i].ext_len;
56 }
57 return 0;
58 }
59 fprintf(stderr, _("%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n"),
60 progname, len, len32, len64, nextents);
61 return 1;
62 }
63
64 int
65 xlog_print_trans_efi(
66 char **ptr,
67 uint src_len,
68 int continued)
69 {
70 xfs_efi_log_format_t *src_f, *f = NULL;
71 uint dst_len;
72 xfs_extent_t *ex;
73 int i;
74 int error = 0;
75 int core_size = offsetof(xfs_efi_log_format_t, efi_extents);
76
77 /*
78 * memmove to ensure 8-byte alignment for the long longs in
79 * xfs_efi_log_format_t structure
80 */
81 if ((src_f = (xfs_efi_log_format_t *)malloc(src_len)) == NULL) {
82 fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
83 exit(1);
84 }
85 memmove((char*)src_f, *ptr, src_len);
86 *ptr += src_len;
87
88 /* convert to native format */
89 dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t);
90
91 if (continued && src_len < core_size) {
92 printf(_("EFI: Not enough data to decode further\n"));
93 error = 1;
94 goto error;
95 }
96
97 if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) {
98 fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
99 exit(1);
100 }
101 if (xfs_efi_copy_format((char*)src_f, src_len, f, continued)) {
102 error = 1;
103 goto error;
104 }
105
106 printf(_("EFI: #regs: %d num_extents: %d id: 0x%llx\n"),
107 f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
108
109 if (continued) {
110 printf(_("EFI free extent data skipped (CONTINUE set, no space)\n"));
111 goto error;
112 }
113
114 ex = f->efi_extents;
115 for (i=0; i < f->efi_nextents; i++) {
116 printf("(s: 0x%llx, l: %d) ",
117 (unsigned long long)ex->ext_start, ex->ext_len);
118 if (i % 4 == 3) printf("\n");
119 ex++;
120 }
121 if (i % 4 != 0)
122 printf("\n");
123 error:
124 free(src_f);
125 free(f);
126 return error;
127 } /* xlog_print_trans_efi */
128
129 void
130 xlog_recover_print_efi(
131 xlog_recover_item_t *item)
132 {
133 xfs_efi_log_format_t *f, *src_f;
134 xfs_extent_t *ex;
135 int i;
136 uint src_len, dst_len;
137
138 src_f = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
139 src_len = item->ri_buf[0].i_len;
140 /*
141 * An xfs_efi_log_format structure contains a variable length array
142 * as the last field.
143 * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
144 * Need to convert to native format.
145 */
146 dst_len = sizeof(xfs_efi_log_format_t) +
147 (src_f->efi_nextents - 1) * sizeof(xfs_extent_t);
148 if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) {
149 fprintf(stderr, _("%s: xlog_recover_print_efi: malloc failed\n"),
150 progname);
151 exit(1);
152 }
153 if (xfs_efi_copy_format((char*)src_f, src_len, f, 0)) {
154 free(f);
155 return;
156 }
157
158 printf(_(" EFI: #regs:%d num_extents:%d id:0x%llx\n"),
159 f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
160 ex = f->efi_extents;
161 printf(" ");
162 for (i=0; i< f->efi_nextents; i++) {
163 printf("(s: 0x%llx, l: %d) ",
164 (unsigned long long)ex->ext_start, ex->ext_len);
165 if (i % 4 == 3)
166 printf("\n");
167 ex++;
168 }
169 if (i % 4 != 0)
170 printf("\n");
171 free(f);
172 }
173
174 int
175 xlog_print_trans_efd(char **ptr, uint len)
176 {
177 xfs_efd_log_format_t *f;
178 xfs_efd_log_format_t lbuf;
179 /* size without extents at end */
180 uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t);
181
182 /*
183 * memmove to ensure 8-byte alignment for the long longs in
184 * xfs_efd_log_format_t structure
185 */
186 memmove(&lbuf, *ptr, min(core_size, len));
187 f = &lbuf;
188 *ptr += len;
189 if (len >= core_size) {
190 printf(_("EFD: #regs: %d num_extents: %d id: 0x%llx\n"),
191 f->efd_size, f->efd_nextents,
192 (unsigned long long)f->efd_efi_id);
193
194 /* don't print extents as they are not used */
195
196 return 0;
197 } else {
198 printf(_("EFD: Not enough data to decode further\n"));
199 return 1;
200 }
201 } /* xlog_print_trans_efd */
202
203 void
204 xlog_recover_print_efd(
205 xlog_recover_item_t *item)
206 {
207 xfs_efd_log_format_t *f;
208
209 f = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
210 /*
211 * An xfs_efd_log_format structure contains a variable length array
212 * as the last field.
213 * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
214 * However, the extents are never used and won't be printed.
215 */
216 printf(_(" EFD: #regs: %d num_extents: %d id: 0x%llx\n"),
217 f->efd_size, f->efd_nextents,
218 (unsigned long long)f->efd_efi_id);
219 }
220
221 /* Reverse Mapping Update Items */
222
223 static int
224 xfs_rui_copy_format(
225 char *buf,
226 uint len,
227 struct xfs_rui_log_format *dst_fmt,
228 int continued)
229 {
230 uint nextents = ((struct xfs_rui_log_format *)buf)->rui_nextents;
231 uint dst_len = xfs_rui_log_format_sizeof(nextents);
232
233 if (len == dst_len || continued) {
234 memcpy((char *)dst_fmt, buf, len);
235 return 0;
236 }
237 fprintf(stderr, _("%s: bad size of RUI format: %u; expected %u; nextents = %u\n"),
238 progname, len, dst_len, nextents);
239 return 1;
240 }
241
242 int
243 xlog_print_trans_rui(
244 char **ptr,
245 uint src_len,
246 int continued)
247 {
248 struct xfs_rui_log_format *src_f, *f = NULL;
249 uint dst_len;
250 uint nextents;
251 struct xfs_map_extent *ex;
252 int i;
253 int error = 0;
254 int core_size;
255
256 core_size = offsetof(struct xfs_rui_log_format, rui_extents);
257
258 /*
259 * memmove to ensure 8-byte alignment for the long longs in
260 * struct xfs_rui_log_format structure
261 */
262 src_f = malloc(src_len);
263 if (src_f == NULL) {
264 fprintf(stderr, _("%s: %s: malloc failed\n"),
265 progname, __func__);
266 exit(1);
267 }
268 memmove((char*)src_f, *ptr, src_len);
269 *ptr += src_len;
270
271 /* convert to native format */
272 nextents = src_f->rui_nextents;
273 dst_len = xfs_rui_log_format_sizeof(nextents);
274
275 if (continued && src_len < core_size) {
276 printf(_("RUI: Not enough data to decode further\n"));
277 error = 1;
278 goto error;
279 }
280
281 f = malloc(dst_len);
282 if (f == NULL) {
283 fprintf(stderr, _("%s: %s: malloc failed\n"),
284 progname, __func__);
285 exit(1);
286 }
287 if (xfs_rui_copy_format((char *)src_f, src_len, f, continued)) {
288 error = 1;
289 goto error;
290 }
291
292 printf(_("RUI: #regs: %d num_extents: %d id: 0x%llx\n"),
293 f->rui_size, f->rui_nextents, (unsigned long long)f->rui_id);
294
295 if (continued) {
296 printf(_("RUI extent data skipped (CONTINUE set, no space)\n"));
297 goto error;
298 }
299
300 ex = f->rui_extents;
301 for (i=0; i < f->rui_nextents; i++) {
302 printf("(s: 0x%llx, l: %d, own: %lld, off: %llu, f: 0x%x) ",
303 (unsigned long long)ex->me_startblock, ex->me_len,
304 (long long)ex->me_owner,
305 (unsigned long long)ex->me_startoff, ex->me_flags);
306 printf("\n");
307 ex++;
308 }
309 error:
310 free(src_f);
311 free(f);
312 return error;
313 }
314
315 void
316 xlog_recover_print_rui(
317 struct xlog_recover_item *item)
318 {
319 char *src_f;
320 uint src_len;
321
322 src_f = item->ri_buf[0].i_addr;
323 src_len = item->ri_buf[0].i_len;
324
325 xlog_print_trans_rui(&src_f, src_len, 0);
326 }
327
328 int
329 xlog_print_trans_rud(
330 char **ptr,
331 uint len)
332 {
333 struct xfs_rud_log_format *f;
334 struct xfs_rud_log_format lbuf;
335
336 /* size without extents at end */
337 uint core_size = sizeof(struct xfs_rud_log_format);
338
339 /*
340 * memmove to ensure 8-byte alignment for the long longs in
341 * xfs_efd_log_format_t structure
342 */
343 memmove(&lbuf, *ptr, min(core_size, len));
344 f = &lbuf;
345 *ptr += len;
346 if (len >= core_size) {
347 printf(_("RUD: #regs: %d id: 0x%llx\n"),
348 f->rud_size,
349 (unsigned long long)f->rud_rui_id);
350
351 /* don't print extents as they are not used */
352
353 return 0;
354 } else {
355 printf(_("RUD: Not enough data to decode further\n"));
356 return 1;
357 }
358 }
359
360 void
361 xlog_recover_print_rud(
362 struct xlog_recover_item *item)
363 {
364 char *f;
365
366 f = item->ri_buf[0].i_addr;
367 xlog_print_trans_rud(&f, sizeof(struct xfs_rud_log_format));
368 }
369
370 /* Reference Count Update Items */
371
372 static int
373 xfs_cui_copy_format(
374 struct xfs_cui_log_format *cui,
375 uint len,
376 struct xfs_cui_log_format *dst_fmt,
377 int continued)
378 {
379 uint nextents;
380 uint dst_len;
381
382 nextents = cui->cui_nextents;
383 dst_len = xfs_cui_log_format_sizeof(nextents);
384
385 if (len == dst_len || continued) {
386 memcpy(dst_fmt, cui, len);
387 return 0;
388 }
389 fprintf(stderr, _("%s: bad size of CUI format: %u; expected %u; nextents = %u\n"),
390 progname, len, dst_len, nextents);
391 return 1;
392 }
393
394 int
395 xlog_print_trans_cui(
396 char **ptr,
397 uint src_len,
398 int continued)
399 {
400 struct xfs_cui_log_format *src_f, *f = NULL;
401 uint dst_len;
402 uint nextents;
403 struct xfs_phys_extent *ex;
404 int i;
405 int error = 0;
406 int core_size;
407
408 core_size = offsetof(struct xfs_cui_log_format, cui_extents);
409
410 src_f = malloc(src_len);
411 if (src_f == NULL) {
412 fprintf(stderr, _("%s: %s: malloc failed\n"),
413 progname, __func__);
414 exit(1);
415 }
416 memcpy(src_f, *ptr, src_len);
417 *ptr += src_len;
418
419 /* convert to native format */
420 nextents = src_f->cui_nextents;
421 dst_len = xfs_cui_log_format_sizeof(nextents);
422
423 if (continued && src_len < core_size) {
424 printf(_("CUI: Not enough data to decode further\n"));
425 error = 1;
426 goto error;
427 }
428
429 f = malloc(dst_len);
430 if (f == NULL) {
431 fprintf(stderr, _("%s: %s: malloc failed\n"),
432 progname, __func__);
433 exit(1);
434 }
435 if (xfs_cui_copy_format(src_f, src_len, f, continued)) {
436 error = 1;
437 goto error;
438 }
439
440 printf(_("CUI: #regs: %d num_extents: %d id: 0x%llx\n"),
441 f->cui_size, f->cui_nextents, (unsigned long long)f->cui_id);
442
443 if (continued) {
444 printf(_("CUI extent data skipped (CONTINUE set, no space)\n"));
445 goto error;
446 }
447
448 ex = f->cui_extents;
449 for (i=0; i < f->cui_nextents; i++) {
450 printf("(s: 0x%llx, l: %d, f: 0x%x) ",
451 (unsigned long long)ex->pe_startblock, ex->pe_len,
452 ex->pe_flags);
453 printf("\n");
454 ex++;
455 }
456 error:
457 free(src_f);
458 free(f);
459 return error;
460 }
461
462 void
463 xlog_recover_print_cui(
464 struct xlog_recover_item *item)
465 {
466 char *src_f;
467 uint src_len;
468
469 src_f = item->ri_buf[0].i_addr;
470 src_len = item->ri_buf[0].i_len;
471
472 xlog_print_trans_cui(&src_f, src_len, 0);
473 }
474
475 int
476 xlog_print_trans_cud(
477 char **ptr,
478 uint len)
479 {
480 struct xfs_cud_log_format *f;
481 struct xfs_cud_log_format lbuf;
482
483 /* size without extents at end */
484 uint core_size = sizeof(struct xfs_cud_log_format);
485
486 memcpy(&lbuf, *ptr, min(core_size, len));
487 f = &lbuf;
488 *ptr += len;
489 if (len >= core_size) {
490 printf(_("CUD: #regs: %d id: 0x%llx\n"),
491 f->cud_size,
492 (unsigned long long)f->cud_cui_id);
493
494 /* don't print extents as they are not used */
495
496 return 0;
497 } else {
498 printf(_("CUD: Not enough data to decode further\n"));
499 return 1;
500 }
501 }
502
503 void
504 xlog_recover_print_cud(
505 struct xlog_recover_item *item)
506 {
507 char *f;
508
509 f = item->ri_buf[0].i_addr;
510 xlog_print_trans_cud(&f, sizeof(struct xfs_cud_log_format));
511 }
512
513 /* Block Mapping Update Items */
514
515 static int
516 xfs_bui_copy_format(
517 struct xfs_bui_log_format *bui,
518 uint len,
519 struct xfs_bui_log_format *dst_fmt,
520 int continued)
521 {
522 uint nextents;
523 uint dst_len;
524
525 nextents = bui->bui_nextents;
526 dst_len = xfs_bui_log_format_sizeof(nextents);
527
528 if (len == dst_len || continued) {
529 memcpy(dst_fmt, bui, len);
530 return 0;
531 }
532 fprintf(stderr, _("%s: bad size of BUI format: %u; expected %u; nextents = %u\n"),
533 progname, len, dst_len, nextents);
534 return 1;
535 }
536
537 int
538 xlog_print_trans_bui(
539 char **ptr,
540 uint src_len,
541 int continued)
542 {
543 struct xfs_bui_log_format *src_f, *f = NULL;
544 uint dst_len;
545 uint nextents;
546 struct xfs_map_extent *ex;
547 int i;
548 int error = 0;
549 int core_size;
550
551 core_size = offsetof(struct xfs_bui_log_format, bui_extents);
552
553 src_f = malloc(src_len);
554 if (src_f == NULL) {
555 fprintf(stderr, _("%s: %s: malloc failed\n"),
556 progname, __func__);
557 exit(1);
558 }
559 memcpy(src_f, *ptr, src_len);
560 *ptr += src_len;
561
562 /* convert to native format */
563 nextents = src_f->bui_nextents;
564 dst_len = xfs_bui_log_format_sizeof(nextents);
565
566 if (continued && src_len < core_size) {
567 printf(_("BUI: Not enough data to decode further\n"));
568 error = 1;
569 goto error;
570 }
571
572 f = malloc(dst_len);
573 if (f == NULL) {
574 fprintf(stderr, _("%s: %s: malloc failed\n"),
575 progname, __func__);
576 exit(1);
577 }
578 if (xfs_bui_copy_format(src_f, src_len, f, continued)) {
579 error = 1;
580 goto error;
581 }
582
583 printf(_("BUI: #regs: %d num_extents: %d id: 0x%llx\n"),
584 f->bui_size, f->bui_nextents, (unsigned long long)f->bui_id);
585
586 if (continued) {
587 printf(_("BUI extent data skipped (CONTINUE set, no space)\n"));
588 goto error;
589 }
590
591 ex = f->bui_extents;
592 for (i=0; i < f->bui_nextents; i++) {
593 printf("(s: 0x%llx, l: %d, own: %lld, off: %llu, f: 0x%x) ",
594 (unsigned long long)ex->me_startblock, ex->me_len,
595 (long long)ex->me_owner,
596 (unsigned long long)ex->me_startoff, ex->me_flags);
597 printf("\n");
598 ex++;
599 }
600 error:
601 free(src_f);
602 free(f);
603 return error;
604 }
605
606 void
607 xlog_recover_print_bui(
608 struct xlog_recover_item *item)
609 {
610 char *src_f;
611 uint src_len;
612
613 src_f = item->ri_buf[0].i_addr;
614 src_len = item->ri_buf[0].i_len;
615
616 xlog_print_trans_bui(&src_f, src_len, 0);
617 }
618
619 int
620 xlog_print_trans_bud(
621 char **ptr,
622 uint len)
623 {
624 struct xfs_bud_log_format *f;
625 struct xfs_bud_log_format lbuf;
626
627 /* size without extents at end */
628 uint core_size = sizeof(struct xfs_bud_log_format);
629
630 memcpy(&lbuf, *ptr, min(core_size, len));
631 f = &lbuf;
632 *ptr += len;
633 if (len >= core_size) {
634 printf(_("BUD: #regs: %d id: 0x%llx\n"),
635 f->bud_size,
636 (unsigned long long)f->bud_bui_id);
637
638 /* don't print extents as they are not used */
639
640 return 0;
641 } else {
642 printf(_("BUD: Not enough data to decode further\n"));
643 return 1;
644 }
645 }
646
647 void
648 xlog_recover_print_bud(
649 struct xlog_recover_item *item)
650 {
651 char *f;
652
653 f = item->ri_buf[0].i_addr;
654 xlog_print_trans_bud(&f, sizeof(struct xfs_bud_log_format));
655 }