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