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