]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/metadump.c
xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset
[thirdparty/xfsprogs-dev.git] / db / metadump.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
61983f67 2/*
56281ed4 3 * Copyright (c) 2007, 2011 SGI
61983f67 4 * All Rights Reserved.
61983f67
BN
5 */
6
6b803e5a
CH
7#include "libxfs.h"
8#include "libxlog.h"
61983f67
BN
9#include "bmap.h"
10#include "command.h"
11#include "metadump.h"
12#include "io.h"
13#include "output.h"
14#include "type.h"
15#include "init.h"
16#include "sig.h"
17#include "xfs_metadump.h"
a2ceac1f
DC
18#include "fprint.h"
19#include "faddr.h"
20#include "field.h"
21#include "dir2.h"
61983f67 22
921c3067 23#define DEFAULT_MAX_EXT_SIZE MAXEXTLEN
7431d134 24
61983f67
BN
25/* copy all metadata structures to/from a file */
26
27static int metadump_f(int argc, char **argv);
28static void metadump_help(void);
29
30/*
31 * metadump commands issue info/wornings/errors to standard error as
32 * metadump supports stdout as a destination.
33 *
34 * All static functions return zero on failure, while the public functions
35 * return zero on success.
36 */
37
38static const cmdinfo_t metadump_cmd =
39 { "metadump", NULL, metadump_f, 0, -1, 0,
b09e839e 40 N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
9ee7055c 41 N_("dump metadata to a file"), metadump_help };
61983f67
BN
42
43static FILE *outf; /* metadump file */
44
45static xfs_metablock_t *metablock; /* header + index + buffers */
46static __be64 *block_index;
47static char *block_buffer;
48
d7006beb 49static int num_indices;
61983f67
BN
50static int cur_index;
51
52static xfs_ino_t cur_ino;
53
54static int show_progress = 0;
55static int stop_on_read_error = 0;
7431d134 56static int max_extent_size = DEFAULT_MAX_EXT_SIZE;
ffc56f19 57static int obfuscate = 1;
b09e839e 58static int zero_stale_data = 1;
61983f67
BN
59static int show_warnings = 0;
60static int progress_since_warning = 0;
449df236 61static bool stdout_metadump;
61983f67
BN
62
63void
64metadump_init(void)
65{
66 add_command(&metadump_cmd);
67}
68
69static void
70metadump_help(void)
71{
9ee7055c 72 dbprintf(_(
61983f67
BN
73"\n"
74" The 'metadump' command dumps the known metadata to a compact file suitable\n"
75" for compressing and sending to an XFS maintainer for corruption analysis \n"
76" or xfs_repair failures.\n\n"
88b8e1d6 77" Options:\n"
b09e839e 78" -a -- Copy full metadata blocks without zeroing unused space\n"
61983f67
BN
79" -e -- Ignore read errors and keep going\n"
80" -g -- Display dump progress\n"
7431d134 81" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
61983f67
BN
82" -o -- Don't obfuscate names and extended attributes\n"
83" -w -- Show warnings of bad metadata information\n"
9ee7055c 84"\n"), DEFAULT_MAX_EXT_SIZE);
61983f67
BN
85}
86
87static void
88print_warning(const char *fmt, ...)
89{
90 char buf[200];
91 va_list ap;
92
93 if (seenint())
94 return;
95
96 va_start(ap, fmt);
97 vsnprintf(buf, sizeof(buf), fmt, ap);
98 va_end(ap);
99 buf[sizeof(buf)-1] = '\0';
100
101 fprintf(stderr, "%s%s: %s\n", progress_since_warning ? "\n" : "",
102 progname, buf);
103 progress_since_warning = 0;
104}
105
106static void
107print_progress(const char *fmt, ...)
108{
109 char buf[60];
110 va_list ap;
111 FILE *f;
112
113 if (seenint())
114 return;
115
116 va_start(ap, fmt);
117 vsnprintf(buf, sizeof(buf), fmt, ap);
118 va_end(ap);
119 buf[sizeof(buf)-1] = '\0';
120
449df236 121 f = stdout_metadump ? stderr : stdout;
61983f67
BN
122 fprintf(f, "\r%-59s", buf);
123 fflush(f);
124 progress_since_warning = 1;
125}
126
127/*
128 * A complete dump file will have a "zero" entry in the last index block,
129 * even if the dump is exactly aligned, the last index will be full of
130 * zeros. If the last index entry is non-zero, the dump is incomplete.
d7006beb 131 * Correspondingly, the last chunk will have a count < num_indices.
878afc65
DC
132 *
133 * Return 0 for success, -1 for failure.
61983f67
BN
134 */
135
136static int
137write_index(void)
138{
139 /*
140 * write index block and following data blocks (streaming)
141 */
142 metablock->mb_count = cpu_to_be16(cur_index);
143 if (fwrite(metablock, (cur_index + 1) << BBSHIFT, 1, outf) != 1) {
4aa3c02f
ES
144 print_warning("error writing to target file");
145 return -1;
61983f67
BN
146 }
147
d7006beb 148 memset(block_index, 0, num_indices * sizeof(__be64));
61983f67 149 cur_index = 0;
878afc65 150 return 0;
61983f67
BN
151}
152
1516a5b5
DC
153/*
154 * Return 0 for success, -errno for failure.
155 */
156static int
157write_buf_segment(
158 char *data,
14f8b681 159 int64_t off,
1516a5b5
DC
160 int len)
161{
162 int i;
163 int ret;
164
165 for (i = 0; i < len; i++, off++, data += BBSIZE) {
166 block_index[cur_index] = cpu_to_be64(off);
167 memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE);
d7006beb 168 if (++cur_index == num_indices) {
1516a5b5
DC
169 ret = write_index();
170 if (ret)
171 return -EIO;
172 }
173 }
174 return 0;
175}
176
fd491857
DC
177/*
178 * we want to preserve the state of the metadata in the dump - whether it is
179 * intact or corrupt, so even if the buffer has a verifier attached to it we
180 * don't want to run it prior to writing the buffer to the metadump image.
181 *
182 * The only reason for running the verifier is to recalculate the CRCs on a
183 * buffer that has been obfuscated. i.e. a buffer than metadump modified itself.
184 * In this case, we only run the verifier if the buffer was not corrupt to begin
185 * with so that we don't accidentally correct buffers with CRC or errors in them
186 * when we are obfuscating them.
187 */
61983f67
BN
188static int
189write_buf(
190 iocur_t *buf)
191{
fd491857 192 struct xfs_buf *bp = buf->bp;
61983f67 193 int i;
878afc65 194 int ret;
61983f67 195
8ab75c4d
DC
196 /*
197 * Run the write verifier to recalculate the buffer CRCs and check
fd491857
DC
198 * metadump didn't introduce a new corruption. Warn if the verifier
199 * failed, but still continue to dump it into the output file.
8ab75c4d 200 */
fd491857
DC
201 if (buf->need_crc && bp && bp->b_ops && !bp->b_error) {
202 bp->b_ops->verify_write(bp);
203 if (bp->b_error) {
204 print_warning(
a3fac935
ES
205 "obfuscation corrupted block at %s bno 0x%llx/0x%x",
206 bp->b_ops->name,
fd491857 207 (long long)bp->b_bn, bp->b_bcount);
8ab75c4d
DC
208 }
209 }
210
1516a5b5
DC
211 /* handle discontiguous buffers */
212 if (!buf->bbmap) {
213 ret = write_buf_segment(buf->data, buf->bb, buf->blen);
214 if (ret)
215 return ret;
216 } else {
217 int len = 0;
218 for (i = 0; i < buf->bbmap->nmaps; i++) {
219 ret = write_buf_segment(buf->data + BBTOB(len),
220 buf->bbmap->b[i].bm_bn,
221 buf->bbmap->b[i].bm_len);
878afc65
DC
222 if (ret)
223 return ret;
1516a5b5 224 len += buf->bbmap->b[i].bm_len;
61983f67
BN
225 }
226 }
878afc65 227 return seenint() ? -EINTR : 0;
61983f67
BN
228}
229
6058426f
DC
230/*
231 * We could be processing a corrupt block, so we can't trust any of
232 * the offsets or lengths to be within the buffer range. Hence check
233 * carefully!
234 */
20f35ef4
ES
235static void
236zero_btree_node(
237 struct xfs_btree_block *block,
238 typnm_t btype)
239{
240 int nrecs;
241 xfs_bmbt_ptr_t *bpp;
242 xfs_bmbt_key_t *bkp;
243 xfs_inobt_ptr_t *ipp;
244 xfs_inobt_key_t *ikp;
245 xfs_alloc_ptr_t *app;
246 xfs_alloc_key_t *akp;
a7302f83
DC
247 char *zp1, *zp2;
248 char *key_end;
e7fd2b6f 249 struct xfs_ino_geometry *igeo = M_IGEO(mp);
20f35ef4
ES
250
251 nrecs = be16_to_cpu(block->bb_numrecs);
6058426f
DC
252 if (nrecs < 0)
253 return;
20f35ef4
ES
254
255 switch (btype) {
256 case TYP_BMAPBTA:
257 case TYP_BMAPBTD:
6058426f
DC
258 if (nrecs > mp->m_bmap_dmxr[1])
259 return;
260
20f35ef4
ES
261 bkp = XFS_BMBT_KEY_ADDR(mp, block, 1);
262 bpp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
a7302f83
DC
263 zp1 = (char *)&bkp[nrecs];
264 zp2 = (char *)&bpp[nrecs];
265 key_end = (char *)bpp;
20f35ef4
ES
266 break;
267 case TYP_INOBT:
268 case TYP_FINOBT:
e7fd2b6f 269 if (nrecs > igeo->inobt_mxr[1])
6058426f
DC
270 return;
271
20f35ef4 272 ikp = XFS_INOBT_KEY_ADDR(mp, block, 1);
e7fd2b6f 273 ipp = XFS_INOBT_PTR_ADDR(mp, block, 1, igeo->inobt_mxr[1]);
a7302f83
DC
274 zp1 = (char *)&ikp[nrecs];
275 zp2 = (char *)&ipp[nrecs];
276 key_end = (char *)ipp;
20f35ef4
ES
277 break;
278 case TYP_BNOBT:
279 case TYP_CNTBT:
6058426f
DC
280 if (nrecs > mp->m_alloc_mxr[1])
281 return;
282
20f35ef4
ES
283 akp = XFS_ALLOC_KEY_ADDR(mp, block, 1);
284 app = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]);
a7302f83
DC
285 zp1 = (char *)&akp[nrecs];
286 zp2 = (char *)&app[nrecs];
287 key_end = (char *)app;
20f35ef4
ES
288 break;
289 default:
a7302f83 290 return;
20f35ef4
ES
291 }
292
a7302f83
DC
293
294 /* Zero from end of keys to beginning of pointers */
295 memset(zp1, 0, key_end - zp1);
296
297 /* Zero from end of pointers to end of block */
298 memset(zp2, 0, (char *)block + mp->m_sb.sb_blocksize - zp2);
20f35ef4
ES
299}
300
6058426f
DC
301/*
302 * We could be processing a corrupt block, so we can't trust any of
303 * the offsets or lengths to be within the buffer range. Hence check
304 * carefully!
305 */
20f35ef4
ES
306static void
307zero_btree_leaf(
308 struct xfs_btree_block *block,
309 typnm_t btype)
310{
311 int nrecs;
312 struct xfs_bmbt_rec *brp;
313 struct xfs_inobt_rec *irp;
314 struct xfs_alloc_rec *arp;
a7302f83 315 char *zp;
20f35ef4
ES
316
317 nrecs = be16_to_cpu(block->bb_numrecs);
6058426f
DC
318 if (nrecs < 0)
319 return;
20f35ef4
ES
320
321 switch (btype) {
322 case TYP_BMAPBTA:
323 case TYP_BMAPBTD:
6058426f
DC
324 if (nrecs > mp->m_bmap_dmxr[0])
325 return;
326
20f35ef4 327 brp = XFS_BMBT_REC_ADDR(mp, block, 1);
a7302f83 328 zp = (char *)&brp[nrecs];
20f35ef4
ES
329 break;
330 case TYP_INOBT:
331 case TYP_FINOBT:
e7fd2b6f 332 if (nrecs > M_IGEO(mp)->inobt_mxr[0])
6058426f
DC
333 return;
334
20f35ef4 335 irp = XFS_INOBT_REC_ADDR(mp, block, 1);
a7302f83 336 zp = (char *)&irp[nrecs];
20f35ef4
ES
337 break;
338 case TYP_BNOBT:
339 case TYP_CNTBT:
6058426f
DC
340 if (nrecs > mp->m_alloc_mxr[0])
341 return;
342
20f35ef4 343 arp = XFS_ALLOC_REC_ADDR(mp, block, 1);
a7302f83 344 zp = (char *)&arp[nrecs];
20f35ef4
ES
345 break;
346 default:
a7302f83 347 return;
20f35ef4
ES
348 }
349
350 /* Zero from end of records to end of block */
a7302f83 351 memset(zp, 0, (char *)block + mp->m_sb.sb_blocksize - zp);
20f35ef4
ES
352}
353
354static void
355zero_btree_block(
356 struct xfs_btree_block *block,
357 typnm_t btype)
358{
359 int level;
360
361 level = be16_to_cpu(block->bb_level);
362
363 if (level > 0)
364 zero_btree_node(block, btype);
365 else
366 zero_btree_leaf(block, btype);
367}
61983f67
BN
368
369static int
370scan_btree(
371 xfs_agnumber_t agno,
372 xfs_agblock_t agbno,
373 int level,
374 typnm_t btype,
375 void *arg,
b194c7d8 376 int (*func)(struct xfs_btree_block *block,
61983f67
BN
377 xfs_agnumber_t agno,
378 xfs_agblock_t agbno,
379 int level,
380 typnm_t btype,
381 void *arg))
382{
d24c0a90
BN
383 int rval = 0;
384
61983f67
BN
385 push_cur();
386 set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb,
387 DB_RING_IGN, NULL);
388 if (iocur_top->data == NULL) {
389 print_warning("cannot read %s block %u/%u", typtab[btype].name,
390 agno, agbno);
d24c0a90
BN
391 rval = !stop_on_read_error;
392 goto pop_out;
61983f67 393 }
20f35ef4
ES
394
395 if (zero_stale_data) {
396 zero_btree_block(iocur_top->data, btype);
397 iocur_top->need_crc = 1;
398 }
399
878afc65 400 if (write_buf(iocur_top))
d24c0a90 401 goto pop_out;
61983f67
BN
402
403 if (!(*func)(iocur_top->data, agno, agbno, level - 1, btype, arg))
d24c0a90
BN
404 goto pop_out;
405 rval = 1;
406pop_out:
61983f67 407 pop_cur();
d24c0a90 408 return rval;
61983f67
BN
409}
410
411/* free space tree copy routines */
412
413static int
414valid_bno(
61983f67 415 xfs_agnumber_t agno,
88b8e1d6 416 xfs_agblock_t agbno)
61983f67 417{
88b8e1d6
BN
418 if (agno < (mp->m_sb.sb_agcount - 1) && agbno > 0 &&
419 agbno <= mp->m_sb.sb_agblocks)
420 return 1;
421 if (agno == (mp->m_sb.sb_agcount - 1) && agbno > 0 &&
422 agbno <= (mp->m_sb.sb_dblocks -
5a35bf2c 423 (xfs_rfsblock_t)(mp->m_sb.sb_agcount - 1) *
66be354e 424 mp->m_sb.sb_agblocks))
61983f67
BN
425 return 1;
426
61983f67
BN
427 return 0;
428}
429
88b8e1d6 430
61983f67
BN
431static int
432scanfunc_freesp(
b194c7d8 433 struct xfs_btree_block *block,
61983f67
BN
434 xfs_agnumber_t agno,
435 xfs_agblock_t agbno,
436 int level,
437 typnm_t btype,
438 void *arg)
439{
440 xfs_alloc_ptr_t *pp;
441 int i;
88b8e1d6 442 int numrecs;
61983f67
BN
443
444 if (level == 0)
445 return 1;
446
b194c7d8 447 numrecs = be16_to_cpu(block->bb_numrecs);
88b8e1d6 448 if (numrecs > mp->m_alloc_mxr[1]) {
61983f67 449 if (show_warnings)
88b8e1d6
BN
450 print_warning("invalid numrecs (%u) in %s block %u/%u",
451 numrecs, typtab[btype].name, agno, agbno);
61983f67
BN
452 return 1;
453 }
454
b3563c19 455 pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]);
88b8e1d6
BN
456 for (i = 0; i < numrecs; i++) {
457 if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
458 if (show_warnings)
459 print_warning("invalid block number (%u/%u) "
460 "in %s block %u/%u",
461 agno, be32_to_cpu(pp[i]),
462 typtab[btype].name, agno, agbno);
61983f67 463 continue;
88b8e1d6 464 }
61983f67
BN
465 if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg,
466 scanfunc_freesp))
467 return 0;
468 }
469 return 1;
470}
471
472static int
473copy_free_bno_btree(
474 xfs_agnumber_t agno,
475 xfs_agf_t *agf)
476{
477 xfs_agblock_t root;
478 int levels;
479
480 root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
481 levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
482
483 /* validate root and levels before processing the tree */
484 if (root == 0 || root > mp->m_sb.sb_agblocks) {
485 if (show_warnings)
486 print_warning("invalid block number (%u) in bnobt "
487 "root in agf %u", root, agno);
488 return 1;
489 }
490 if (levels >= XFS_BTREE_MAXLEVELS) {
491 if (show_warnings)
492 print_warning("invalid level (%u) in bnobt root "
493 "in agf %u", levels, agno);
494 return 1;
495 }
496
497 return scan_btree(agno, root, levels, TYP_BNOBT, agf, scanfunc_freesp);
498}
499
500static int
501copy_free_cnt_btree(
502 xfs_agnumber_t agno,
503 xfs_agf_t *agf)
504{
505 xfs_agblock_t root;
506 int levels;
507
508 root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
509 levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
510
511 /* validate root and levels before processing the tree */
512 if (root == 0 || root > mp->m_sb.sb_agblocks) {
513 if (show_warnings)
514 print_warning("invalid block number (%u) in cntbt "
515 "root in agf %u", root, agno);
516 return 1;
517 }
518 if (levels >= XFS_BTREE_MAXLEVELS) {
519 if (show_warnings)
520 print_warning("invalid level (%u) in cntbt root "
521 "in agf %u", levels, agno);
522 return 1;
523 }
524
525 return scan_btree(agno, root, levels, TYP_CNTBT, agf, scanfunc_freesp);
526}
527
e434854e
DW
528static int
529scanfunc_rmapbt(
530 struct xfs_btree_block *block,
531 xfs_agnumber_t agno,
532 xfs_agblock_t agbno,
533 int level,
534 typnm_t btype,
535 void *arg)
536{
537 xfs_rmap_ptr_t *pp;
538 int i;
539 int numrecs;
540
541 if (level == 0)
542 return 1;
543
544 numrecs = be16_to_cpu(block->bb_numrecs);
545 if (numrecs > mp->m_rmap_mxr[1]) {
546 if (show_warnings)
547 print_warning("invalid numrecs (%u) in %s block %u/%u",
548 numrecs, typtab[btype].name, agno, agbno);
549 return 1;
550 }
551
552 pp = XFS_RMAP_PTR_ADDR(block, 1, mp->m_rmap_mxr[1]);
553 for (i = 0; i < numrecs; i++) {
554 if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
555 if (show_warnings)
556 print_warning("invalid block number (%u/%u) "
557 "in %s block %u/%u",
558 agno, be32_to_cpu(pp[i]),
559 typtab[btype].name, agno, agbno);
560 continue;
561 }
562 if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg,
563 scanfunc_rmapbt))
564 return 0;
565 }
566 return 1;
567}
568
569static int
570copy_rmap_btree(
571 xfs_agnumber_t agno,
572 struct xfs_agf *agf)
573{
574 xfs_agblock_t root;
575 int levels;
576
577 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
578 return 1;
579
580 root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
581 levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
582
583 /* validate root and levels before processing the tree */
584 if (root == 0 || root > mp->m_sb.sb_agblocks) {
585 if (show_warnings)
586 print_warning("invalid block number (%u) in rmapbt "
587 "root in agf %u", root, agno);
588 return 1;
589 }
590 if (levels >= XFS_BTREE_MAXLEVELS) {
591 if (show_warnings)
592 print_warning("invalid level (%u) in rmapbt root "
593 "in agf %u", levels, agno);
594 return 1;
595 }
596
597 return scan_btree(agno, root, levels, TYP_RMAPBT, agf, scanfunc_rmapbt);
598}
599
e2756db3
DW
600static int
601scanfunc_refcntbt(
602 struct xfs_btree_block *block,
603 xfs_agnumber_t agno,
604 xfs_agblock_t agbno,
605 int level,
606 typnm_t btype,
607 void *arg)
608{
609 xfs_refcount_ptr_t *pp;
610 int i;
611 int numrecs;
612
613 if (level == 0)
614 return 1;
615
616 numrecs = be16_to_cpu(block->bb_numrecs);
617 if (numrecs > mp->m_refc_mxr[1]) {
618 if (show_warnings)
619 print_warning("invalid numrecs (%u) in %s block %u/%u",
620 numrecs, typtab[btype].name, agno, agbno);
621 return 1;
622 }
623
624 pp = XFS_REFCOUNT_PTR_ADDR(block, 1, mp->m_refc_mxr[1]);
625 for (i = 0; i < numrecs; i++) {
626 if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
627 if (show_warnings)
628 print_warning("invalid block number (%u/%u) "
629 "in %s block %u/%u",
630 agno, be32_to_cpu(pp[i]),
631 typtab[btype].name, agno, agbno);
632 continue;
633 }
634 if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg,
635 scanfunc_refcntbt))
636 return 0;
637 }
638 return 1;
639}
640
641static int
642copy_refcount_btree(
643 xfs_agnumber_t agno,
644 struct xfs_agf *agf)
645{
646 xfs_agblock_t root;
647 int levels;
648
649 if (!xfs_sb_version_hasreflink(&mp->m_sb))
650 return 1;
651
652 root = be32_to_cpu(agf->agf_refcount_root);
653 levels = be32_to_cpu(agf->agf_refcount_level);
654
655 /* validate root and levels before processing the tree */
656 if (root == 0 || root > mp->m_sb.sb_agblocks) {
657 if (show_warnings)
658 print_warning("invalid block number (%u) in refcntbt "
659 "root in agf %u", root, agno);
660 return 1;
661 }
662 if (levels >= XFS_BTREE_MAXLEVELS) {
663 if (show_warnings)
664 print_warning("invalid level (%u) in refcntbt root "
665 "in agf %u", levels, agno);
666 return 1;
667 }
668
669 return scan_btree(agno, root, levels, TYP_REFCBT, agf, scanfunc_refcntbt);
670}
671
61983f67
BN
672/* filename and extended attribute obfuscation routines */
673
78027d48 674struct name_ent {
61983f67
BN
675 struct name_ent *next;
676 xfs_dahash_t hash;
78027d48 677 int namelen;
02211695 678 unsigned char name[1];
78027d48 679};
61983f67
BN
680
681#define NAME_TABLE_SIZE 4096
682
a85f8b0a 683static struct name_ent *nametable[NAME_TABLE_SIZE];
61983f67
BN
684
685static void
a85f8b0a 686nametable_clear(void)
61983f67 687{
a85f8b0a 688 int i;
78027d48 689 struct name_ent *ent;
61983f67
BN
690
691 for (i = 0; i < NAME_TABLE_SIZE; i++) {
a85f8b0a
AE
692 while ((ent = nametable[i])) {
693 nametable[i] = ent->next;
694 free(ent);
61983f67
BN
695 }
696 }
697}
698
a85f8b0a
AE
699/*
700 * See if the given name is already in the name table. If so,
701 * return a pointer to its entry, otherwise return a null pointer.
702 */
703static struct name_ent *
02211695 704nametable_find(xfs_dahash_t hash, int namelen, unsigned char *name)
a85f8b0a
AE
705{
706 struct name_ent *ent;
707
708 for (ent = nametable[hash % NAME_TABLE_SIZE]; ent; ent = ent->next) {
709 if (ent->hash == hash && ent->namelen == namelen &&
710 !memcmp(ent->name, name, namelen))
711 return ent;
712 }
713 return NULL;
714}
715
716/*
717 * Add the given name to the name table. Returns a pointer to the
718 * name's new entry, or a null pointer if an error occurs.
719 */
720static struct name_ent *
02211695 721nametable_add(xfs_dahash_t hash, int namelen, unsigned char *name)
a85f8b0a
AE
722{
723 struct name_ent *ent;
724
725 ent = malloc(sizeof *ent + namelen);
726 if (!ent)
727 return NULL;
728
729 ent->namelen = namelen;
730 memcpy(ent->name, name, namelen);
731 ent->hash = hash;
732 ent->next = nametable[hash % NAME_TABLE_SIZE];
733
734 nametable[hash % NAME_TABLE_SIZE] = ent;
735
736 return ent;
737}
61983f67
BN
738
739#define is_invalid_char(c) ((c) == '/' || (c) == '\0')
740#define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
741
02211695 742static inline unsigned char
61983f67
BN
743random_filename_char(void)
744{
02211695 745 static unsigned char filename_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
7c3a9916
AE
746 "abcdefghijklmnopqrstuvwxyz"
747 "0123456789-_";
61983f67 748
7c3a9916 749 return filename_alphabet[random() % (sizeof filename_alphabet - 1)];
61983f67
BN
750}
751
56281ed4
AE
752#define ORPHANAGE "lost+found"
753#define ORPHANAGE_LEN (sizeof (ORPHANAGE) - 1)
754
755static inline int
756is_orphanage_dir(
757 struct xfs_mount *mp,
758 xfs_ino_t dir_ino,
759 size_t name_len,
02211695 760 unsigned char *name)
56281ed4
AE
761{
762 return dir_ino == mp->m_sb.sb_rootino &&
763 name_len == ORPHANAGE_LEN &&
764 !memcmp(name, ORPHANAGE, ORPHANAGE_LEN);
765}
766
767/*
768 * Determine whether a name is one we shouldn't obfuscate because
769 * it's an orphan (or the "lost+found" directory itself). Note
770 * "cur_ino" is the inode for the directory currently being
771 * processed.
772 *
773 * Returns 1 if the name should NOT be obfuscated or 0 otherwise.
774 */
61983f67 775static int
56281ed4 776in_lost_found(
61983f67
BN
777 xfs_ino_t ino,
778 int namelen,
02211695 779 unsigned char *name)
61983f67
BN
780{
781 static xfs_ino_t orphanage_ino = 0;
56281ed4 782 char s[24]; /* 21 is enough (64 bits in decimal) */
61983f67
BN
783 int slen;
784
56281ed4
AE
785 /* Record the "lost+found" inode if we haven't done so already */
786
787 ASSERT(ino != 0);
788 if (!orphanage_ino && is_orphanage_dir(mp, cur_ino, namelen, name))
789 orphanage_ino = ino;
790
791 /* We don't obfuscate the "lost+found" directory itself */
792
793 if (ino == orphanage_ino)
61983f67
BN
794 return 1;
795
56281ed4
AE
796 /* Most files aren't in "lost+found" at all */
797
798 if (cur_ino != orphanage_ino)
61983f67
BN
799 return 0;
800
801 /*
56281ed4
AE
802 * Within "lost+found", we don't obfuscate any file whose
803 * name is the same as its inode number. Any others are
804 * stray files and can be obfuscated.
61983f67 805 */
56281ed4 806 slen = snprintf(s, sizeof (s), "%llu", (unsigned long long) ino);
61983f67 807
56281ed4 808 return slen == namelen && !memcmp(name, s, namelen);
61983f67
BN
809}
810
da7daaf2
AE
811/*
812 * Given a name and its hash value, massage the name in such a way
813 * that the result is another name of equal length which shares the
814 * same hash value.
815 */
61983f67 816static void
da7daaf2
AE
817obfuscate_name(
818 xfs_dahash_t hash,
819 size_t name_len,
02211695 820 unsigned char *name)
61983f67 821{
02211695 822 unsigned char *newp = name;
da7daaf2
AE
823 int i;
824 xfs_dahash_t new_hash = 0;
02211695
CH
825 unsigned char *first;
826 unsigned char high_bit;
da7daaf2 827 int shift;
61983f67 828
56281ed4
AE
829 /*
830 * Our obfuscation algorithm requires at least 5-character
831 * names, so don't bother if the name is too short. We
832 * work backward from a hash value to determine the last
833 * five bytes in a name required to produce a new name
834 * with the same hash.
835 */
da7daaf2 836 if (name_len < 5)
61983f67
BN
837 return;
838
da7daaf2
AE
839 /*
840 * The beginning of the obfuscated name can be pretty much
841 * anything, so fill it in with random characters.
842 * Accumulate its new hash value as we go.
843 */
844 for (i = 0; i < name_len - 5; i++) {
845 *newp = random_filename_char();
846 new_hash = *newp ^ rol32(new_hash, 7);
847 newp++;
848 }
849
850 /*
851 * Compute which five bytes need to be used at the end of
852 * the name so the hash of the obfuscated name is the same
853 * as the hash of the original. If any result in an invalid
854 * character, flip a bit and arrange for a corresponding bit
855 * in a neighboring byte to be flipped as well. For the
856 * last byte, the "neighbor" to change is the first byte
857 * we're computing here.
858 */
859 new_hash = rol32(new_hash, 3) ^ hash;
860
861 first = newp;
862 high_bit = 0;
863 for (shift = 28; shift >= 0; shift -= 7) {
864 *newp = (new_hash >> shift & 0x7f) ^ high_bit;
865 if (is_invalid_char(*newp)) {
866 *newp ^= 1;
867 high_bit = 0x80;
868 } else
869 high_bit = 0;
870 ASSERT(!is_invalid_char(*newp));
871 newp++;
872 }
873
874 /*
875 * If we flipped a bit on the last byte, we need to fix up
876 * the matching bit in the first byte. The result will
877 * be a valid character, because we know that first byte
878 * has 0's in its upper four bits (it was produced by a
879 * 28-bit right-shift of a 32-bit unsigned value).
880 */
881 if (high_bit) {
882 *first ^= 0x10;
883 ASSERT(!is_invalid_char(*first));
884 }
002c6e02 885 ASSERT(libxfs_da_hashname(name, name_len) == hash);
da7daaf2
AE
886}
887
1167ddc4
AE
888/*
889 * Flip a bit in each of two bytes at the end of the given name.
890 * This is used in generating a series of alternate names to be used
891 * in the event a duplicate is found.
892 *
893 * The bits flipped are selected such that they both affect the same
894 * bit in the name's computed hash value, so flipping them both will
895 * preserve the hash.
896 *
897 * The following diagram aims to show the portion of a computed
898 * hash that a given byte of a name affects.
899 *
900 * 31 28 24 21 14 8 7 3 0
901 * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
902 * hash: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
903 * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
904 * last-4 ->| |<-- last-2 --->| |<--- last ---->|
905 * |<-- last-3 --->| |<-- last-1 --->| |<- last-4
906 * |<-- last-7 --->| |<-- last-5 --->|
907 * |<-- last-8 --->| |<-- last-6 --->|
908 * . . . and so on
909 *
910 * The last byte of the name directly affects the low-order byte of
911 * the hash. The next-to-last affects bits 7-14, the next one back
912 * affects bits 14-21, and so on. The effect wraps around when it
913 * goes beyond the top of the hash (as happens for byte last-4).
914 *
915 * Bits that are flipped together "overlap" on the hash value. As
916 * an example of overlap, the last two bytes both affect bit 7 in
917 * the hash. That pair of bytes (and their overlapping bits) can be
918 * used for this "flip bit" operation (it's the first pair tried,
919 * actually).
920 *
921 * A table defines overlapping pairs--the bytes involved and bits
922 * within them--that can be used this way. The byte offset is
923 * relative to a starting point within the name, which will be set
924 * to affect the bytes at the end of the name. The function is
925 * called with a "bitseq" value which indicates which bit flip is
926 * desired, and this translates directly into selecting which entry
927 * in the bit_to_flip[] table to apply.
928 *
929 * The function returns 1 if the operation was successful. It
930 * returns 0 if the result produced a character that's not valid in
931 * a name (either '/' or a '\0'). Finally, it returns -1 if the bit
932 * sequence number is beyond what is supported for a name of this
933 * length.
934 *
935 * Discussion
936 * ----------
937 * (Also see the discussion above find_alternate(), below.)
938 *
939 * In order to make this function work for any length name, the
940 * table is ordered by increasing byte offset, so that the earliest
941 * entries can apply to the shortest strings. This way all names
942 * are done consistently.
943 *
944 * When bit flips occur, they can convert printable characters
945 * into non-printable ones. In an effort to reduce the impact of
946 * this, the first bit flips are chosen to affect bytes the end of
947 * the name (and furthermore, toward the low bits of a byte). Those
948 * bytes are often non-printable anyway because of the way they are
949 * initially selected by obfuscate_name()). This is accomplished,
950 * using later table entries first.
951 *
952 * Each row in the table doubles the number of alternates that
953 * can be generated. A two-byte name is limited to using only
954 * the first row, so it's possible to generate two alternates
955 * (the original name, plus the alternate produced by flipping
956 * the one pair of bits). In a 5-byte name, the effect of the
957 * first byte overlaps the last by 4 its, and there are 8 bits
958 * to flip, allowing for 256 possible alternates.
959 *
960 * Short names (less than 5 bytes) are never even obfuscated, so for
961 * such names the relatively small number of alternates should never
962 * really be a problem.
963 *
964 * Long names (more than 6 bytes, say) are not likely to exhaust
965 * the number of available alternates. In fact, the table could
966 * probably have stopped at 8 entries, on the assumption that 256
967 * alternates should be enough for most any situation. The entries
968 * beyond those are present mostly for demonstration of how it could
969 * be populated with more entries, should it ever be necessary to do
970 * so.
971 */
972static int
973flip_bit(
974 size_t name_len,
02211695 975 unsigned char *name,
1167ddc4
AE
976 uint32_t bitseq)
977{
978 int index;
979 size_t offset;
02211695
CH
980 unsigned char *p0, *p1;
981 unsigned char m0, m1;
1167ddc4
AE
982 struct {
983 int byte; /* Offset from start within name */
02211695 984 unsigned char bit; /* Bit within that byte */
1167ddc4
AE
985 } bit_to_flip[][2] = { /* Sorted by second entry's byte */
986 { { 0, 0 }, { 1, 7 } }, /* Each row defines a pair */
987 { { 1, 0 }, { 2, 7 } }, /* of bytes and a bit within */
988 { { 2, 0 }, { 3, 7 } }, /* each byte. Each bit in */
989 { { 0, 4 }, { 4, 0 } }, /* a pair affects the same */
990 { { 0, 5 }, { 4, 1 } }, /* bit in the hash, so flipping */
991 { { 0, 6 }, { 4, 2 } }, /* both will change the name */
992 { { 0, 7 }, { 4, 3 } }, /* while preserving the hash. */
993 { { 3, 0 }, { 4, 7 } },
994 { { 0, 0 }, { 5, 3 } }, /* The first entry's byte offset */
995 { { 0, 1 }, { 5, 4 } }, /* must be less than the second. */
996 { { 0, 2 }, { 5, 5 } },
997 { { 0, 3 }, { 5, 6 } }, /* The table can be extended to */
998 { { 0, 4 }, { 5, 7 } }, /* an arbitrary number of entries */
999 { { 4, 0 }, { 5, 7 } }, /* but there's not much point. */
1000 /* . . . */
1001 };
1002
1003 /* Find the first entry *not* usable for name of this length */
1004
1005 for (index = 0; index < ARRAY_SIZE(bit_to_flip); index++)
1006 if (bit_to_flip[index][1].byte >= name_len)
1007 break;
1008
1009 /*
1010 * Back up to the last usable entry. If that number is
1011 * smaller than the bit sequence number, inform the caller
1012 * that nothing this large (or larger) will work.
1013 */
1014 if (bitseq > --index)
1015 return -1;
1016
1017 /*
1018 * We will be switching bits at the end of name, with a
1019 * preference for affecting the last bytes first. Compute
1020 * where in the name we'll start applying the changes.
1021 */
1022 offset = name_len - (bit_to_flip[index][1].byte + 1);
1023 index -= bitseq; /* Use later table entries first */
1024
1025 p0 = name + offset + bit_to_flip[index][0].byte;
1026 p1 = name + offset + bit_to_flip[index][1].byte;
1027 m0 = 1 << bit_to_flip[index][0].bit;
1028 m1 = 1 << bit_to_flip[index][1].bit;
1029
1030 /* Only change the bytes if it produces valid characters */
1031
1032 if (is_invalid_char(*p0 ^ m0) || is_invalid_char(*p1 ^ m1))
1033 return 0;
1034
1035 *p0 ^= m0;
1036 *p1 ^= m1;
1037
1038 return 1;
1039}
1040
1041/*
1042 * This function generates a well-defined sequence of "alternate"
1043 * names for a given name. An alternate is a name having the same
1044 * length and same hash value as the original name. This is needed
1045 * because the algorithm produces only one obfuscated name to use
1046 * for a given original name, and it's possible that result matches
1047 * a name already seen. This function checks for this, and if it
1048 * occurs, finds another suitable obfuscated name to use.
1049 *
1050 * Each bit in the binary representation of the sequence number is
1051 * used to select one possible "bit flip" operation to perform on
1052 * the name. So for example:
1053 * seq = 0: selects no bits to flip
1054 * seq = 1: selects the 0th bit to flip
1055 * seq = 2: selects the 1st bit to flip
1056 * seq = 3: selects the 0th and 1st bit to flip
1057 * ... and so on.
1058 *
1059 * The flip_bit() function takes care of the details of the bit
1060 * flipping within the name. Note that the "1st bit" in this
1061 * context is a bit sequence number; i.e. it doesn't necessarily
1062 * mean bit 0x02 will be changed.
1063 *
1064 * If a valid name (one that contains no '/' or '\0' characters) is
1065 * produced by this process for the given sequence number, this
1066 * function returns 1. If the result is not valid, it returns 0.
1067 * Returns -1 if the sequence number is beyond the the maximum for
1068 * names of the given length.
1069 *
1070 *
1071 * Discussion
1072 * ----------
1073 * The number of alternates available for a given name is dependent
1074 * on its length. A "bit flip" involves inverting two bits in
1075 * a name--the two bits being selected such that their values
1076 * affect the name's hash value in the same way. Alternates are
1077 * thus generated by inverting the value of pairs of such
1078 * "overlapping" bits in the original name. Each byte after the
1079 * first in a name adds at least one bit of overlap to work with.
1080 * (See comments above flip_bit() for more discussion on this.)
1081 *
1082 * So the number of alternates is dependent on the number of such
1083 * overlapping bits in a name. If there are N bit overlaps, there
1084 * 2^N alternates for that hash value.
1085 *
1086 * Here are the number of overlapping bits available for generating
1087 * alternates for names of specific lengths:
1088 * 1 0 (must have 2 bytes to have any overlap)
1089 * 2 1 One bit overlaps--so 2 possible alternates
1090 * 3 2 Two bits overlap--so 4 possible alternates
1091 * 4 4 Three bits overlap, so 2^3 alternates
1092 * 5 8 8 bits overlap (due to wrapping), 256 alternates
1093 * 6 18 2^18 alternates
1094 * 7 28 2^28 alternates
1095 * ...
1096 * It's clear that the number of alternates grows very quickly with
1097 * the length of the name. But note that the set of alternates
1098 * includes invalid names. And for certain (contrived) names, the
1099 * number of valid names is a fairly small fraction of the total
1100 * number of alternates.
1101 *
1102 * The main driver for this infrastructure for coming up with
1103 * alternate names is really related to names 5 (or possibly 6)
1104 * bytes in length. 5-byte obfuscated names contain no randomly-
1105 * generated bytes in them, and the chance of an obfuscated name
1106 * matching an already-seen name is too high to just ignore. This
1107 * methodical selection of alternates ensures we don't produce
1108 * duplicate names unless we have exhausted our options.
1109 */
1110static int
1111find_alternate(
1112 size_t name_len,
02211695 1113 unsigned char *name,
1167ddc4
AE
1114 uint32_t seq)
1115{
1116 uint32_t bitseq = 0;
1117 uint32_t bits = seq;
1118
1119 if (!seq)
1120 return 1; /* alternate 0 is the original name */
1121 if (name_len < 2) /* Must have 2 bytes to flip */
1122 return -1;
1123
1124 for (bitseq = 0; bits; bitseq++) {
1125 uint32_t mask = 1 << bitseq;
1126 int fb;
1127
1128 if (!(bits & mask))
1129 continue;
1130
1131 fb = flip_bit(name_len, name, bitseq);
1132 if (fb < 1)
1133 return fb ? -1 : 0;
1134 bits ^= mask;
1135 }
1136
1137 return 1;
1138}
1139
fcb63670
AE
1140/*
1141 * Look up the given name in the name table. If it is already
1167ddc4
AE
1142 * present, iterate through a well-defined sequence of alternate
1143 * names and attempt to use an alternate name instead.
fcb63670
AE
1144 *
1145 * Returns 1 if the (possibly modified) name is not present in the
1167ddc4
AE
1146 * name table. Returns 0 if the name and all possible alternates
1147 * are already in the table.
fcb63670
AE
1148 */
1149static int
02211695 1150handle_duplicate_name(xfs_dahash_t hash, size_t name_len, unsigned char *name)
fcb63670 1151{
02211695 1152 unsigned char new_name[name_len + 1];
1167ddc4 1153 uint32_t seq = 1;
fcb63670
AE
1154
1155 if (!nametable_find(hash, name_len, name))
1167ddc4 1156 return 1; /* No duplicate */
fcb63670
AE
1157
1158 /* Name is already in use. Need to find an alternate. */
1159
1160 do {
1167ddc4 1161 int found;
fcb63670 1162
1167ddc4
AE
1163 /* Only change incoming name if we find an alternate */
1164 do {
1165 memcpy(new_name, name, name_len);
1166 found = find_alternate(name_len, new_name, seq++);
1167 if (found < 0)
1168 return 0; /* No more to check */
1169 } while (!found);
1170 } while (nametable_find(hash, name_len, new_name));
fcb63670 1171
1167ddc4
AE
1172 /*
1173 * The alternate wasn't in the table already. Pass it back
1174 * to the caller.
1175 */
1176 memcpy(name, new_name, name_len);
1177
1178 return 1;
fcb63670
AE
1179}
1180
da7daaf2
AE
1181static void
1182generate_obfuscated_name(
1183 xfs_ino_t ino,
1184 int namelen,
02211695 1185 unsigned char *name)
da7daaf2
AE
1186{
1187 xfs_dahash_t hash;
da7daaf2 1188
56281ed4
AE
1189 /*
1190 * We don't obfuscate "lost+found" or any orphan files
1191 * therein. When the name table is used for extended
1192 * attributes, the inode number provided is 0, in which
1193 * case we don't need to make this check.
1194 */
1195 if (ino && in_lost_found(ino, namelen, name))
1196 return;
61983f67 1197
ad6bb839 1198 /*
fcb63670
AE
1199 * If the name starts with a slash, just skip over it. It
1200 * isn't included in the hash and we don't record it in the
1201 * name table. Note that the namelen value passed in does
1202 * not count the leading slash (if one is present).
ad6bb839
AE
1203 */
1204 if (*name == '/')
1205 name++;
61983f67 1206
fcb63670 1207 /* Obfuscate the name (if possible) */
61983f67 1208
fcb63670
AE
1209 hash = libxfs_da_hashname(name, namelen);
1210 obfuscate_name(hash, namelen, name);
88b1fe2a
AE
1211
1212 /*
fcb63670
AE
1213 * Make sure the name is not something already seen. If we
1214 * fail to find a suitable alternate, we're dealing with a
1215 * very pathological situation, and we may end up creating
1216 * a duplicate name in the metadump, so issue a warning.
88b1fe2a 1217 */
fcb63670 1218 if (!handle_duplicate_name(hash, namelen, name)) {
88b1fe2a
AE
1219 print_warning("duplicate name for inode %llu "
1220 "in dir inode %llu\n",
1221 (unsigned long long) ino,
1222 (unsigned long long) cur_ino);
fcb63670
AE
1223 return;
1224 }
1225
1226 /* Create an entry for the new name in the name table. */
61983f67 1227
a85f8b0a
AE
1228 if (!nametable_add(hash, namelen, name))
1229 print_warning("unable to record name for inode %llu "
1230 "in dir inode %llu\n",
1231 (unsigned long long) ino,
1232 (unsigned long long) cur_ino);
61983f67
BN
1233}
1234
1235static void
87c955c3 1236process_sf_dir(
61983f67
BN
1237 xfs_dinode_t *dip)
1238{
eb0cb950 1239 struct xfs_dir2_sf_hdr *sfp;
61983f67 1240 xfs_dir2_sf_entry_t *sfep;
14f8b681 1241 uint64_t ino_dir_size;
61983f67
BN
1242 int i;
1243
eb0cb950 1244 sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
56b2de80 1245 ino_dir_size = be64_to_cpu(dip->di_size);
61983f67
BN
1246 if (ino_dir_size > XFS_DFORK_DSIZE(dip, mp)) {
1247 ino_dir_size = XFS_DFORK_DSIZE(dip, mp);
1248 if (show_warnings)
88b8e1d6 1249 print_warning("invalid size in dir inode %llu",
61983f67
BN
1250 (long long)cur_ino);
1251 }
1252
eb0cb950
DC
1253 sfep = xfs_dir2_sf_firstentry(sfp);
1254 for (i = 0; (i < sfp->count) &&
61983f67
BN
1255 ((char *)sfep - (char *)sfp < ino_dir_size); i++) {
1256
1257 /*
1258 * first check for bad name lengths. If they are bad, we
1259 * have limitations to how much can be obfuscated.
1260 */
1261 int namelen = sfep->namelen;
1262
1263 if (namelen == 0) {
1264 if (show_warnings)
1265 print_warning("zero length entry in dir inode "
1266 "%llu", (long long)cur_ino);
eb0cb950 1267 if (i != sfp->count - 1)
61983f67
BN
1268 break;
1269 namelen = ino_dir_size - ((char *)&sfep->name[0] -
1270 (char *)sfp);
1271 } else if ((char *)sfep - (char *)sfp +
660836c9 1272 libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen) >
61983f67
BN
1273 ino_dir_size) {
1274 if (show_warnings)
1275 print_warning("entry length in dir inode %llu "
1276 "overflows space", (long long)cur_ino);
eb0cb950 1277 if (i != sfp->count - 1)
61983f67
BN
1278 break;
1279 namelen = ino_dir_size - ((char *)&sfep->name[0] -
1280 (char *)sfp);
1281 }
1282
87c955c3
ES
1283 if (obfuscate)
1284 generate_obfuscated_name(
e96bd2d3 1285 libxfs_dir2_sf_get_ino(mp, sfp, sfep),
a2ceac1f 1286 namelen, &sfep->name[0]);
61983f67
BN
1287
1288 sfep = (xfs_dir2_sf_entry_t *)((char *)sfep +
660836c9 1289 libxfs_dir2_sf_entsize(mp, sfp, namelen));
61983f67 1290 }
87c955c3
ES
1291
1292 /* zero stale data in rest of space in data fork, if any */
1293 if (zero_stale_data && (ino_dir_size < XFS_DFORK_DSIZE(dip, mp)))
1294 memset(sfep, 0, XFS_DFORK_DSIZE(dip, mp) - ino_dir_size);
61983f67
BN
1295}
1296
f63c7540
DC
1297/*
1298 * The pathname may not be null terminated. It may be terminated by the end of
1299 * a buffer or inode literal area, and the start of the next region contains
1300 * unknown data. Therefore, when we get to the last component of the symlink, we
1301 * cannot assume that strlen() will give us the right result. Hence we need to
1302 * track the remaining pathname length and use that instead.
1303 */
b249a9f0
ES
1304static void
1305obfuscate_path_components(
1306 char *buf,
14f8b681 1307 uint64_t len)
b249a9f0 1308{
02211695
CH
1309 unsigned char *comp = (unsigned char *)buf;
1310 unsigned char *end = comp + len;
b249a9f0
ES
1311 xfs_dahash_t hash;
1312
f63c7540 1313 while (comp < end) {
b249a9f0
ES
1314 char *slash;
1315 int namelen;
1316
1317 /* find slash at end of this component */
1318 slash = strchr((char *)comp, '/');
1319 if (!slash) {
1320 /* last (or single) component */
f63c7540 1321 namelen = strnlen((char *)comp, len);
b249a9f0
ES
1322 hash = libxfs_da_hashname(comp, namelen);
1323 obfuscate_name(hash, namelen, comp);
1324 break;
1325 }
1326 namelen = slash - (char *)comp;
1327 /* handle leading or consecutive slashes */
1328 if (!namelen) {
1329 comp++;
f63c7540 1330 len--;
b249a9f0
ES
1331 continue;
1332 }
1333 hash = libxfs_da_hashname(comp, namelen);
1334 obfuscate_name(hash, namelen, comp);
1335 comp += namelen + 1;
f63c7540 1336 len -= namelen + 1;
b249a9f0
ES
1337 }
1338}
1339
61983f67 1340static void
87c955c3 1341process_sf_symlink(
61983f67
BN
1342 xfs_dinode_t *dip)
1343{
14f8b681 1344 uint64_t len;
56b2de80 1345 char *buf;
88b8e1d6 1346
56b2de80 1347 len = be64_to_cpu(dip->di_size);
88b8e1d6
BN
1348 if (len > XFS_DFORK_DSIZE(dip, mp)) {
1349 if (show_warnings)
1350 print_warning("invalid size (%d) in symlink inode %llu",
1351 len, (long long)cur_ino);
1352 len = XFS_DFORK_DSIZE(dip, mp);
1353 }
61983f67 1354
56b2de80 1355 buf = (char *)XFS_DFORK_DPTR(dip);
87c955c3
ES
1356 if (obfuscate)
1357 obfuscate_path_components(buf, len);
1358
1359 /* zero stale data in rest of space in data fork, if any */
1360 if (zero_stale_data && len < XFS_DFORK_DSIZE(dip, mp))
1361 memset(&buf[len], 0, XFS_DFORK_DSIZE(dip, mp) - len);
61983f67
BN
1362}
1363
1364static void
87c955c3 1365process_sf_attr(
61983f67
BN
1366 xfs_dinode_t *dip)
1367{
1368 /*
1941482c
ES
1369 * with extended attributes, obfuscate the names and fill the actual
1370 * values with 'v' (to see a valid string length, as opposed to NULLs)
61983f67
BN
1371 */
1372
1373 xfs_attr_shortform_t *asfp;
1374 xfs_attr_sf_entry_t *asfep;
1375 int ino_attr_size;
1376 int i;
1377
1378 asfp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
1379 if (asfp->hdr.count == 0)
1380 return;
1381
1382 ino_attr_size = be16_to_cpu(asfp->hdr.totsize);
1383 if (ino_attr_size > XFS_DFORK_ASIZE(dip, mp)) {
1384 ino_attr_size = XFS_DFORK_ASIZE(dip, mp);
1385 if (show_warnings)
1386 print_warning("invalid attr size in inode %llu",
1387 (long long)cur_ino);
1388 }
1389
1390 asfep = &asfp->list[0];
1391 for (i = 0; (i < asfp->hdr.count) &&
1392 ((char *)asfep - (char *)asfp < ino_attr_size); i++) {
1393
1394 int namelen = asfep->namelen;
1395
1396 if (namelen == 0) {
1397 if (show_warnings)
1398 print_warning("zero length attr entry in inode "
1399 "%llu", (long long)cur_ino);
1400 break;
1401 } else if ((char *)asfep - (char *)asfp +
1402 XFS_ATTR_SF_ENTSIZE(asfep) > ino_attr_size) {
1403 if (show_warnings)
1404 print_warning("attr entry length in inode %llu "
1405 "overflows space", (long long)cur_ino);
1406 break;
1407 }
1408
87c955c3
ES
1409 if (obfuscate) {
1410 generate_obfuscated_name(0, asfep->namelen,
1411 &asfep->nameval[0]);
1412 memset(&asfep->nameval[asfep->namelen], 'v',
1413 asfep->valuelen);
1414 }
61983f67
BN
1415
1416 asfep = (xfs_attr_sf_entry_t *)((char *)asfep +
1417 XFS_ATTR_SF_ENTSIZE(asfep));
1418 }
87c955c3
ES
1419
1420 /* zero stale data in rest of space in attr fork, if any */
1421 if (zero_stale_data && (ino_attr_size < XFS_DFORK_ASIZE(dip, mp)))
1422 memset(asfep, 0, XFS_DFORK_ASIZE(dip, mp) - ino_attr_size);
61983f67
BN
1423}
1424
c3387ef7
SR
1425static void
1426process_dir_free_block(
1427 char *block)
1428{
1429 struct xfs_dir2_free *free;
1430 struct xfs_dir3_icfree_hdr freehdr;
1431
1432 if (!zero_stale_data)
1433 return;
1434
1435 free = (struct xfs_dir2_free *)block;
61e2142e 1436 libxfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
c3387ef7
SR
1437
1438 switch (freehdr.magic) {
1439 case XFS_DIR2_FREE_MAGIC:
1440 case XFS_DIR3_FREE_MAGIC: {
1441 __be16 *bests;
1442 char *high;
1443 int used;
1444
1445 /* Zero out space from end of bests[] to end of block */
cb5d1930 1446 bests = freehdr.bests;
c3387ef7
SR
1447 high = (char *)&bests[freehdr.nvalid];
1448 used = high - (char*)free;
1449 memset(high, 0, mp->m_dir_geo->blksize - used);
1450 iocur_top->need_crc = 1;
1451 break;
1452 }
1453 default:
1454 if (show_warnings)
1455 print_warning("invalid magic in dir inode %llu "
1456 "free block",
1457 (unsigned long long)cur_ino);
1458 break;
1459 }
1460}
1461
a56173b5
ES
1462static void
1463process_dir_leaf_block(
1464 char *block)
1465{
1466 struct xfs_dir2_leaf *leaf;
11f3d9ff 1467 struct xfs_dir3_icleaf_hdr leafhdr;
a56173b5
ES
1468
1469 if (!zero_stale_data)
1470 return;
1471
1472 /* Yes, this works for dir2 & dir3. Difference is padding. */
1473 leaf = (struct xfs_dir2_leaf *)block;
9db68faf 1474 libxfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
a56173b5 1475
11f3d9ff
SR
1476 switch (leafhdr.magic) {
1477 case XFS_DIR2_LEAF1_MAGIC:
1478 case XFS_DIR3_LEAF1_MAGIC: {
a56173b5
ES
1479 struct xfs_dir2_leaf_tail *ltp;
1480 __be16 *lbp;
a56173b5
ES
1481 char *free; /* end of ents */
1482
11f3d9ff 1483 /* Zero out space from end of ents[] to bests */
a2279497 1484 free = (char *)&leafhdr.ents[leafhdr.count];
a56173b5
ES
1485 ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
1486 lbp = xfs_dir2_leaf_bests_p(ltp);
1487 memset(free, 0, (char *)lbp - free);
1488 iocur_top->need_crc = 1;
11f3d9ff
SR
1489 break;
1490 }
1491 case XFS_DIR2_LEAFN_MAGIC:
1492 case XFS_DIR3_LEAFN_MAGIC: {
11f3d9ff
SR
1493 char *free;
1494 int used;
1495
1496 /* Zero out space from end of ents[] to end of block */
a2279497 1497 free = (char *)&leafhdr.ents[leafhdr.count];
11f3d9ff
SR
1498 used = free - (char*)leaf;
1499 memset(free, 0, mp->m_dir_geo->blksize - used);
1500 iocur_top->need_crc = 1;
1501 break;
1502 }
1503 default:
1504 break;
a56173b5
ES
1505 }
1506}
1507
61983f67 1508static void
6d34e8b3 1509process_dir_data_block(
6e79202b 1510 char *block,
5a35bf2c 1511 xfs_fileoff_t offset,
6e79202b 1512 int is_block_format)
61983f67
BN
1513{
1514 /*
1515 * we have to rely on the fileoffset and signature of the block to
1516 * handle it's contents. If it's invalid, leave it alone.
1517 * for multi-fsblock dir blocks, if a name crosses an extent boundary,
1518 * ignore it and continue.
1519 */
6e79202b
DC
1520 int dir_offset;
1521 char *ptr;
1522 char *endptr;
1523 int end_of_data;
1524 int wantmagic;
1525 struct xfs_dir2_data_hdr *datahdr;
1526
1527 datahdr = (struct xfs_dir2_data_hdr *)block;
1528
6e79202b
DC
1529 if (is_block_format) {
1530 xfs_dir2_leaf_entry_t *blp;
1531 xfs_dir2_block_tail_t *btp;
1532
ff105f75 1533 btp = xfs_dir2_block_tail_p(mp->m_dir_geo, datahdr);
6e79202b
DC
1534 blp = xfs_dir2_block_leaf_p(btp);
1535 if ((char *)blp > (char *)btp)
1536 blp = (xfs_dir2_leaf_entry_t *)btp;
1537
1538 end_of_data = (char *)blp - block;
1539 if (xfs_sb_version_hascrc(&mp->m_sb))
1540 wantmagic = XFS_DIR3_BLOCK_MAGIC;
1541 else
1542 wantmagic = XFS_DIR2_BLOCK_MAGIC;
1543 } else { /* leaf/node format */
ff105f75 1544 end_of_data = mp->m_dir_geo->fsbcount << mp->m_sb.sb_blocklog;
6e79202b
DC
1545 if (xfs_sb_version_hascrc(&mp->m_sb))
1546 wantmagic = XFS_DIR3_DATA_MAGIC;
1547 else
1548 wantmagic = XFS_DIR2_DATA_MAGIC;
1549 }
61983f67 1550
6e79202b
DC
1551 if (be32_to_cpu(datahdr->magic) != wantmagic) {
1552 if (show_warnings)
1553 print_warning(
1554 "invalid magic in dir inode %llu block %ld",
c3387ef7 1555 (unsigned long long)cur_ino, (long)offset);
6e79202b
DC
1556 return;
1557 }
61983f67 1558
9c036d76 1559 dir_offset = mp->m_dir_inode_ops->data_entry_offset;
6e79202b 1560 ptr = block + dir_offset;
ff105f75 1561 endptr = block + mp->m_dir_geo->blksize;
61983f67 1562
6e79202b
DC
1563 while (ptr < endptr && dir_offset < end_of_data) {
1564 xfs_dir2_data_entry_t *dep;
1565 xfs_dir2_data_unused_t *dup;
1566 int length;
61983f67 1567
6e79202b 1568 dup = (xfs_dir2_data_unused_t *)ptr;
61983f67 1569
6e79202b 1570 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
8ab6f7e0
ES
1571 int free_length = be16_to_cpu(dup->length);
1572 if (dir_offset + free_length > end_of_data ||
1573 !free_length ||
1574 (free_length & (XFS_DIR2_DATA_ALIGN - 1))) {
61983f67 1575 if (show_warnings)
6e79202b
DC
1576 print_warning(
1577 "invalid length for dir free space in inode %llu",
61983f67 1578 (long long)cur_ino);
6e79202b 1579 return;
61983f67 1580 }
6e79202b
DC
1581 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
1582 dir_offset)
1583 return;
8ab6f7e0
ES
1584 dir_offset += free_length;
1585 ptr += free_length;
6d34e8b3
ES
1586 /*
1587 * Zero the unused space up to the tag - the tag is
1588 * actually at a variable offset, so zeroing &dup->tag
1589 * is zeroing the free space in between
1590 */
1591 if (zero_stale_data) {
8ab6f7e0 1592 int zlen = free_length -
6d34e8b3
ES
1593 sizeof(xfs_dir2_data_unused_t);
1594
1595 if (zlen > 0) {
1596 memset(&dup->tag, 0, zlen);
1597 iocur_top->need_crc = 1;
1598 }
1599 }
6e79202b
DC
1600 if (dir_offset >= end_of_data || ptr >= endptr)
1601 return;
1602 }
1603
1604 dep = (xfs_dir2_data_entry_t *)ptr;
ff105f75 1605 length = M_DIROPS(mp)->data_entsize(dep->namelen);
6e79202b
DC
1606
1607 if (dir_offset + length > end_of_data ||
1608 ptr + length > endptr) {
1609 if (show_warnings)
1610 print_warning(
1611 "invalid length for dir entry name in inode %llu",
1612 (long long)cur_ino);
1613 return;
61983f67 1614 }
ff105f75 1615 if (be16_to_cpu(*M_DIROPS(mp)->data_entry_tag_p(dep)) !=
6e79202b
DC
1616 dir_offset)
1617 return;
6d34e8b3
ES
1618
1619 if (obfuscate)
1620 generate_obfuscated_name(be64_to_cpu(dep->inumber),
6e79202b
DC
1621 dep->namelen, &dep->name[0]);
1622 dir_offset += length;
1623 ptr += length;
6d34e8b3
ES
1624 /* Zero the unused space after name, up to the tag */
1625 if (zero_stale_data) {
1626 /* 1 byte for ftype; don't bother with conditional */
1627 int zlen =
ff105f75 1628 (char *)M_DIROPS(mp)->data_entry_tag_p(dep) -
6d34e8b3
ES
1629 (char *)&dep->name[dep->namelen] - 1;
1630 if (zlen > 0) {
1631 memset(&dep->name[dep->namelen] + 1, 0, zlen);
1632 iocur_top->need_crc = 1;
1633 }
1634 }
61983f67
BN
1635 }
1636}
1637
0e81250e 1638static int
23b2ae23 1639process_symlink_block(
0e81250e
DW
1640 xfs_fileoff_t o,
1641 xfs_fsblock_t s,
1642 xfs_filblks_t c,
1643 typnm_t btype,
1644 xfs_fileoff_t last)
61983f67 1645{
0e81250e
DW
1646 struct bbmap map;
1647 char *link;
1648 int ret = 0;
1649
1650 push_cur();
1651 map.nmaps = 1;
1652 map.b[0].bm_bn = XFS_FSB_TO_DADDR(mp, s);
1653 map.b[0].bm_len = XFS_FSB_TO_BB(mp, c);
1654 set_cur(&typtab[btype], 0, 0, DB_RING_IGN, &map);
1655 if (!iocur_top->data) {
1656 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, s);
1657 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, s);
1658
1659 print_warning("cannot read %s block %u/%u (%llu)",
1660 typtab[btype].name, agno, agbno, s);
1661 if (stop_on_read_error)
1662 ret = -1;
1663 goto out_pop;
1664 }
1665 link = iocur_top->data;
23b2ae23 1666
80917c1a 1667 if (xfs_sb_version_hascrc(&(mp)->m_sb))
23b2ae23
ES
1668 link += sizeof(struct xfs_dsymlink_hdr);
1669
1670 if (obfuscate)
1671 obfuscate_path_components(link, XFS_SYMLINK_BUF_SPACE(mp,
1672 mp->m_sb.sb_blocksize));
1673 if (zero_stale_data) {
1674 size_t linklen, zlen;
80917c1a 1675
23b2ae23
ES
1676 linklen = strlen(link);
1677 zlen = mp->m_sb.sb_blocksize - linklen;
1678 if (xfs_sb_version_hascrc(&mp->m_sb))
1679 zlen -= sizeof(struct xfs_dsymlink_hdr);
1680 if (zlen < mp->m_sb.sb_blocksize)
1681 memset(link + linklen, 0, zlen);
1682 }
0e81250e
DW
1683
1684 iocur_top->need_crc = 1;
1685 ret = write_buf(iocur_top);
1686out_pop:
1687 pop_cur();
1688 return ret;
61983f67
BN
1689}
1690
1691#define MAX_REMOTE_VALS 4095
1692
1693static struct attr_data_s {
1694 int remote_val_count;
1695 xfs_dablk_t remote_vals[MAX_REMOTE_VALS];
1696} attr_data;
1697
1698static inline void
1699add_remote_vals(
1700 xfs_dablk_t blockidx,
1701 int length)
1702{
1703 while (length > 0 && attr_data.remote_val_count < MAX_REMOTE_VALS) {
1704 attr_data.remote_vals[attr_data.remote_val_count] = blockidx;
1705 attr_data.remote_val_count++;
1706 blockidx++;
e66eae01 1707 length -= XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
61983f67 1708 }
ed737480
DC
1709
1710 if (attr_data.remote_val_count >= MAX_REMOTE_VALS) {
1711 print_warning(
1712"Overflowed attr obfuscation array. No longer obfuscating remote attrs.");
1713 }
61983f67
BN
1714}
1715
80853366 1716/* Handle remote and leaf attributes */
61983f67 1717static void
70099c89 1718process_attr_block(
80853366
ES
1719 char *block,
1720 xfs_fileoff_t offset)
61983f67 1721{
80853366
ES
1722 struct xfs_attr_leafblock *leaf;
1723 struct xfs_attr3_icleaf_hdr hdr;
1724 int i;
1725 int nentries;
1726 xfs_attr_leaf_entry_t *entry;
1727 xfs_attr_leaf_name_local_t *local;
1728 xfs_attr_leaf_name_remote_t *remote;
14f8b681 1729 uint32_t bs = mp->m_sb.sb_blocksize;
70099c89 1730 char *first_name;
80853366 1731
61983f67 1732
ed737480 1733 leaf = (xfs_attr_leafblock_t *)block;
61983f67 1734
80853366
ES
1735 /* Remote attributes - attr3 has XFS_ATTR3_RMT_MAGIC, attr has none */
1736 if ((be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) &&
1737 (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)) {
ed737480 1738 for (i = 0; i < attr_data.remote_val_count; i++) {
70099c89 1739 if (obfuscate && attr_data.remote_vals[i] == offset)
80853366
ES
1740 /* Macros to handle both attr and attr3 */
1741 memset(block +
1742 (bs - XFS_ATTR3_RMT_BUF_SPACE(mp, bs)),
1941482c 1743 'v', XFS_ATTR3_RMT_BUF_SPACE(mp, bs));
61983f67 1744 }
ed737480
DC
1745 return;
1746 }
61983f67 1747
80853366 1748 /* Ok, it's a leaf - get header; accounts for crc & non-crc */
19ebedcf 1749 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &hdr, leaf);
80853366
ES
1750
1751 nentries = hdr.count;
59562913
ES
1752 if (nentries == 0 ||
1753 nentries * sizeof(xfs_attr_leaf_entry_t) +
80853366
ES
1754 xfs_attr3_leaf_hdr_size(leaf) >
1755 XFS_ATTR3_RMT_BUF_SPACE(mp, bs)) {
ed737480
DC
1756 if (show_warnings)
1757 print_warning("invalid attr count in inode %llu",
1758 (long long)cur_ino);
1759 return;
1760 }
1761
80853366 1762 entry = xfs_attr3_leaf_entryp(leaf);
70099c89
ES
1763 /* We will move this as we parse */
1764 first_name = NULL;
80853366 1765 for (i = 0; i < nentries; i++, entry++) {
70099c89
ES
1766 int nlen, vlen, zlen;
1767
1768 /* Grows up; if this name is topmost, move first_name */
1769 if (!first_name || xfs_attr3_leaf_name(leaf, i) < first_name)
1770 first_name = xfs_attr3_leaf_name(leaf, i);
1771
ff105f75 1772 if (be16_to_cpu(entry->nameidx) > mp->m_sb.sb_blocksize) {
61983f67 1773 if (show_warnings)
ed737480
DC
1774 print_warning(
1775 "invalid attr nameidx in inode %llu",
61983f67 1776 (long long)cur_ino);
ed737480 1777 break;
61983f67 1778 }
ed737480
DC
1779 if (entry->flags & XFS_ATTR_LOCAL) {
1780 local = xfs_attr3_leaf_name_local(leaf, i);
1781 if (local->namelen == 0) {
61983f67 1782 if (show_warnings)
ed737480
DC
1783 print_warning(
1784 "zero length for attr name in inode %llu",
1785 (long long)cur_ino);
61983f67
BN
1786 break;
1787 }
70099c89
ES
1788 if (obfuscate) {
1789 generate_obfuscated_name(0, local->namelen,
1790 &local->nameval[0]);
1791 memset(&local->nameval[local->namelen], 'v',
1792 be16_to_cpu(local->valuelen));
1793 }
1794 /* zero from end of nameval[] to next name start */
1795 nlen = local->namelen;
1796 vlen = be16_to_cpu(local->valuelen);
1797 zlen = xfs_attr_leaf_entsize_local(nlen, vlen) -
1798 (sizeof(xfs_attr_leaf_name_local_t) - 1 +
1799 nlen + vlen);
1800 if (zero_stale_data)
1801 memset(&local->nameval[nlen + vlen], 0, zlen);
ed737480
DC
1802 } else {
1803 remote = xfs_attr3_leaf_name_remote(leaf, i);
1804 if (remote->namelen == 0 || remote->valueblk == 0) {
1805 if (show_warnings)
1806 print_warning(
1807 "invalid attr entry in inode %llu",
1808 (long long)cur_ino);
1809 break;
61983f67 1810 }
70099c89
ES
1811 if (obfuscate) {
1812 generate_obfuscated_name(0, remote->namelen,
1813 &remote->name[0]);
1814 add_remote_vals(be32_to_cpu(remote->valueblk),
1815 be32_to_cpu(remote->valuelen));
1816 }
1817 /* zero from end of name[] to next name start */
1818 nlen = remote->namelen;
1819 zlen = xfs_attr_leaf_entsize_remote(nlen) -
1820 (sizeof(xfs_attr_leaf_name_remote_t) - 1 +
1821 nlen);
1822 if (zero_stale_data)
1823 memset(&remote->name[nlen], 0, zlen);
61983f67
BN
1824 }
1825 }
70099c89
ES
1826
1827 /* Zero from end of entries array to the first name/val */
1828 if (zero_stale_data) {
1829 struct xfs_attr_leaf_entry *entries;
1830
1831 entries = xfs_attr3_leaf_entryp(leaf);
1832 memset(&entries[nentries], 0,
1833 first_name - (char *)&entries[nentries]);
1834 }
61983f67
BN
1835}
1836
70099c89 1837/* Processes symlinks, attrs, directories ... */
d452ae4d
DC
1838static int
1839process_single_fsb_objects(
5a35bf2c
DC
1840 xfs_fileoff_t o,
1841 xfs_fsblock_t s,
1842 xfs_filblks_t c,
d452ae4d 1843 typnm_t btype,
5a35bf2c 1844 xfs_fileoff_t last)
d452ae4d 1845{
ed737480 1846 char *dp;
d452ae4d 1847 int ret = 0;
ed737480 1848 int i;
d452ae4d 1849
0c6b1caf
DC
1850 for (i = 0; i < c; i++) {
1851 push_cur();
1852 set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), blkbb,
1853 DB_RING_IGN, NULL);
d452ae4d 1854
0c6b1caf
DC
1855 if (!iocur_top->data) {
1856 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, s);
1857 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, s);
61983f67 1858
0c6b1caf
DC
1859 print_warning("cannot read %s block %u/%u (%llu)",
1860 typtab[btype].name, agno, agbno, s);
1861 if (stop_on_read_error)
1862 ret = -EIO;
1863 goto out_pop;
d452ae4d 1864
0c6b1caf 1865 }
d452ae4d 1866
6d34e8b3 1867 if (!obfuscate && !zero_stale_data)
0c6b1caf 1868 goto write;
d452ae4d 1869
c83c169e
ES
1870 /* Zero unused part of interior nodes */
1871 if (zero_stale_data) {
1872 xfs_da_intnode_t *node = iocur_top->data;
1873 int magic = be16_to_cpu(node->hdr.info.magic);
1874
1875 if (magic == XFS_DA_NODE_MAGIC ||
1876 magic == XFS_DA3_NODE_MAGIC) {
1877 struct xfs_da3_icnode_hdr hdr;
1878 int used;
1879
08c16786 1880 libxfs_da3_node_hdr_from_disk(mp, &hdr, node);
52be9b6a
CH
1881 switch (btype) {
1882 case TYP_DIR2:
1883 used = mp->m_dir_geo->node_hdr_size;
1884 break;
1885 case TYP_ATTR:
1886 used = mp->m_attr_geo->node_hdr_size;
1887 break;
1888 default:
1889 /* unknown type, don't zero anything */
1890 used = mp->m_sb.sb_blocksize;
1891 break;
1892 }
c83c169e
ES
1893
1894 used += hdr.count
1895 * sizeof(struct xfs_da_node_entry);
1896
1897 if (used < mp->m_sb.sb_blocksize) {
1898 memset((char *)node + used, 0,
1899 mp->m_sb.sb_blocksize - used);
1900 iocur_top->need_crc = 1;
1901 }
1902 }
1903 }
1904
1905 /* Handle leaf nodes */
0c6b1caf 1906 dp = iocur_top->data;
ed737480
DC
1907 switch (btype) {
1908 case TYP_DIR2:
a56173b5 1909 if (o >= mp->m_dir_geo->freeblk) {
c3387ef7 1910 process_dir_free_block(dp);
a56173b5
ES
1911 } else if (o >= mp->m_dir_geo->leafblk) {
1912 process_dir_leaf_block(dp);
1913 } else {
1914 process_dir_data_block(dp, o,
ff105f75 1915 last == mp->m_dir_geo->fsbcount);
a56173b5 1916 }
fd491857 1917 iocur_top->need_crc = 1;
ed737480 1918 break;
ed737480 1919 case TYP_ATTR:
70099c89
ES
1920 process_attr_block(dp, o);
1921 iocur_top->need_crc = 1;
ed737480
DC
1922 break;
1923 default:
1924 break;
1925 }
0c6b1caf
DC
1926
1927write:
1928 ret = write_buf(iocur_top);
1929out_pop:
1930 pop_cur();
1931 if (ret)
1932 break;
ed737480 1933 o++;
0c6b1caf 1934 s++;
d452ae4d 1935 }
d452ae4d 1936
d452ae4d
DC
1937 return ret;
1938}
1939
6e79202b
DC
1940/*
1941 * Static map to aggregate multiple extents into a single directory block.
1942 */
1943static struct bbmap mfsb_map;
1944static int mfsb_length;
1945
d452ae4d 1946static int
9e43c345 1947process_multi_fsb_dir(
5a35bf2c
DC
1948 xfs_fileoff_t o,
1949 xfs_fsblock_t s,
1950 xfs_filblks_t c,
d452ae4d 1951 typnm_t btype,
5a35bf2c 1952 xfs_fileoff_t last)
d452ae4d 1953{
b04e7e92 1954 char *dp;
ed737480
DC
1955 int ret = 0;
1956
6e79202b
DC
1957 while (c > 0) {
1958 unsigned int bm_len;
ed737480 1959
ff105f75
DC
1960 if (mfsb_length + c >= mp->m_dir_geo->fsbcount) {
1961 bm_len = mp->m_dir_geo->fsbcount - mfsb_length;
6e79202b
DC
1962 mfsb_length = 0;
1963 } else {
1964 mfsb_length += c;
1965 bm_len = c;
1966 }
ed737480 1967
6e79202b
DC
1968 mfsb_map.b[mfsb_map.nmaps].bm_bn = XFS_FSB_TO_DADDR(mp, s);
1969 mfsb_map.b[mfsb_map.nmaps].bm_len = XFS_FSB_TO_BB(mp, bm_len);
1970 mfsb_map.nmaps++;
ed737480 1971
6e79202b
DC
1972 if (mfsb_length == 0) {
1973 push_cur();
1974 set_cur(&typtab[btype], 0, 0, DB_RING_IGN, &mfsb_map);
1975 if (!iocur_top->data) {
1976 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, s);
1977 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, s);
ed737480 1978
6e79202b
DC
1979 print_warning("cannot read %s block %u/%u (%llu)",
1980 typtab[btype].name, agno, agbno, s);
1981 if (stop_on_read_error)
1982 ret = -1;
1983 goto out_pop;
ed737480 1984
6e79202b 1985 }
ed737480 1986
b04e7e92
SR
1987 if (!obfuscate && !zero_stale_data)
1988 goto write;
6e79202b 1989
b04e7e92
SR
1990 dp = iocur_top->data;
1991 if (o >= mp->m_dir_geo->freeblk) {
c3387ef7 1992 process_dir_free_block(dp);
b04e7e92
SR
1993 } else if (o >= mp->m_dir_geo->leafblk) {
1994 process_dir_leaf_block(dp);
1995 } else {
1996 process_dir_data_block(dp, o,
1997 last == mp->m_dir_geo->fsbcount);
1998 }
fd491857 1999 iocur_top->need_crc = 1;
b04e7e92 2000write:
6e79202b 2001 ret = write_buf(iocur_top);
ed737480 2002out_pop:
6e79202b
DC
2003 pop_cur();
2004 mfsb_map.nmaps = 0;
2005 if (ret)
2006 break;
2007 }
2008 c -= bm_len;
2009 s += bm_len;
2010 }
2011
ed737480 2012 return ret;
d452ae4d
DC
2013}
2014
001df390
DW
2015static bool
2016is_multi_fsb_object(
2017 struct xfs_mount *mp,
2018 typnm_t btype)
2019{
2020 if (btype == TYP_DIR2 && mp->m_dir_geo->fsbcount > 1)
2021 return true;
0e81250e
DW
2022 if (btype == TYP_SYMLINK)
2023 return true;
001df390
DW
2024 return false;
2025}
2026
9e43c345
DW
2027static int
2028process_multi_fsb_objects(
2029 xfs_fileoff_t o,
2030 xfs_fsblock_t s,
2031 xfs_filblks_t c,
2032 typnm_t btype,
2033 xfs_fileoff_t last)
2034{
2035 switch (btype) {
2036 case TYP_DIR2:
2037 return process_multi_fsb_dir(o, s, c, btype, last);
0e81250e
DW
2038 case TYP_SYMLINK:
2039 return process_symlink_block(o, s, c, btype, last);
9e43c345
DW
2040 default:
2041 print_warning("bad type for multi-fsb object %d", btype);
2042 return -EINVAL;
2043 }
2044}
2045
d452ae4d 2046/* inode copy routines */
61983f67
BN
2047static int
2048process_bmbt_reclist(
2049 xfs_bmbt_rec_t *rp,
2050 int numrecs,
2051 typnm_t btype)
2052{
2053 int i;
5a35bf2c
DC
2054 xfs_fileoff_t o, op = NULLFILEOFF;
2055 xfs_fsblock_t s;
2056 xfs_filblks_t c, cp = NULLFILEOFF;
61983f67 2057 int f;
5a35bf2c 2058 xfs_fileoff_t last;
88b8e1d6
BN
2059 xfs_agnumber_t agno;
2060 xfs_agblock_t agbno;
001df390 2061 bool is_multi_fsb = is_multi_fsb_object(mp, btype);
d452ae4d 2062 int error;
61983f67
BN
2063
2064 if (btype == TYP_DATA)
2065 return 1;
2066
2067 convert_extent(&rp[numrecs - 1], &o, &s, &c, &f);
2068 last = o + c;
2069
2070 for (i = 0; i < numrecs; i++, rp++) {
2071 convert_extent(rp, &o, &s, &c, &f);
2072
88b8e1d6
BN
2073 /*
2074 * ignore extents that are clearly bogus, and if a bogus
2075 * one is found, stop processing remaining extents
2076 */
2077 if (i > 0 && op + cp > o) {
2078 if (show_warnings)
2079 print_warning("bmap extent %d in %s ino %llu "
2080 "starts at %llu, previous extent "
2081 "ended at %llu", i,
2082 typtab[btype].name, (long long)cur_ino,
2083 o, op + cp - 1);
2084 break;
2085 }
2086
2087 if (c > max_extent_size) {
2088 /*
2089 * since we are only processing non-data extents,
2090 * large numbers of blocks in a metadata extent is
2091 * extremely rare and more than likely to be corrupt.
2092 */
2093 if (show_warnings)
2094 print_warning("suspicious count %u in bmap "
2095 "extent %d in %s ino %llu", c, i,
2096 typtab[btype].name, (long long)cur_ino);
2097 break;
2098 }
2099
2100 op = o;
2101 cp = c;
2102
2103 agno = XFS_FSB_TO_AGNO(mp, s);
2104 agbno = XFS_FSB_TO_AGBNO(mp, s);
2105
2106 if (!valid_bno(agno, agbno)) {
2107 if (show_warnings)
2108 print_warning("invalid block number %u/%u "
2109 "(%llu) in bmap extent %d in %s ino "
2110 "%llu", agno, agbno, s, i,
2111 typtab[btype].name, (long long)cur_ino);
2112 break;
2113 }
2114
2115 if (!valid_bno(agno, agbno + c - 1)) {
2116 if (show_warnings)
2117 print_warning("bmap extent %i in %s inode %llu "
2118 "overflows AG (end is %u/%u)", i,
2119 typtab[btype].name, (long long)cur_ino,
2120 agno, agbno + c - 1);
2121 break;
2122 }
2123
d452ae4d 2124 /* multi-extent blocks require special handling */
001df390
DW
2125 if (is_multi_fsb)
2126 error = process_multi_fsb_objects(o, s, c, btype,
2127 last);
2128 else
2129 error = process_single_fsb_objects(o, s, c, btype,
2130 last);
d452ae4d
DC
2131 if (error)
2132 return 0;
61983f67
BN
2133 }
2134
2135 return 1;
2136}
2137
2138static int
2139scanfunc_bmap(
b194c7d8 2140 struct xfs_btree_block *block,
61983f67
BN
2141 xfs_agnumber_t agno,
2142 xfs_agblock_t agbno,
2143 int level,
2144 typnm_t btype,
2145 void *arg) /* ptr to itype */
2146{
2147 int i;
2148 xfs_bmbt_ptr_t *pp;
61983f67
BN
2149 int nrecs;
2150
b194c7d8 2151 nrecs = be16_to_cpu(block->bb_numrecs);
61983f67
BN
2152
2153 if (level == 0) {
2154 if (nrecs > mp->m_bmap_dmxr[0]) {
2155 if (show_warnings)
2156 print_warning("invalid numrecs (%u) in %s "
2157 "block %u/%u", nrecs,
2158 typtab[btype].name, agno, agbno);
2159 return 1;
2160 }
b3563c19
BN
2161 return process_bmbt_reclist(XFS_BMBT_REC_ADDR(mp, block, 1),
2162 nrecs, *(typnm_t*)arg);
61983f67
BN
2163 }
2164
2165 if (nrecs > mp->m_bmap_dmxr[1]) {
2166 if (show_warnings)
2167 print_warning("invalid numrecs (%u) in %s block %u/%u",
2168 nrecs, typtab[btype].name, agno, agbno);
2169 return 1;
2170 }
b3563c19 2171 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
61983f67
BN
2172 for (i = 0; i < nrecs; i++) {
2173 xfs_agnumber_t ag;
2174 xfs_agblock_t bno;
2175
1bec3a62
ES
2176 ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i]));
2177 bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i]));
61983f67
BN
2178
2179 if (bno == 0 || bno > mp->m_sb.sb_agblocks ||
2180 ag > mp->m_sb.sb_agcount) {
2181 if (show_warnings)
2182 print_warning("invalid block number (%u/%u) "
2183 "in %s block %u/%u", ag, bno,
2184 typtab[btype].name, agno, agbno);
2185 continue;
2186 }
2187
2188 if (!scan_btree(ag, bno, level, btype, arg, scanfunc_bmap))
2189 return 0;
2190 }
2191 return 1;
2192}
2193
2194static int
2195process_btinode(
2196 xfs_dinode_t *dip,
2197 typnm_t itype)
2198{
2199 xfs_bmdr_block_t *dib;
2200 int i;
2201 xfs_bmbt_ptr_t *pp;
61983f67
BN
2202 int level;
2203 int nrecs;
2204 int maxrecs;
2205 int whichfork;
2206 typnm_t btype;
2207
2208 whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
2209 btype = (itype == TYP_ATTR) ? TYP_BMAPBTA : TYP_BMAPBTD;
2210
2211 dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
2212 level = be16_to_cpu(dib->bb_level);
2213 nrecs = be16_to_cpu(dib->bb_numrecs);
2214
2215 if (level > XFS_BM_MAXLEVELS(mp, whichfork)) {
2216 if (show_warnings)
2217 print_warning("invalid level (%u) in inode %lld %s "
2218 "root", level, (long long)cur_ino,
2219 typtab[btype].name);
2220 return 1;
2221 }
2222
b3563c19
BN
2223 if (level == 0) {
2224 return process_bmbt_reclist(XFS_BMDR_REC_ADDR(dib, 1),
2225 nrecs, itype);
2226 }
61983f67 2227
e2f60652 2228 maxrecs = libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0);
61983f67
BN
2229 if (nrecs > maxrecs) {
2230 if (show_warnings)
2231 print_warning("invalid numrecs (%u) in inode %lld %s "
2232 "root", nrecs, (long long)cur_ino,
2233 typtab[btype].name);
2234 return 1;
2235 }
2236
b3563c19 2237 pp = XFS_BMDR_PTR_ADDR(dib, 1, maxrecs);
07b75e31
SR
2238
2239 if (zero_stale_data) {
2240 char *top;
2241
2242 /* Unused btree key space */
2243 top = (char*)XFS_BMDR_KEY_ADDR(dib, nrecs + 1);
2244 memset(top, 0, (char*)pp - top);
2245
2246 /* Unused btree ptr space */
2247 top = (char*)&pp[nrecs];
2248 memset(top, 0, (char*)dib + XFS_DFORK_SIZE(dip, mp, whichfork) - top);
2249 }
2250
61983f67
BN
2251 for (i = 0; i < nrecs; i++) {
2252 xfs_agnumber_t ag;
2253 xfs_agblock_t bno;
2254
1bec3a62
ES
2255 ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i]));
2256 bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i]));
61983f67
BN
2257
2258 if (bno == 0 || bno > mp->m_sb.sb_agblocks ||
2259 ag > mp->m_sb.sb_agcount) {
2260 if (show_warnings)
2261 print_warning("invalid block number (%u/%u) "
2262 "in inode %llu %s root", ag,
2263 bno, (long long)cur_ino,
2264 typtab[btype].name);
2265 continue;
2266 }
2267
2268 if (!scan_btree(ag, bno, level, btype, &itype, scanfunc_bmap))
2269 return 0;
2270 }
2271 return 1;
2272}
2273
2274static int
2275process_exinode(
2276 xfs_dinode_t *dip,
2277 typnm_t itype)
2278{
2279 int whichfork;
87c955c3 2280 int used;
88b8e1d6 2281 xfs_extnum_t nex;
61983f67
BN
2282
2283 whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
2284
5e656dbb 2285 nex = XFS_DFORK_NEXTENTS(dip, whichfork);
87c955c3
ES
2286 used = nex * sizeof(xfs_bmbt_rec_t);
2287 if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
88b8e1d6
BN
2288 if (show_warnings)
2289 print_warning("bad number of extents %d in inode %lld",
2290 nex, (long long)cur_ino);
2291 return 1;
2292 }
2293
87c955c3
ES
2294 /* Zero unused data fork past used extents */
2295 if (zero_stale_data && (used < XFS_DFORK_SIZE(dip, mp, whichfork)))
2296 memset(XFS_DFORK_PTR(dip, whichfork) + used, 0,
2297 XFS_DFORK_SIZE(dip, mp, whichfork) - used);
2298
2299
88b8e1d6
BN
2300 return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip,
2301 whichfork), nex, itype);
61983f67
BN
2302}
2303
2304static int
2305process_inode_data(
2306 xfs_dinode_t *dip,
2307 typnm_t itype)
2308{
56b2de80 2309 switch (dip->di_format) {
61983f67 2310 case XFS_DINODE_FMT_LOCAL:
87c955c3 2311 if (obfuscate || zero_stale_data)
61983f67
BN
2312 switch (itype) {
2313 case TYP_DIR2:
87c955c3 2314 process_sf_dir(dip);
61983f67
BN
2315 break;
2316
2317 case TYP_SYMLINK:
87c955c3 2318 process_sf_symlink(dip);
61983f67
BN
2319 break;
2320
2321 default: ;
2322 }
2323 break;
2324
2325 case XFS_DINODE_FMT_EXTENTS:
2326 return process_exinode(dip, itype);
2327
2328 case XFS_DINODE_FMT_BTREE:
2329 return process_btinode(dip, itype);
2330 }
2331 return 1;
2332}
2333
b32d0eb6
SR
2334static int
2335process_dev_inode(
2336 xfs_dinode_t *dip)
2337{
2338 if (XFS_DFORK_NEXTENTS(dip, XFS_DATA_FORK)) {
2339 if (show_warnings)
2340 print_warning("inode %llu has unexpected extents",
2341 (unsigned long long)cur_ino);
2342 return 0;
2343 } else {
2344 if (zero_stale_data) {
2345 unsigned int size = sizeof(xfs_dev_t);
2346
2347 memset(XFS_DFORK_DPTR(dip) + size, 0,
2348 XFS_DFORK_DSIZE(dip, mp) - size);
2349 }
2350 return 1;
2351 }
2352}
2353
fd491857
DC
2354/*
2355 * when we process the inode, we may change the data in the data and/or
2356 * attribute fork if they are in short form and we are obfuscating names.
2357 * In this case we need to recalculate the CRC of the inode, but we should
2358 * only do that if the CRC in the inode is good to begin with. If the crc
2359 * is not ok, we just leave it alone.
2360 */
61983f67
BN
2361static int
2362process_inode(
2363 xfs_agnumber_t agno,
2364 xfs_agino_t agino,
27499a0a
ES
2365 xfs_dinode_t *dip,
2366 bool free_inode)
61983f67 2367{
61983f67 2368 int success;
fd491857
DC
2369 bool crc_was_ok = false; /* no recalc by default */
2370 bool need_new_crc = false;
61983f67 2371
61983f67
BN
2372 success = 1;
2373 cur_ino = XFS_AGINO_TO_INO(mp, agno, agino);
2374
27499a0a
ES
2375 /* we only care about crc recalculation if we will modify the inode. */
2376 if (obfuscate || zero_stale_data) {
e2f60652 2377 crc_was_ok = libxfs_verify_cksum((char *)dip,
fd491857
DC
2378 mp->m_sb.sb_inodesize,
2379 offsetof(struct xfs_dinode, di_crc));
2380 }
2381
27499a0a
ES
2382 if (free_inode) {
2383 if (zero_stale_data) {
2384 /* Zero all of the inode literal area */
2385 memset(XFS_DFORK_DPTR(dip), 0,
2386 XFS_LITINO(mp, dip->di_version));
2387 }
2388 goto done;
2389 }
2390
61983f67 2391 /* copy appropriate data fork metadata */
56b2de80 2392 switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
61983f67 2393 case S_IFDIR:
61983f67 2394 success = process_inode_data(dip, TYP_DIR2);
fd491857
DC
2395 if (dip->di_format == XFS_DINODE_FMT_LOCAL)
2396 need_new_crc = 1;
61983f67
BN
2397 break;
2398 case S_IFLNK:
2399 success = process_inode_data(dip, TYP_SYMLINK);
fd491857
DC
2400 if (dip->di_format == XFS_DINODE_FMT_LOCAL)
2401 need_new_crc = 1;
61983f67 2402 break;
88b8e1d6 2403 case S_IFREG:
61983f67 2404 success = process_inode_data(dip, TYP_DATA);
88b8e1d6 2405 break;
b32d0eb6
SR
2406 case S_IFIFO:
2407 case S_IFCHR:
2408 case S_IFBLK:
2409 case S_IFSOCK:
2410 success = process_dev_inode(dip);
2411 need_new_crc = 1;
2412 break;
2413 default:
2414 break;
61983f67 2415 }
a85f8b0a 2416 nametable_clear();
61983f67 2417
88b8e1d6 2418 /* copy extended attributes if they exist and forkoff is valid */
49f693fa
DC
2419 if (success &&
2420 XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp, dip->di_version)) {
61983f67 2421 attr_data.remote_val_count = 0;
56b2de80 2422 switch (dip->di_aformat) {
61983f67 2423 case XFS_DINODE_FMT_LOCAL:
fd491857 2424 need_new_crc = 1;
87c955c3
ES
2425 if (obfuscate || zero_stale_data)
2426 process_sf_attr(dip);
61983f67
BN
2427 break;
2428
2429 case XFS_DINODE_FMT_EXTENTS:
2430 success = process_exinode(dip, TYP_ATTR);
2431 break;
2432
2433 case XFS_DINODE_FMT_BTREE:
2434 success = process_btinode(dip, TYP_ATTR);
2435 break;
2436 }
a85f8b0a 2437 nametable_clear();
61983f67 2438 }
fd491857 2439
27499a0a
ES
2440done:
2441 /* Heavy handed but low cost; just do it as a catch-all. */
2442 if (zero_stale_data)
2443 need_new_crc = 1;
2444
fd491857 2445 if (crc_was_ok && need_new_crc)
f616e2bf 2446 libxfs_dinode_calc_crc(mp, dip);
61983f67
BN
2447 return success;
2448}
2449
14f8b681 2450static uint32_t inodes_copied;
61983f67
BN
2451
2452static int
2453copy_inode_chunk(
2454 xfs_agnumber_t agno,
2455 xfs_inobt_rec_t *rp)
2456{
2457 xfs_agino_t agino;
2458 int off;
2459 xfs_agblock_t agbno;
04b21e41 2460 xfs_agblock_t end_agbno;
61983f67 2461 int i;
d24c0a90 2462 int rval = 0;
04b21e41
BF
2463 int blks_per_buf;
2464 int inodes_per_buf;
2465 int ioff;
e7fd2b6f 2466 struct xfs_ino_geometry *igeo = M_IGEO(mp);
61983f67
BN
2467
2468 agino = be32_to_cpu(rp->ir_startino);
2469 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
e7fd2b6f 2470 end_agbno = agbno + igeo->ialloc_blks;
61983f67
BN
2471 off = XFS_INO_TO_OFFSET(mp, agino);
2472
04b21e41
BF
2473 /*
2474 * If the fs supports sparse inode records, we must process inodes a
2475 * cluster at a time because that is the sparse allocation granularity.
2476 * Otherwise, we risk CRC corruption errors on reads of inode chunks.
2477 *
2478 * Also make sure that that we don't process more than the single record
2479 * we've been passed (large block sizes can hold multiple inode chunks).
2480 */
2481 if (xfs_sb_version_hassparseinodes(&mp->m_sb))
e7fd2b6f 2482 blks_per_buf = igeo->blocks_per_cluster;
04b21e41 2483 else
e7fd2b6f 2484 blks_per_buf = igeo->ialloc_blks;
7516da71 2485 inodes_per_buf = min(XFS_FSB_TO_INO(mp, blks_per_buf),
04b21e41
BF
2486 XFS_INODES_PER_CHUNK);
2487
2488 /*
2489 * Sanity check that we only process a single buffer if ir_startino has
2490 * a buffer offset. A non-zero offset implies that the entire chunk lies
2491 * within a block.
2492 */
2493 if (off && inodes_per_buf != XFS_INODES_PER_CHUNK) {
2494 print_warning("bad starting inode offset %d", off);
2495 return 0;
2496 }
2497
88b8e1d6
BN
2498 if (agino == 0 || agino == NULLAGINO || !valid_bno(agno, agbno) ||
2499 !valid_bno(agno, XFS_AGINO_TO_AGBNO(mp,
2500 agino + XFS_INODES_PER_CHUNK - 1))) {
2501 if (show_warnings)
2502 print_warning("bad inode number %llu (%u/%u)",
2503 XFS_AGINO_TO_INO(mp, agno, agino), agno, agino);
2504 return 1;
2505 }
2506
88b8e1d6
BN
2507 /*
2508 * check for basic assumptions about inode chunks, and if any
2509 * assumptions fail, don't process the inode chunk.
2510 */
88b8e1d6
BN
2511 if ((mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK && off != 0) ||
2512 (mp->m_sb.sb_inopblock > XFS_INODES_PER_CHUNK &&
2513 off % XFS_INODES_PER_CHUNK != 0) ||
5e656dbb 2514 (xfs_sb_version_hasalign(&mp->m_sb) &&
0ab7cbc8 2515 mp->m_sb.sb_inoalignmt != 0 &&
88b8e1d6
BN
2516 agbno % mp->m_sb.sb_inoalignmt != 0)) {
2517 if (show_warnings)
2518 print_warning("badly aligned inode (start = %llu)",
2519 XFS_AGINO_TO_INO(mp, agno, agino));
9180183e
BF
2520 return 1;
2521 }
2522
2523 push_cur();
04b21e41
BF
2524 ioff = 0;
2525 while (agbno < end_agbno && ioff < XFS_INODES_PER_CHUNK) {
2526 if (xfs_inobt_is_sparse_disk(rp, ioff))
2527 goto next_bp;
2528
2529 set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno),
2530 XFS_FSB_TO_BB(mp, blks_per_buf), DB_RING_IGN, NULL);
2531 if (iocur_top->data == NULL) {
2532 print_warning("cannot read inode block %u/%u",
2533 agno, agbno);
2534 rval = !stop_on_read_error;
2535 goto pop_out;
2536 }
88b8e1d6 2537
04b21e41
BF
2538 for (i = 0; i < inodes_per_buf; i++) {
2539 xfs_dinode_t *dip;
61983f67 2540
04b21e41
BF
2541 dip = (xfs_dinode_t *)((char *)iocur_top->data +
2542 ((off + i) << mp->m_sb.sb_inodelog));
61983f67 2543
04b21e41
BF
2544 /* process_inode handles free inodes, too */
2545 if (!process_inode(agno, agino + ioff + i, dip,
752ae76b 2546 XFS_INOBT_IS_FREE_DISK(rp, ioff + i)))
04b21e41 2547 goto pop_out;
9180183e 2548
04b21e41
BF
2549 inodes_copied++;
2550 }
61983f67 2551
04b21e41
BF
2552 if (write_buf(iocur_top))
2553 goto pop_out;
2554
2555next_bp:
2556 agbno += blks_per_buf;
2557 ioff += inodes_per_buf;
2558 }
61983f67
BN
2559
2560 if (show_progress)
2561 print_progress("Copied %u of %u inodes (%u of %u AGs)",
2562 inodes_copied, mp->m_sb.sb_icount, agno,
2563 mp->m_sb.sb_agcount);
d24c0a90
BN
2564 rval = 1;
2565pop_out:
61983f67 2566 pop_cur();
d24c0a90 2567 return rval;
61983f67
BN
2568}
2569
2570static int
2571scanfunc_ino(
b194c7d8 2572 struct xfs_btree_block *block,
61983f67
BN
2573 xfs_agnumber_t agno,
2574 xfs_agblock_t agbno,
2575 int level,
2576 typnm_t btype,
2577 void *arg)
2578{
2579 xfs_inobt_rec_t *rp;
2580 xfs_inobt_ptr_t *pp;
2581 int i;
88b8e1d6 2582 int numrecs;
03e956b2 2583 int finobt = *(int *) arg;
e7fd2b6f 2584 struct xfs_ino_geometry *igeo = M_IGEO(mp);
88b8e1d6 2585
b194c7d8 2586 numrecs = be16_to_cpu(block->bb_numrecs);
61983f67
BN
2587
2588 if (level == 0) {
e7fd2b6f 2589 if (numrecs > igeo->inobt_mxr[0]) {
88b8e1d6
BN
2590 if (show_warnings)
2591 print_warning("invalid numrecs %d in %s "
2592 "block %u/%u", numrecs,
2593 typtab[btype].name, agno, agbno);
e7fd2b6f 2594 numrecs = igeo->inobt_mxr[0];
88b8e1d6 2595 }
03e956b2
BF
2596
2597 /*
2598 * Only copy the btree blocks for the finobt. The inobt scan
2599 * copies the inode chunks.
2600 */
2601 if (finobt)
2602 return 1;
2603
b3563c19 2604 rp = XFS_INOBT_REC_ADDR(mp, block, 1);
88b8e1d6 2605 for (i = 0; i < numrecs; i++, rp++) {
61983f67
BN
2606 if (!copy_inode_chunk(agno, rp))
2607 return 0;
2608 }
88b8e1d6
BN
2609 return 1;
2610 }
2611
e7fd2b6f 2612 if (numrecs > igeo->inobt_mxr[1]) {
88b8e1d6
BN
2613 if (show_warnings)
2614 print_warning("invalid numrecs %d in %s block %u/%u",
2615 numrecs, typtab[btype].name, agno, agbno);
e7fd2b6f 2616 numrecs = igeo->inobt_mxr[1];
88b8e1d6
BN
2617 }
2618
e7fd2b6f 2619 pp = XFS_INOBT_PTR_ADDR(mp, block, 1, igeo->inobt_mxr[1]);
88b8e1d6
BN
2620 for (i = 0; i < numrecs; i++) {
2621 if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
2622 if (show_warnings)
2623 print_warning("invalid block number (%u/%u) "
2624 "in %s block %u/%u",
2625 agno, be32_to_cpu(pp[i]),
2626 typtab[btype].name, agno, agbno);
2627 continue;
61983f67 2628 }
88b8e1d6
BN
2629 if (!scan_btree(agno, be32_to_cpu(pp[i]), level,
2630 btype, arg, scanfunc_ino))
2631 return 0;
61983f67
BN
2632 }
2633 return 1;
2634}
2635
2636static int
2637copy_inodes(
2638 xfs_agnumber_t agno,
2639 xfs_agi_t *agi)
2640{
2641 xfs_agblock_t root;
2642 int levels;
03e956b2 2643 int finobt = 0;
61983f67
BN
2644
2645 root = be32_to_cpu(agi->agi_root);
2646 levels = be32_to_cpu(agi->agi_level);
2647
2648 /* validate root and levels before processing the tree */
2649 if (root == 0 || root > mp->m_sb.sb_agblocks) {
2650 if (show_warnings)
2651 print_warning("invalid block number (%u) in inobt "
2652 "root in agi %u", root, agno);
2653 return 1;
2654 }
2655 if (levels >= XFS_BTREE_MAXLEVELS) {
2656 if (show_warnings)
2657 print_warning("invalid level (%u) in inobt root "
2658 "in agi %u", levels, agno);
2659 return 1;
2660 }
2661
03e956b2
BF
2662 if (!scan_btree(agno, root, levels, TYP_INOBT, &finobt, scanfunc_ino))
2663 return 0;
2664
2665 if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
2666 root = be32_to_cpu(agi->agi_free_root);
2667 levels = be32_to_cpu(agi->agi_free_level);
2668
2669 finobt = 1;
28bbc15a 2670 if (!scan_btree(agno, root, levels, TYP_FINOBT, &finobt,
03e956b2
BF
2671 scanfunc_ino))
2672 return 0;
2673 }
2674
2675 return 1;
61983f67
BN
2676}
2677
2678static int
2679scan_ag(
2680 xfs_agnumber_t agno)
2681{
2682 xfs_agf_t *agf;
2683 xfs_agi_t *agi;
d24c0a90
BN
2684 int stack_count = 0;
2685 int rval = 0;
61983f67
BN
2686
2687 /* copy the superblock of the AG */
2688 push_cur();
d24c0a90 2689 stack_count++;
61983f67
BN
2690 set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
2691 XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
2692 if (!iocur_top->data) {
2693 print_warning("cannot read superblock for ag %u", agno);
2694 if (stop_on_read_error)
d24c0a90 2695 goto pop_out;
61983f67 2696 } else {
8927d44b
ES
2697 /* Replace any filesystem label with "L's" */
2698 if (obfuscate) {
2699 struct xfs_sb *sb = iocur_top->data;
2700 memset(sb->sb_fname, 'L',
2701 min(strlen(sb->sb_fname), sizeof(sb->sb_fname)));
2702 iocur_top->need_crc = 1;
2703 }
878afc65 2704 if (write_buf(iocur_top))
d24c0a90 2705 goto pop_out;
61983f67
BN
2706 }
2707
2708 /* copy the AG free space btree root */
2709 push_cur();
d24c0a90 2710 stack_count++;
61983f67
BN
2711 set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
2712 XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
2713 agf = iocur_top->data;
2714 if (iocur_top->data == NULL) {
2715 print_warning("cannot read agf block for ag %u", agno);
2716 if (stop_on_read_error)
d24c0a90 2717 goto pop_out;
61983f67 2718 } else {
878afc65 2719 if (write_buf(iocur_top))
d24c0a90 2720 goto pop_out;
61983f67
BN
2721 }
2722
2723 /* copy the AG inode btree root */
2724 push_cur();
d24c0a90 2725 stack_count++;
61983f67
BN
2726 set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
2727 XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
2728 agi = iocur_top->data;
2729 if (iocur_top->data == NULL) {
2730 print_warning("cannot read agi block for ag %u", agno);
2731 if (stop_on_read_error)
d24c0a90 2732 goto pop_out;
61983f67 2733 } else {
878afc65 2734 if (write_buf(iocur_top))
d24c0a90 2735 goto pop_out;
61983f67
BN
2736 }
2737
2738 /* copy the AG free list header */
2739 push_cur();
d24c0a90 2740 stack_count++;
61983f67
BN
2741 set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
2742 XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
2743 if (iocur_top->data == NULL) {
2744 print_warning("cannot read agfl block for ag %u", agno);
2745 if (stop_on_read_error)
d24c0a90 2746 goto pop_out;
61983f67 2747 } else {
18cdb614
ES
2748 if (agf && zero_stale_data) {
2749 /* Zero out unused bits of agfl */
2750 int i;
2751 __be32 *agfl_bno;
2752
2753 agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, iocur_top->bp);
2754 i = be32_to_cpu(agf->agf_fllast);
2755
2756 for (;;) {
b8165508 2757 if (++i == libxfs_agfl_size(mp))
18cdb614
ES
2758 i = 0;
2759 if (i == be32_to_cpu(agf->agf_flfirst))
2760 break;
2761 agfl_bno[i] = cpu_to_be32(NULLAGBLOCK);
2762 }
2763 iocur_top->need_crc = 1;
2764 }
878afc65 2765 if (write_buf(iocur_top))
d24c0a90 2766 goto pop_out;
61983f67 2767 }
61983f67
BN
2768
2769 /* copy AG free space btrees */
2770 if (agf) {
2771 if (show_progress)
2772 print_progress("Copying free space trees of AG %u",
2773 agno);
2774 if (!copy_free_bno_btree(agno, agf))
d24c0a90 2775 goto pop_out;
61983f67 2776 if (!copy_free_cnt_btree(agno, agf))
d24c0a90 2777 goto pop_out;
e434854e
DW
2778 if (!copy_rmap_btree(agno, agf))
2779 goto pop_out;
e2756db3
DW
2780 if (!copy_refcount_btree(agno, agf))
2781 goto pop_out;
61983f67
BN
2782 }
2783
2784 /* copy inode btrees and the inodes and their associated metadata */
2785 if (agi) {
2786 if (!copy_inodes(agno, agi))
d24c0a90 2787 goto pop_out;
61983f67 2788 }
d24c0a90
BN
2789 rval = 1;
2790pop_out:
2791 while (stack_count--)
2792 pop_cur();
2793 return rval;
61983f67
BN
2794}
2795
2796static int
2797copy_ino(
2798 xfs_ino_t ino,
2799 typnm_t itype)
2800{
2801 xfs_agnumber_t agno;
2802 xfs_agblock_t agbno;
2803 xfs_agino_t agino;
61983f67 2804 int offset;
d24c0a90 2805 int rval = 0;
61983f67 2806
39fe84af 2807 if (ino == 0 || ino == NULLFSINO)
61983f67
BN
2808 return 1;
2809
2810 agno = XFS_INO_TO_AGNO(mp, ino);
2811 agino = XFS_INO_TO_AGINO(mp, ino);
2812 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
2813 offset = XFS_AGINO_TO_OFFSET(mp, agino);
2814
2815 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
2816 offset >= mp->m_sb.sb_inopblock) {
2817 if (show_warnings)
2818 print_warning("invalid %s inode number (%lld)",
2819 typtab[itype].name, (long long)ino);
2820 return 1;
2821 }
2822
2823 push_cur();
2824 set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno),
2825 blkbb, DB_RING_IGN, NULL);
2826 if (iocur_top->data == NULL) {
2827 print_warning("cannot read %s inode %lld",
2828 typtab[itype].name, (long long)ino);
d24c0a90
BN
2829 rval = !stop_on_read_error;
2830 goto pop_out;
61983f67
BN
2831 }
2832 off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
2833
61983f67 2834 cur_ino = ino;
5e656dbb 2835 rval = process_inode_data(iocur_top->data, itype);
d24c0a90
BN
2836pop_out:
2837 pop_cur();
2838 return rval;
61983f67
BN
2839}
2840
2841
2842static int
2843copy_sb_inodes(void)
2844{
2845 if (!copy_ino(mp->m_sb.sb_rbmino, TYP_RTBITMAP))
2846 return 0;
2847
2848 if (!copy_ino(mp->m_sb.sb_rsumino, TYP_RTSUMMARY))
2849 return 0;
2850
2851 if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK))
2852 return 0;
2853
0340d706
CS
2854 if (!copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK))
2855 return 0;
2856
2857 return copy_ino(mp->m_sb.sb_pquotino, TYP_DQBLK);
61983f67
BN
2858}
2859
2860static int
2861copy_log(void)
2862{
0ab627db
BF
2863 struct xlog log;
2864 int dirty;
1c12a814
BF
2865 xfs_daddr_t logstart;
2866 int logblocks;
2867 int logversion;
2868 int cycle = XLOG_INIT_CYCLE;
190df617 2869
61983f67
BN
2870 if (show_progress)
2871 print_progress("Copying log");
2872
2873 push_cur();
2874 set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
2875 mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
2876 if (iocur_top->data == NULL) {
d24c0a90 2877 pop_cur();
61983f67
BN
2878 print_warning("cannot read log");
2879 return !stop_on_read_error;
2880 }
190df617 2881
75333d29
ES
2882 /* If not obfuscating or zeroing, just copy the log as it is */
2883 if (!obfuscate && !zero_stale_data)
37a78181
ES
2884 goto done;
2885
0ab627db 2886 dirty = xlog_is_dirty(mp, &log, &x, 0);
190df617
ES
2887
2888 switch (dirty) {
2889 case 0:
2890 /* clear out a clean log */
2891 if (show_progress)
2892 print_progress("Zeroing clean log");
1c12a814
BF
2893
2894 logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
2895 logblocks = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
2896 logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1;
2897 if (xfs_sb_version_hascrc(&mp->m_sb))
2898 cycle = log.l_curr_cycle + 1;
2899
2900 libxfs_log_clear(NULL, iocur_top->data, logstart, logblocks,
2901 &mp->m_sb.sb_uuid, logversion,
571a78a7 2902 mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true);
190df617
ES
2903 break;
2904 case 1:
2905 /* keep the dirty log */
74642d8e
ES
2906 if (obfuscate)
2907 print_warning(
3b3751ab
JT
2908_("Warning: log recovery of an obfuscated metadata image can leak "
2909"unobfuscated metadata and/or cause image corruption. If possible, "
2910"please mount the filesystem to clean the log, or disable obfuscation."));
190df617
ES
2911 break;
2912 case -1:
2913 /* log detection error */
74642d8e
ES
2914 if (obfuscate)
2915 print_warning(
190df617
ES
2916_("Could not discern log; image will contain unobfuscated metadata in log."));
2917 break;
2918 }
2919
37a78181 2920done:
878afc65 2921 return !write_buf(iocur_top);
61983f67
BN
2922}
2923
2924static int
2925metadump_f(
2926 int argc,
2927 char **argv)
2928{
2929 xfs_agnumber_t agno;
2930 int c;
2931 int start_iocur_sp;
449df236
DW
2932 int outfd = -1;
2933 int ret;
88b8e1d6 2934 char *p;
61983f67
BN
2935
2936 exitcode = 1;
2937 show_progress = 0;
2938 show_warnings = 0;
2939 stop_on_read_error = 0;
2940
2941 if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
2942 print_warning("bad superblock magic number %x, giving up",
2943 mp->m_sb.sb_magicnum);
2944 return 0;
2945 }
2946
a547152d
ES
2947 /*
2948 * on load, we sanity-checked agcount and possibly set to 1
2949 * if it was corrupted and large.
2950 */
2951 if (mp->m_sb.sb_agcount == 1 &&
2952 XFS_MAX_DBLOCKS(&mp->m_sb) < mp->m_sb.sb_dblocks) {
2953 print_warning("truncated agcount, giving up");
2954 return 0;
2955 }
2956
b09e839e 2957 while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
61983f67 2958 switch (c) {
b09e839e
ES
2959 case 'a':
2960 zero_stale_data = 0;
2961 break;
61983f67
BN
2962 case 'e':
2963 stop_on_read_error = 1;
2964 break;
2965 case 'g':
2966 show_progress = 1;
2967 break;
88b8e1d6
BN
2968 case 'm':
2969 max_extent_size = (int)strtol(optarg, &p, 0);
2970 if (*p != '\0' || max_extent_size <= 0) {
2971 print_warning("bad max extent size %s",
2972 optarg);
2973 return 0;
2974 }
2975 break;
61983f67 2976 case 'o':
ffc56f19 2977 obfuscate = 0;
61983f67
BN
2978 break;
2979 case 'w':
2980 show_warnings = 1;
2981 break;
2982 default:
2983 print_warning("bad option for metadump command");
2984 return 0;
2985 }
2986 }
2987
2988 if (optind != argc - 1) {
2989 print_warning("too few options for metadump (no filename given)");
2990 return 0;
2991 }
2992
2993 metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
2994 if (metablock == NULL) {
2995 print_warning("memory allocation failure");
2996 return 0;
2997 }
2998 metablock->mb_blocklog = BBSHIFT;
2999 metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
3000
2291c68b
ES
3001 /* Set flags about state of metadump */
3002 metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
3003 if (obfuscate)
3004 metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
3005 if (!zero_stale_data)
3006 metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
3007
3008 /* If we'll copy the log, see if the log is dirty */
3009 if (mp->m_sb.sb_logstart) {
3010 push_cur();
3011 set_cur(&typtab[TYP_LOG],
3012 XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
3013 mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
3014 if (iocur_top->data) { /* best effort */
3015 struct xlog log;
3016
3017 if (xlog_is_dirty(mp, &log, &x, 0))
3018 metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
3019 }
3020 pop_cur();
3021 }
3022
61983f67
BN
3023 block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
3024 block_buffer = (char *)metablock + BBSIZE;
d7006beb
ES
3025 num_indices = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64);
3026
3027 /*
3028 * A metadump block can hold at most num_indices of BBSIZE sectors;
3029 * do not try to dump a filesystem with a sector size which does not
3030 * fit within num_indices (i.e. within a single metablock).
3031 */
3032 if (mp->m_sb.sb_sectsize > num_indices * BBSIZE) {
3033 print_warning("Cannot dump filesystem with sector size %u",
3034 mp->m_sb.sb_sectsize);
3035 free(metablock);
3036 return 0;
3037 }
3038
61983f67
BN
3039 cur_index = 0;
3040 start_iocur_sp = iocur_sp;
3041
3042 if (strcmp(argv[optind], "-") == 0) {
3043 if (isatty(fileno(stdout))) {
3044 print_warning("cannot write to a terminal");
61983f67
BN
3045 free(metablock);
3046 return 0;
3047 }
4944defa
DW
3048 /*
3049 * Redirect stdout to stderr for the duration of the
3050 * metadump operation so that dbprintf and other messages
3051 * are sent to the console instead of polluting the
3052 * metadump stream.
449df236
DW
3053 *
3054 * We get to do this the hard way because musl doesn't
3055 * allow reassignment of stdout.
4944defa 3056 */
449df236
DW
3057 fflush(stdout);
3058 outfd = dup(STDOUT_FILENO);
3059 if (outfd < 0) {
3060 perror("opening dump stream");
3061 goto out;
3062 }
3063 ret = dup2(STDERR_FILENO, STDOUT_FILENO);
3064 if (ret < 0) {
3065 perror("redirecting stdout");
3066 close(outfd);
3067 goto out;
3068 }
3069 outf = fdopen(outfd, "a");
3070 if (outf == NULL) {
3071 fprintf(stderr, "cannot create dump stream\n");
3072 dup2(outfd, STDOUT_FILENO);
3073 close(outfd);
3074 goto out;
3075 }
4944defa 3076 stdout_metadump = true;
61983f67
BN
3077 } else {
3078 outf = fopen(argv[optind], "wb");
3079 if (outf == NULL) {
3080 print_warning("cannot create dump file");
449df236 3081 goto out;
61983f67
BN
3082 }
3083 }
3084
3085 exitcode = 0;
3086
3087 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
3088 if (!scan_ag(agno)) {
3089 exitcode = 1;
3090 break;
3091 }
3092 }
3093
3094 /* copy realtime and quota inode contents */
3095 if (!exitcode)
3096 exitcode = !copy_sb_inodes();
3097
3098 /* copy log if it's internal */
3099 if ((mp->m_sb.sb_logstart != 0) && !exitcode)
3100 exitcode = !copy_log();
3101
3102 /* write the remaining index */
3103 if (!exitcode)
878afc65 3104 exitcode = write_index() < 0;
61983f67
BN
3105
3106 if (progress_since_warning)
4944defa 3107 fputc('\n', stdout_metadump ? stderr : stdout);
61983f67 3108
449df236
DW
3109 if (stdout_metadump) {
3110 fflush(outf);
3111 fflush(stdout);
3112 ret = dup2(outfd, STDOUT_FILENO);
3113 if (ret < 0)
3114 perror("un-redirecting stdout");
a749e257 3115 stdout_metadump = false;
449df236
DW
3116 }
3117 fclose(outf);
61983f67
BN
3118
3119 /* cleanup iocur stack */
3120 while (iocur_sp > start_iocur_sp)
3121 pop_cur();
449df236 3122out:
61983f67
BN
3123 free(metablock);
3124
3125 return 0;
3126}