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