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