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