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