]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/dinode.c
xfs_repair: fix uninitialized variable warnings
[thirdparty/xfsprogs-dev.git] / repair / dinode.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a 7#include "libxfs.h"
2bd0ea18
NS
8#include "avl.h"
9#include "globals.h"
10#include "agheader.h"
11#include "incore.h"
12#include "protos.h"
13#include "err_protos.h"
2bd0ea18
NS
14#include "dir2.h"
15#include "dinode.h"
16#include "scan.h"
17#include "versions.h"
18#include "attr_repair.h"
19#include "bmap.h"
3b6ac903 20#include "threads.h"
9e0f480e
DW
21#include "slab.h"
22#include "rmap.h"
2bd0ea18 23
beed0dc8
DC
24/*
25 * gettext lookups for translations of strings use mutexes internally to
26 * the library. Hence when we come through here doing parallel scans in
27 * multiple AGs, then all do concurrent text conversions and serialise
28 * on the translation string lookups. Let's avoid doing repeated lookups
29 * by making them static variables and only assigning the translation
30 * once.
31 */
32static char *forkname_data;
33static char *forkname_attr;
34static char *ftype_real_time;
35static char *ftype_regular;
36
37void
38dinode_bmbt_translation_init(void)
39{
40 forkname_data = _("data");
41 forkname_attr = _("attr");
42 ftype_real_time = _("real-time");
43 ftype_regular = _("regular");
44}
45
46char *
47get_forkname(int whichfork)
48{
49
50 if (whichfork == XFS_DATA_FORK)
51 return forkname_data;
52 return forkname_attr;
53}
54
2bd0ea18
NS
55/*
56 * inode clearing routines
57 */
58
8b8a6b02 59static int
2bd0ea18
NS
60clear_dinode_attr(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
61{
56b2de80 62 ASSERT(dino->di_forkoff != 0);
2bd0ea18
NS
63
64 if (!no_modify)
5d1b7f0f
CH
65 fprintf(stderr,
66_("clearing inode %" PRIu64 " attributes\n"), ino_num);
2bd0ea18 67 else
5d1b7f0f
CH
68 fprintf(stderr,
69_("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
2bd0ea18 70
56b2de80 71 if (be16_to_cpu(dino->di_anextents) != 0) {
2bd0ea18
NS
72 if (no_modify)
73 return(1);
56b2de80 74 dino->di_anextents = cpu_to_be16(0);
2bd0ea18
NS
75 }
76
56b2de80 77 if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
2bd0ea18
NS
78 if (no_modify)
79 return(1);
56b2de80 80 dino->di_aformat = XFS_DINODE_FMT_EXTENTS;
2bd0ea18
NS
81 }
82
83 /* get rid of the fork by clearing forkoff */
84
85 /* Originally, when the attr repair code was added, the fork was cleared
86 * by turning it into shortform status. This meant clearing the
87 * hdr.totsize/count fields and also changing aformat to LOCAL
88 * (vs EXTENTS). Over various fixes, the aformat and forkoff have
89 * been updated to not show an attribute fork at all, however.
90 * It could be possible that resetting totsize/count are not needed,
dfc130f3 91 * but just to be safe, leave it in for now.
2bd0ea18
NS
92 */
93
94 if (!no_modify) {
95 xfs_attr_shortform_t *asf = (xfs_attr_shortform_t *)
46eca962 96 XFS_DFORK_APTR(dino);
5e656dbb
BN
97 asf->hdr.totsize = cpu_to_be16(sizeof(xfs_attr_sf_hdr_t));
98 asf->hdr.count = 0;
56b2de80 99 dino->di_forkoff = 0; /* got to do this after asf is set */
2bd0ea18
NS
100 }
101
102 /*
103 * always returns 1 since the fork gets zapped
104 */
105 return(1);
106}
107
0724d0f4 108static void
e0607266 109clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num)
2bd0ea18 110{
0724d0f4
ES
111 memset(dinoc, 0, sizeof(*dinoc));
112 dinoc->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
113 if (xfs_sb_version_hascrc(&mp->m_sb))
114 dinoc->di_version = 3;
115 else
116 dinoc->di_version = 2;
117 dinoc->di_gen = cpu_to_be32(random());
118 dinoc->di_format = XFS_DINODE_FMT_EXTENTS;
119 dinoc->di_aformat = XFS_DINODE_FMT_EXTENTS;
e0607266
DC
120 /* we are done for version 1/2 inodes */
121 if (dinoc->di_version < 3)
0724d0f4
ES
122 return;
123 dinoc->di_ino = cpu_to_be64(ino_num);
124 platform_uuid_copy(&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid);
125 return;
2bd0ea18
NS
126}
127
119383bf 128static void
2bd0ea18
NS
129clear_dinode_unlinked(xfs_mount_t *mp, xfs_dinode_t *dino)
130{
131
119383bf 132 dino->di_next_unlinked = cpu_to_be32(NULLAGINO);
2bd0ea18
NS
133}
134
135/*
136 * this clears the unlinked list too so it should not be called
137 * until after the agi unlinked lists are walked in phase 3.
2bd0ea18 138 */
0724d0f4 139static void
2bd0ea18
NS
140clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
141{
0724d0f4
ES
142 clear_dinode_core(mp, dino, ino_num);
143 clear_dinode_unlinked(mp, dino);
2bd0ea18
NS
144
145 /* and clear the forks */
0724d0f4
ES
146 memset(XFS_DFORK_DPTR(dino), 0, XFS_LITINO(mp, dino->di_version));
147 return;
2bd0ea18
NS
148}
149
150
151/*
152 * misc. inode-related utility routines
153 */
154
9234d416
BN
155/*
156 * verify_ag_bno is heavily used. In the common case, it
1e77098c 157 * performs just two number of compares
5e656dbb 158 * Returns 1 for bad ag/bno pair or 0 if it's valid.
1e77098c
MV
159 */
160static __inline int
161verify_ag_bno(xfs_sb_t *sbp,
162 xfs_agnumber_t agno,
163 xfs_agblock_t agbno)
164{
f8149110 165 if (agno < (sbp->sb_agcount - 1))
5e656dbb 166 return (agbno >= sbp->sb_agblocks);
f8149110 167 if (agno == (sbp->sb_agcount - 1))
5e656dbb 168 return (agbno >= (sbp->sb_dblocks -
5a35bf2c 169 ((xfs_rfsblock_t)(sbp->sb_agcount - 1) *
003e8e41 170 sbp->sb_agblocks)));
5e656dbb 171 return 1;
1e77098c
MV
172}
173
2bd0ea18
NS
174/*
175 * returns 0 if inode number is valid, 1 if bogus
176 */
177int
178verify_inum(xfs_mount_t *mp,
179 xfs_ino_t ino)
180{
181 xfs_agnumber_t agno;
182 xfs_agino_t agino;
183 xfs_agblock_t agbno;
184 xfs_sb_t *sbp = &mp->m_sb;;
185
186 /* range check ag #, ag block. range-checking offset is pointless */
187
188 agno = XFS_INO_TO_AGNO(mp, ino);
189 agino = XFS_INO_TO_AGINO(mp, ino);
190 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1e77098c
MV
191 if (agbno == 0)
192 return 1;
2bd0ea18
NS
193
194 if (ino == 0 || ino == NULLFSINO)
195 return(1);
196
197 if (ino != XFS_AGINO_TO_INO(mp, agno, agino))
198 return(1);
199
1e77098c 200 return verify_ag_bno(sbp, agno, agbno);
2bd0ea18
NS
201}
202
203/*
204 * have a separate routine to ensure that we don't accidentally
205 * lose illegally set bits in the agino by turning it into an FSINO
206 * to feed to the above routine
207 */
208int
209verify_aginum(xfs_mount_t *mp,
210 xfs_agnumber_t agno,
211 xfs_agino_t agino)
212{
213 xfs_agblock_t agbno;
214 xfs_sb_t *sbp = &mp->m_sb;;
215
216 /* range check ag #, ag block. range-checking offset is pointless */
217
218 if (agino == 0 || agino == NULLAGINO)
219 return(1);
220
221 /*
222 * agino's can't be too close to NULLAGINO because the min blocksize
223 * is 9 bits and at most 1 bit of that gets used for the inode offset
224 * so if the agino gets shifted by the # of offset bits and compared
225 * to the legal agbno values, a bogus agino will be too large. there
226 * will be extra bits set at the top that shouldn't be set.
227 */
228 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1e77098c
MV
229 if (agbno == 0)
230 return 1;
2bd0ea18 231
1e77098c 232 return verify_ag_bno(sbp, agno, agbno);
2bd0ea18
NS
233}
234
235/*
236 * return 1 if block number is good, 0 if out of range
237 */
238int
239verify_dfsbno(xfs_mount_t *mp,
5a35bf2c 240 xfs_fsblock_t fsbno)
2bd0ea18
NS
241{
242 xfs_agnumber_t agno;
243 xfs_agblock_t agbno;
244 xfs_sb_t *sbp = &mp->m_sb;;
245
246 /* range check ag #, ag block. range-checking offset is pointless */
247
248 agno = XFS_FSB_TO_AGNO(mp, fsbno);
249 agbno = XFS_FSB_TO_AGBNO(mp, fsbno);
250
1e77098c
MV
251 return verify_ag_bno(sbp, agno, agbno) == 0;
252}
2bd0ea18 253
1e77098c
MV
254#define XR_DFSBNORANGE_VALID 0
255#define XR_DFSBNORANGE_BADSTART 1
256#define XR_DFSBNORANGE_BADEND 2
257#define XR_DFSBNORANGE_OVERFLOW 3
258
259static __inline int
260verify_dfsbno_range(xfs_mount_t *mp,
5a35bf2c
DC
261 xfs_fsblock_t fsbno,
262 xfs_filblks_t count)
1e77098c
MV
263{
264 xfs_agnumber_t agno;
265 xfs_agblock_t agbno;
266 xfs_sb_t *sbp = &mp->m_sb;;
267
268 /* the start and end blocks better be in the same allocation group */
269 agno = XFS_FSB_TO_AGNO(mp, fsbno);
270 if (agno != XFS_FSB_TO_AGNO(mp, fsbno + count - 1)) {
271 return XR_DFSBNORANGE_OVERFLOW;
272 }
273
274 agbno = XFS_FSB_TO_AGBNO(mp, fsbno);
275 if (verify_ag_bno(sbp, agno, agbno)) {
276 return XR_DFSBNORANGE_BADSTART;
277 }
278
279 agbno = XFS_FSB_TO_AGBNO(mp, fsbno + count - 1);
280 if (verify_ag_bno(sbp, agno, agbno)) {
281 return XR_DFSBNORANGE_BADEND;
282 }
283
284 return (XR_DFSBNORANGE_VALID);
2bd0ea18
NS
285}
286
287int
288verify_agbno(xfs_mount_t *mp,
289 xfs_agnumber_t agno,
290 xfs_agblock_t agbno)
291{
292 xfs_sb_t *sbp = &mp->m_sb;;
293
294 /* range check ag #, ag block. range-checking offset is pointless */
1e77098c 295 return verify_ag_bno(sbp, agno, agbno) == 0;
2bd0ea18
NS
296}
297
2556c98b
BN
298static int
299process_rt_rec(
300 xfs_mount_t *mp,
e0a12bda 301 xfs_bmbt_irec_t *irec,
2556c98b 302 xfs_ino_t ino,
5a35bf2c 303 xfs_rfsblock_t *tot,
2556c98b
BN
304 int check_dups)
305{
5a35bf2c
DC
306 xfs_fsblock_t b;
307 xfs_rtblock_t ext;
2556c98b 308 int state;
2556c98b
BN
309 int pwe; /* partially-written extent */
310
2556c98b
BN
311 /*
312 * check numeric validity of the extent
313 */
e0a12bda 314 if (irec->br_startblock >= mp->m_sb.sb_rblocks) {
5d1b7f0f
CH
315 do_warn(
316_("inode %" PRIu64 " - bad rt extent start block number %" PRIu64 ", offset %" PRIu64 "\n"),
317 ino,
318 irec->br_startblock,
319 irec->br_startoff);
2556c98b
BN
320 return 1;
321 }
e0a12bda 322 if (irec->br_startblock + irec->br_blockcount - 1 >= mp->m_sb.sb_rblocks) {
5d1b7f0f
CH
323 do_warn(
324_("inode %" PRIu64 " - bad rt extent last block number %" PRIu64 ", offset %" PRIu64 "\n"),
325 ino,
326 irec->br_startblock + irec->br_blockcount - 1,
327 irec->br_startoff);
2556c98b
BN
328 return 1;
329 }
e0a12bda 330 if (irec->br_startblock + irec->br_blockcount - 1 < irec->br_startblock) {
5d1b7f0f
CH
331 do_warn(
332_("inode %" PRIu64 " - bad rt extent overflows - start %" PRIu64 ", "
333 "end %" PRIu64 ", offset %" PRIu64 "\n"),
334 ino,
335 irec->br_startblock,
336 irec->br_startblock + irec->br_blockcount - 1,
337 irec->br_startoff);
2556c98b
BN
338 return 1;
339 }
340
2556c98b
BN
341 /*
342 * set the appropriate number of extents
8961bfde 343 * this iterates block by block, this can be optimised using extents
2556c98b 344 */
e0a12bda
BN
345 for (b = irec->br_startblock; b < irec->br_startblock +
346 irec->br_blockcount; b += mp->m_sb.sb_rextsize) {
5a35bf2c 347 ext = (xfs_rtblock_t) b / mp->m_sb.sb_rextsize;
b7fdeb4d 348 pwe = irec->br_state == XFS_EXT_UNWRITTEN &&
2556c98b
BN
349 (b % mp->m_sb.sb_rextsize != 0);
350
351 if (check_dups == 1) {
352 if (search_rt_dup_extent(mp, ext) && !pwe) {
5d1b7f0f
CH
353 do_warn(
354_("data fork in rt ino %" PRIu64 " claims dup rt extent,"
355 "off - %" PRIu64 ", start - %" PRIu64 ", count %" PRIu64 "\n"),
356 ino,
357 irec->br_startoff,
358 irec->br_startblock,
359 irec->br_blockcount);
2556c98b
BN
360 return 1;
361 }
362 continue;
363 }
364
95650c4d 365 state = get_rtbmap(ext);
2556c98b 366 switch (state) {
95650c4d
BN
367 case XR_E_FREE:
368 case XR_E_UNKNOWN:
369 set_rtbmap(ext, XR_E_INUSE);
370 break;
371 case XR_E_BAD_STATE:
5d1b7f0f
CH
372 do_error(
373_("bad state in rt block map %" PRIu64 "\n"),
374 ext);
95650c4d
BN
375 case XR_E_FS_MAP:
376 case XR_E_INO:
377 case XR_E_INUSE_FS:
5d1b7f0f
CH
378 do_error(
379_("data fork in rt inode %" PRIu64 " found metadata block %" PRIu64 " in rt bmap\n"),
95650c4d
BN
380 ino, ext);
381 case XR_E_INUSE:
382 if (pwe)
2556c98b 383 break;
a93fcc04 384 /* fall through */
95650c4d
BN
385 case XR_E_MULT:
386 set_rtbmap(ext, XR_E_MULT);
5d1b7f0f
CH
387 do_warn(
388_("data fork in rt inode %" PRIu64 " claims used rt block %" PRIu64 "\n"),
389 ino, ext);
95650c4d
BN
390 return 1;
391 case XR_E_FREE1:
392 default:
5d1b7f0f
CH
393 do_error(
394_("illegal state %d in rt block map %" PRIu64 "\n"),
395 state, b);
2556c98b
BN
396 }
397 }
398
399 /*
400 * bump up the block counter
401 */
e0a12bda 402 *tot += irec->br_blockcount;
2556c98b
BN
403
404 return 0;
405}
3b6ac903 406
2bd0ea18
NS
407/*
408 * return 1 if inode should be cleared, 0 otherwise
409 * if check_dups should be set to 1, that implies that
410 * the primary purpose of this call is to see if the
411 * file overlaps with any duplicate extents (in the
412 * duplicate extent list).
413 */
8b8a6b02 414static int
2bd0ea18
NS
415process_bmbt_reclist_int(
416 xfs_mount_t *mp,
e0a12bda 417 xfs_bmbt_rec_t *rp,
e1f43b4c 418 int *numrecs,
2bd0ea18
NS
419 int type,
420 xfs_ino_t ino,
5a35bf2c 421 xfs_rfsblock_t *tot,
2bd0ea18 422 blkmap_t **blkmapp,
5a35bf2c
DC
423 xfs_fileoff_t *first_key,
424 xfs_fileoff_t *last_key,
2bd0ea18
NS
425 int check_dups,
426 int whichfork)
427{
e0a12bda 428 xfs_bmbt_irec_t irec;
5a35bf2c
DC
429 xfs_filblks_t cp = 0; /* prev count */
430 xfs_fsblock_t sp = 0; /* prev start */
431 xfs_fileoff_t op = 0; /* prev offset */
432 xfs_fsblock_t b;
2bd0ea18 433 char *ftype;
beed0dc8 434 char *forkname = get_forkname(whichfork);
2bd0ea18
NS
435 int i;
436 int state;
1e77098c
MV
437 xfs_agnumber_t agno;
438 xfs_agblock_t agbno;
8961bfde
BN
439 xfs_agblock_t ebno;
440 xfs_extlen_t blen;
2556c98b
BN
441 xfs_agnumber_t locked_agno = -1;
442 int error = 1;
2bd0ea18 443
2bd0ea18 444 if (type == XR_INO_RTDATA)
beed0dc8 445 ftype = ftype_real_time;
2bd0ea18 446 else
beed0dc8 447 ftype = ftype_regular;
2bd0ea18 448
e1f43b4c 449 for (i = 0; i < *numrecs; i++) {
ff105f75 450 libxfs_bmbt_disk_get_all((rp +i), &irec);
2bd0ea18 451 if (i == 0)
e0a12bda 452 *last_key = *first_key = irec.br_startoff;
2bd0ea18 453 else
e0a12bda
BN
454 *last_key = irec.br_startoff;
455 if (i > 0 && op + cp > irec.br_startoff) {
5d1b7f0f
CH
456 do_warn(
457_("bmap rec out of order, inode %" PRIu64" entry %d "
458 "[o s c] [%" PRIu64 " %" PRIu64 " %" PRIu64 "], "
459 "%d [%" PRIu64 " %" PRIu64 " %" PRIu64 "]\n"),
e0a12bda
BN
460 ino, i, irec.br_startoff, irec.br_startblock,
461 irec.br_blockcount, i - 1, op, sp, cp);
2556c98b 462 goto done;
2bd0ea18 463 }
e0a12bda
BN
464 op = irec.br_startoff;
465 cp = irec.br_blockcount;
466 sp = irec.br_startblock;
2bd0ea18
NS
467
468 /*
469 * check numeric validity of the extent
470 */
e0a12bda 471 if (irec.br_blockcount == 0) {
5d1b7f0f
CH
472 do_warn(
473_("zero length extent (off = %" PRIu64 ", fsbno = %" PRIu64 ") in ino %" PRIu64 "\n"),
474 irec.br_startoff,
475 irec.br_startblock,
476 ino);
2556c98b 477 goto done;
2bd0ea18
NS
478 }
479
2556c98b 480 if (type == XR_INO_RTDATA && whichfork == XFS_DATA_FORK) {
2bd0ea18 481 /*
2556c98b
BN
482 * realtime bitmaps don't use AG locks, so returning
483 * immediately is fine for this code path.
2bd0ea18 484 */
e0a12bda 485 if (process_rt_rec(mp, &irec, ino, tot, check_dups))
2556c98b 486 return 1;
2bd0ea18 487 /*
e0a12bda 488 * skip rest of loop processing since that'irec.br_startblock
2bd0ea18
NS
489 * all for regular file forks and attr forks
490 */
491 continue;
492 }
493
2bd0ea18
NS
494 /*
495 * regular file data fork or attribute fork
496 */
e0a12bda
BN
497 switch (verify_dfsbno_range(mp, irec.br_startblock,
498 irec.br_blockcount)) {
2556c98b
BN
499 case XR_DFSBNORANGE_VALID:
500 break;
501
502 case XR_DFSBNORANGE_BADSTART:
5d1b7f0f
CH
503 do_warn(
504_("inode %" PRIu64 " - bad extent starting block number %" PRIu64 ", offset %" PRIu64 "\n"),
505 ino,
506 irec.br_startblock,
e0a12bda 507 irec.br_startoff);
2556c98b
BN
508 goto done;
509
510 case XR_DFSBNORANGE_BADEND:
5d1b7f0f
CH
511 do_warn(
512_("inode %" PRIu64 " - bad extent last block number %" PRIu64 ", offset %" PRIu64 "\n"),
513 ino,
514 irec.br_startblock + irec.br_blockcount - 1,
515 irec.br_startoff);
2556c98b
BN
516 goto done;
517
518 case XR_DFSBNORANGE_OVERFLOW:
5d1b7f0f
CH
519 do_warn(
520_("inode %" PRIu64 " - bad extent overflows - start %" PRIu64 ", "
521 "end %" PRIu64 ", offset %" PRIu64 "\n"),
522 ino,
523 irec.br_startblock,
524 irec.br_startblock + irec.br_blockcount - 1,
525 irec.br_startoff);
2556c98b
BN
526 goto done;
527 }
7511a9cf
ES
528 /* Ensure this extent does not extend beyond the max offset */
529 if (irec.br_startoff + irec.br_blockcount - 1 >
530 fs_max_file_offset) {
5d1b7f0f 531 do_warn(
7511a9cf
ES
532_("inode %" PRIu64 " - extent exceeds max offset - start %" PRIu64 ", "
533 "count %" PRIu64 ", physical block %" PRIu64 "\n"),
534 ino, irec.br_startoff, irec.br_blockcount,
535 irec.br_startblock);
2556c98b
BN
536 goto done;
537 }
538
75372fed 539 if (blkmapp && *blkmapp) {
ea4a8de1
BM
540 int error2;
541 error2 = blkmap_set_ext(blkmapp, irec.br_startoff,
e0a12bda 542 irec.br_startblock, irec.br_blockcount);
ea4a8de1 543 if (error2) {
75372fed
DC
544 /*
545 * we don't want to clear the inode due to an
546 * internal bmap tracking error, but if we've
547 * run out of memory then we simply can't
548 * validate that the filesystem is consistent.
549 * Hence just abort at this point with an ENOMEM
550 * error.
551 */
552 do_abort(
553_("Fatal error: inode %" PRIu64 " - blkmap_set_ext(): %s\n"
554 "\t%s fork, off - %" PRIu64 ", start - %" PRIu64 ", cnt %" PRIu64 "\n"),
ea4a8de1 555 ino, strerror(error2), forkname,
75372fed
DC
556 irec.br_startoff, irec.br_startblock,
557 irec.br_blockcount);
558 }
559 }
560
1e77098c
MV
561 /*
562 * Profiling shows that the following loop takes the
563 * most time in all of xfs_repair.
564 */
e0a12bda
BN
565 agno = XFS_FSB_TO_AGNO(mp, irec.br_startblock);
566 agbno = XFS_FSB_TO_AGBNO(mp, irec.br_startblock);
8961bfde 567 ebno = agbno + irec.br_blockcount;
2556c98b
BN
568 if (agno != locked_agno) {
569 if (locked_agno != -1)
586f8abf
DC
570 pthread_mutex_unlock(&ag_locks[locked_agno].lock);
571 pthread_mutex_lock(&ag_locks[agno].lock);
2556c98b
BN
572 locked_agno = agno;
573 }
574
575 if (check_dups) {
576 /*
577 * if we're just checking the bmap for dups,
578 * return if we find one, otherwise, continue
579 * checking each entry without setting the
580 * block bitmap
581 */
a406779b
DW
582 if (!(type == XR_INO_DATA &&
583 xfs_sb_version_hasreflink(&mp->m_sb)) &&
584 search_dup_extent(agno, agbno, ebno)) {
5d1b7f0f
CH
585 do_warn(
586_("%s fork in ino %" PRIu64 " claims dup extent, "
587 "off - %" PRIu64 ", start - %" PRIu64 ", cnt %" PRIu64 "\n"),
79872d6e
BN
588 forkname, ino, irec.br_startoff,
589 irec.br_startblock,
590 irec.br_blockcount);
591 goto done;
dfc130f3 592 }
e0a12bda 593 *tot += irec.br_blockcount;
2556c98b
BN
594 continue;
595 }
dfc130f3 596
8961bfde
BN
597 for (b = irec.br_startblock;
598 agbno < ebno;
599 b += blen, agbno += blen) {
600 state = get_bmap_ext(agno, agbno, ebno, &blen);
2bd0ea18
NS
601 switch (state) {
602 case XR_E_FREE:
603 case XR_E_FREE1:
5d1b7f0f
CH
604 do_warn(
605_("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"),
14f8b681 606 forkname, ino, (uint64_t) b);
2bd0ea18 607 /* fall through ... */
0f94fa4b 608 case XR_E_INUSE1: /* seen by rmap */
2bd0ea18 609 case XR_E_UNKNOWN:
2bd0ea18 610 break;
2556c98b 611
2bd0ea18 612 case XR_E_BAD_STATE:
5d1b7f0f 613 do_error(_("bad state in block map %" PRIu64 "\n"), b);
2556c98b 614
0f94fa4b
DW
615 case XR_E_FS_MAP1:
616 case XR_E_INO1:
617 case XR_E_INUSE_FS1:
618 do_warn(_("rmap claims metadata use!\n"));
619 /* fall through */
2bd0ea18
NS
620 case XR_E_FS_MAP:
621 case XR_E_INO:
622 case XR_E_INUSE_FS:
85c9f7f4 623 case XR_E_REFC:
5d1b7f0f
CH
624 do_warn(
625_("%s fork in inode %" PRIu64 " claims metadata block %" PRIu64 "\n"),
626 forkname, ino, b);
2556c98b
BN
627 goto done;
628
2bd0ea18
NS
629 case XR_E_INUSE:
630 case XR_E_MULT:
a406779b
DW
631 if (type == XR_INO_DATA &&
632 xfs_sb_version_hasreflink(&mp->m_sb))
633 break;
5d1b7f0f
CH
634 do_warn(
635_("%s fork in %s inode %" PRIu64 " claims used block %" PRIu64 "\n"),
636 forkname, ftype, ino, b);
2556c98b
BN
637 goto done;
638
85c9f7f4
DW
639 case XR_E_COW:
640 do_warn(
641_("%s fork in %s inode %" PRIu64 " claims CoW block %" PRIu64 "\n"),
642 forkname, ftype, ino, b);
643 goto done;
644
2bd0ea18 645 default:
5d1b7f0f
CH
646 do_error(
647_("illegal state %d in block map %" PRIu64 "\n"),
2bd0ea18 648 state, b);
bf678507
DW
649 goto done;
650 }
651 }
652
653 /*
654 * Update the internal extent map only after we've checked
655 * every block in this extent. The first time we reject this
656 * data fork we'll try to rebuild the bmbt from rmap data.
657 * After a successful rebuild we'll try this scan again.
658 * (If the rebuild fails we won't come back here.)
659 */
660 agbno = XFS_FSB_TO_AGBNO(mp, irec.br_startblock);
661 ebno = agbno + irec.br_blockcount;
662 for (; agbno < ebno; agbno += blen) {
663 state = get_bmap_ext(agno, agbno, ebno, &blen);
664 switch (state) {
665 case XR_E_FREE:
666 case XR_E_FREE1:
667 case XR_E_INUSE1:
668 case XR_E_UNKNOWN:
669 set_bmap_ext(agno, agbno, blen, XR_E_INUSE);
670 break;
671 case XR_E_INUSE:
672 case XR_E_MULT:
673 set_bmap_ext(agno, agbno, blen, XR_E_MULT);
674 break;
675 default:
676 break;
2bd0ea18
NS
677 }
678 }
9e0f480e 679 if (collect_rmaps) { /* && !check_dups */
2d273771 680 error = rmap_add_rec(mp, ino, whichfork, &irec);
9e0f480e
DW
681 if (error)
682 do_error(
683_("couldn't add reverse mapping\n")
684 );
685 }
e0a12bda 686 *tot += irec.br_blockcount;
2bd0ea18 687 }
2556c98b
BN
688 error = 0;
689done:
690 if (locked_agno != -1)
586f8abf 691 pthread_mutex_unlock(&ag_locks[locked_agno].lock);
e1f43b4c
CH
692
693 if (i != *numrecs) {
694 ASSERT(i < *numrecs);
695 do_warn(_("correcting nextents for inode %" PRIu64 "\n"), ino);
696 *numrecs = i;
697 }
698
2556c98b 699 return error;
2bd0ea18
NS
700}
701
702/*
703 * return 1 if inode should be cleared, 0 otherwise, sets block bitmap
704 * as a side-effect
705 */
706int
707process_bmbt_reclist(
708 xfs_mount_t *mp,
5e656dbb 709 xfs_bmbt_rec_t *rp,
e1f43b4c 710 int *numrecs,
2bd0ea18
NS
711 int type,
712 xfs_ino_t ino,
5a35bf2c 713 xfs_rfsblock_t *tot,
2bd0ea18 714 blkmap_t **blkmapp,
5a35bf2c
DC
715 xfs_fileoff_t *first_key,
716 xfs_fileoff_t *last_key,
2bd0ea18
NS
717 int whichfork)
718{
5e656dbb
BN
719 return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot,
720 blkmapp, first_key, last_key, 0, whichfork);
2bd0ea18
NS
721}
722
723/*
724 * return 1 if inode should be cleared, 0 otherwise, does not set
725 * block bitmap
726 */
727int
728scan_bmbt_reclist(
729 xfs_mount_t *mp,
5e656dbb 730 xfs_bmbt_rec_t *rp,
e1f43b4c 731 int *numrecs,
2bd0ea18
NS
732 int type,
733 xfs_ino_t ino,
5a35bf2c 734 xfs_rfsblock_t *tot,
2bd0ea18
NS
735 int whichfork)
736{
5a35bf2c
DC
737 xfs_fileoff_t first_key = 0;
738 xfs_fileoff_t last_key = 0;
2bd0ea18 739
5e656dbb
BN
740 return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot,
741 NULL, &first_key, &last_key, 1, whichfork);
2bd0ea18
NS
742}
743
744/*
15028317
DW
745 * Grab the buffer backing an inode. This is meant for routines that
746 * work with inodes one at a time in any order (like walking the
747 * unlinked lists to look for inodes). The caller is responsible for
748 * writing/releasing the buffer.
2bd0ea18 749 */
15028317
DW
750struct xfs_buf *
751get_agino_buf(
752 struct xfs_mount *mp,
753 xfs_agnumber_t agno,
754 xfs_agino_t agino,
755 struct xfs_dinode **dipp)
2bd0ea18 756{
15028317
DW
757 struct xfs_buf *bp;
758 int cluster_size;
759 int ino_per_cluster;
760 xfs_agino_t cluster_agino;
761 xfs_daddr_t cluster_daddr;
762 xfs_daddr_t cluster_blks;
2bd0ea18 763
15028317
DW
764 /*
765 * Inode buffers have been read into memory in inode_cluster_size
766 * chunks (or one FSB). To find the correct buffer for an inode,
767 * we must find the buffer for its cluster, add the appropriate
768 * offset, and return that.
769 */
68d16907 770 cluster_size = max(mp->m_inode_cluster_size, mp->m_sb.sb_blocksize);
15028317
DW
771 ino_per_cluster = cluster_size / mp->m_sb.sb_inodesize;
772 cluster_agino = agino & ~(ino_per_cluster - 1);
68d16907 773 cluster_blks = XFS_FSB_TO_DADDR(mp, max(1,
2703398a 774 mp->m_inode_cluster_size >> mp->m_sb.sb_blocklog));
15028317
DW
775 cluster_daddr = XFS_AGB_TO_DADDR(mp, agno,
776 XFS_AGINO_TO_AGBNO(mp, cluster_agino));
777
778#ifdef XR_INODE_TRACE
779 printf("cluster_size %d ipc %d clusagino %d daddr %lld sectors %lld\n",
780 cluster_size, ino_per_cluster, cluster_agino, cluster_daddr,
781 cluster_blks);
782#endif
783
784 bp = libxfs_readbuf(mp->m_dev, cluster_daddr, cluster_blks,
785 0, &xfs_inode_buf_ops);
2bd0ea18 786 if (!bp) {
5d1b7f0f 787 do_warn(_("cannot read inode (%u/%u), disk block %" PRIu64 "\n"),
15028317
DW
788 agno, cluster_agino, cluster_daddr);
789 return NULL;
2bd0ea18
NS
790 }
791
15028317
DW
792 *dipp = xfs_make_iptr(mp, bp, agino - cluster_agino);
793 ASSERT(!xfs_sb_version_hascrc(&mp->m_sb) ||
794 XFS_AGINO_TO_INO(mp, agno, agino) ==
795 be64_to_cpu((*dipp)->di_ino));
796 return bp;
2bd0ea18
NS
797}
798
2bd0ea18
NS
799/*
800 * higher level inode processing stuff starts here:
801 * first, one utility routine for each type of inode
802 */
803
804/*
805 * return 1 if inode should be cleared, 0 otherwise
806 */
8b8a6b02 807static int
2bd0ea18
NS
808process_btinode(
809 xfs_mount_t *mp,
810 xfs_agnumber_t agno,
811 xfs_agino_t ino,
812 xfs_dinode_t *dip,
813 int type,
814 int *dirty,
5a35bf2c 815 xfs_rfsblock_t *tot,
14f8b681 816 uint64_t *nex,
2bd0ea18
NS
817 blkmap_t **blkmapp,
818 int whichfork,
819 int check_dups)
820{
821 xfs_bmdr_block_t *dib;
5a35bf2c
DC
822 xfs_fileoff_t last_key;
823 xfs_fileoff_t first_key = 0;
2bd0ea18
NS
824 xfs_ino_t lino;
825 xfs_bmbt_ptr_t *pp;
826 xfs_bmbt_key_t *pkey;
beed0dc8 827 char *forkname = get_forkname(whichfork);
2bd0ea18 828 int i;
9234d416
BN
829 int level;
830 int numrecs;
2bd0ea18 831 bmap_cursor_t cursor;
14f8b681 832 uint64_t magic;
2bd0ea18 833
46eca962 834 dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
2bd0ea18
NS
835 lino = XFS_AGINO_TO_INO(mp, agno, ino);
836 *tot = 0;
837 *nex = 0;
838
e0607266
DC
839 magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_BMAP_CRC_MAGIC
840 : XFS_BMAP_MAGIC;
841
5e656dbb
BN
842 level = be16_to_cpu(dib->bb_level);
843 numrecs = be16_to_cpu(dib->bb_numrecs);
9234d416
BN
844
845 if ((level == 0) || (level > XFS_BM_MAXLEVELS(mp, whichfork))) {
2bd0ea18 846 /*
2bd0ea18
NS
847 * XXX - if we were going to fix up the inode,
848 * we'd try to treat the fork as an interior
849 * node and see if we could get an accurate
850 * level value from one of the blocks pointed
851 * to by the pointers in the fork. For now
852 * though, we just bail (and blow out the inode).
853 */
5d1b7f0f
CH
854 do_warn(
855_("bad level %d in inode %" PRIu64 " bmap btree root block\n"),
9234d416
BN
856 level, XFS_AGINO_TO_INO(mp, agno, ino));
857 return(1);
858 }
859 if (numrecs == 0) {
5d1b7f0f
CH
860 do_warn(
861_("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"),
2bd0ea18
NS
862 XFS_AGINO_TO_INO(mp, agno, ino));
863 return(1);
864 }
865 /*
866 * use bmdr/dfork_dsize since the root block is in the data fork
867 */
5e656dbb 868 if (XFS_BMDR_SPACE_CALC(numrecs) > XFS_DFORK_SIZE(dip, mp, whichfork)) {
2bd0ea18 869 do_warn(
507f4e33 870 _("indicated size of %s btree root (%d bytes) greater than space in "
5d1b7f0f 871 "inode %" PRIu64 " %s fork\n"),
9234d416 872 forkname, XFS_BMDR_SPACE_CALC(numrecs), lino, forkname);
2bd0ea18
NS
873 return(1);
874 }
875
9234d416
BN
876 init_bm_cursor(&cursor, level + 1);
877
b3563c19 878 pp = XFS_BMDR_PTR_ADDR(dib, 1,
e2f60652 879 libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0));
b3563c19 880 pkey = XFS_BMDR_KEY_ADDR(dib, 1);
5a35bf2c 881 last_key = NULLFILEOFF;
2bd0ea18 882
9234d416 883 for (i = 0; i < numrecs; i++) {
2bd0ea18
NS
884 /*
885 * XXX - if we were going to do more to fix up the inode
886 * btree, we'd do it right here. For now, if there's a
887 * problem, we'll bail out and presumably clear the inode.
888 */
fb36a55d
ES
889 if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) {
890 do_warn(
891_("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"),
892 get_unaligned_be64(&pp[i]), lino);
2bd0ea18
NS
893 return(1);
894 }
895
fb36a55d
ES
896 if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt,
897 type, whichfork, lino, tot, nex, blkmapp,
898 &cursor, 1, check_dups, magic,
899 &xfs_bmbt_buf_ops))
2bd0ea18
NS
900 return(1);
901 /*
902 * fix key (offset) mismatches between the keys in root
903 * block records and the first key of each child block.
904 * fixes cases where entries have been shifted between
905 * blocks but the parent hasn't been updated
906 */
5e656dbb 907 if (!check_dups && cursor.level[level-1].first_key !=
fb36a55d 908 get_unaligned_be64(&pkey[i].br_startoff)) {
2bd0ea18
NS
909 if (!no_modify) {
910 do_warn(
fb36a55d
ES
911_("correcting key in bmbt root (was %" PRIu64 ", now %" PRIu64") in inode "
912 "%" PRIu64" %s fork\n"),
913 get_unaligned_be64(&pkey[i].br_startoff),
914 cursor.level[level-1].first_key,
915 XFS_AGINO_TO_INO(mp, agno, ino),
916 forkname);
2bd0ea18 917 *dirty = 1;
fb36a55d
ES
918 put_unaligned_be64(
919 cursor.level[level-1].first_key,
920 &pkey[i].br_startoff);
2bd0ea18
NS
921 } else {
922 do_warn(
fb36a55d
ES
923_("bad key in bmbt root (is %" PRIu64 ", would reset to %" PRIu64 ") in inode "
924 "%" PRIu64 " %s fork\n"),
925 get_unaligned_be64(&pkey[i].br_startoff),
926 cursor.level[level-1].first_key,
927 XFS_AGINO_TO_INO(mp, agno, ino),
928 forkname);
2bd0ea18
NS
929 }
930 }
931 /*
932 * make sure that keys are in ascending order. blow out
933 * inode if the ordering doesn't hold
934 */
935 if (check_dups == 0) {
5a35bf2c 936 if (last_key != NULLFILEOFF && last_key >=
9234d416 937 cursor.level[level-1].first_key) {
2bd0ea18 938 do_warn(
5d1b7f0f 939 _("out of order bmbt root key %" PRIu64 " in inode %" PRIu64 " %s fork\n"),
2bd0ea18
NS
940 first_key,
941 XFS_AGINO_TO_INO(mp, agno, ino),
942 forkname);
943 return(1);
944 }
9234d416 945 last_key = cursor.level[level-1].first_key;
2bd0ea18
NS
946 }
947 }
2e10b140
ES
948 /*
949 * Ideally if all the extents are ok (perhaps after further
950 * checks below?) we'd just move this back into extents format.
951 * But for now clear it, as the kernel will choke on this
952 */
953 if (*nex <= XFS_DFORK_SIZE(dip, mp, whichfork) /
954 sizeof(xfs_bmbt_rec_t)) {
955 do_warn(
5d1b7f0f 956 _("extent count for ino %" PRIu64 " %s fork too low (%" PRIu64 ") for file format\n"),
2e10b140
ES
957 lino, forkname, *nex);
958 return(1);
959 }
2bd0ea18
NS
960 /*
961 * Check that the last child block's forward sibling pointer
962 * is NULL.
963 */
964 if (check_dups == 0 &&
5a35bf2c 965 cursor.level[0].right_fsbno != NULLFSBLOCK) {
2bd0ea18 966 do_warn(
5a35bf2c 967 _("bad fwd (right) sibling pointer (saw %" PRIu64 " should be NULLFSBLOCK)\n"),
2bd0ea18
NS
968 cursor.level[0].right_fsbno);
969 do_warn(
5d1b7f0f 970 _("\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"),
2bd0ea18
NS
971 XFS_AGINO_TO_INO(mp, agno, ino), forkname,
972 cursor.level[0].fsbno);
973 return(1);
974 }
dfc130f3 975
2bd0ea18
NS
976 return(0);
977}
978
979/*
980 * return 1 if inode should be cleared, 0 otherwise
981 */
8b8a6b02 982static int
2bd0ea18
NS
983process_exinode(
984 xfs_mount_t *mp,
985 xfs_agnumber_t agno,
986 xfs_agino_t ino,
987 xfs_dinode_t *dip,
988 int type,
989 int *dirty,
5a35bf2c 990 xfs_rfsblock_t *tot,
14f8b681 991 uint64_t *nex,
2bd0ea18
NS
992 blkmap_t **blkmapp,
993 int whichfork,
994 int check_dups)
995{
996 xfs_ino_t lino;
5e656dbb 997 xfs_bmbt_rec_t *rp;
5a35bf2c
DC
998 xfs_fileoff_t first_key;
999 xfs_fileoff_t last_key;
5fa28531 1000 int32_t numrecs;
e1f43b4c 1001 int ret;
2bd0ea18
NS
1002
1003 lino = XFS_AGINO_TO_INO(mp, agno, ino);
5e656dbb 1004 rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
2bd0ea18 1005 *tot = 0;
e1f43b4c
CH
1006 numrecs = XFS_DFORK_NEXTENTS(dip, whichfork);
1007
5fa28531
DC
1008 /*
1009 * We've already decided on the maximum number of extents on the inode,
1010 * and numrecs may be corrupt. Hence make sure we only allow numrecs to
1011 * be in the range of valid on-disk numbers, which is:
1012 * 0 < numrecs < 2^31 - 1
1013 */
1014 if (numrecs < 0)
1015 numrecs = *nex;
1016
2bd0ea18
NS
1017 /*
1018 * XXX - if we were going to fix up the btree record,
1019 * we'd do it right here. For now, if there's a problem,
1020 * we'll bail out and presumably clear the inode.
1021 */
1022 if (check_dups == 0)
e1f43b4c 1023 ret = process_bmbt_reclist(mp, rp, &numrecs, type, lino,
2bd0ea18 1024 tot, blkmapp, &first_key, &last_key,
e1f43b4c 1025 whichfork);
2bd0ea18 1026 else
e1f43b4c
CH
1027 ret = scan_bmbt_reclist(mp, rp, &numrecs, type, lino, tot,
1028 whichfork);
1029
1030 *nex = numrecs;
1031 return ret;
2bd0ea18
NS
1032}
1033
1034/*
1035 * return 1 if inode should be cleared, 0 otherwise
1036 */
5e656dbb 1037static int
2bd0ea18
NS
1038process_lclinode(
1039 xfs_mount_t *mp,
1040 xfs_agnumber_t agno,
1041 xfs_agino_t ino,
1042 xfs_dinode_t *dip,
5e656dbb 1043 int whichfork)
2bd0ea18
NS
1044{
1045 xfs_attr_shortform_t *asf;
2bd0ea18
NS
1046 xfs_ino_t lino;
1047
2bd0ea18 1048 lino = XFS_AGINO_TO_INO(mp, agno, ino);
56b2de80 1049 if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_size) >
5e656dbb 1050 XFS_DFORK_DSIZE(dip, mp)) {
2bd0ea18 1051 do_warn(
5d1b7f0f
CH
1052 _("local inode %" PRIu64 " data fork is too large (size = %lld, max = %d)\n"),
1053 lino, (unsigned long long) be64_to_cpu(dip->di_size),
46eca962 1054 XFS_DFORK_DSIZE(dip, mp));
2bd0ea18
NS
1055 return(1);
1056 } else if (whichfork == XFS_ATTR_FORK) {
5e656dbb
BN
1057 asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
1058 if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) {
2bd0ea18 1059 do_warn(
5d1b7f0f 1060 _("local inode %" PRIu64 " attr fork too large (size %d, max = %d)\n"),
5e656dbb 1061 lino, be16_to_cpu(asf->hdr.totsize),
46eca962 1062 XFS_DFORK_ASIZE(dip, mp));
2bd0ea18
NS
1063 return(1);
1064 }
5e656dbb 1065 if (be16_to_cpu(asf->hdr.totsize) < sizeof(xfs_attr_sf_hdr_t)) {
2bd0ea18 1066 do_warn(
5d1b7f0f 1067 _("local inode %" PRIu64 " attr too small (size = %d, min size = %zd)\n"),
5e656dbb 1068 lino, be16_to_cpu(asf->hdr.totsize),
507f4e33 1069 sizeof(xfs_attr_sf_hdr_t));
2bd0ea18
NS
1070 return(1);
1071 }
1072 }
1073
1074 return(0);
1075}
1076
8b8a6b02 1077static int
2bd0ea18
NS
1078process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino)
1079{
5a35bf2c 1080 xfs_fileoff_t expected_offset;
e0a12bda
BN
1081 xfs_bmbt_rec_t *rp;
1082 xfs_bmbt_irec_t irec;
2bd0ea18
NS
1083 int numrecs;
1084 int i;
1085 int max_blocks;
2bd0ea18 1086
56b2de80 1087 if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
f8149110 1088 if (dino->di_format == XFS_DINODE_FMT_LOCAL)
5e656dbb 1089 return 0;
5d1b7f0f
CH
1090 do_warn(
1091_("mismatch between format (%d) and size (%" PRId64 ") in symlink ino %" PRIu64 "\n"),
1092 dino->di_format,
14f8b681 1093 (int64_t)be64_to_cpu(dino->di_size), lino);
5e656dbb
BN
1094 return 1;
1095 }
56b2de80 1096 if (dino->di_format == XFS_DINODE_FMT_LOCAL) {
5d1b7f0f 1097 do_warn(
b52923f3 1098_("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu64 "\n"),
5d1b7f0f 1099 dino->di_format,
14f8b681 1100 (int64_t)be64_to_cpu(dino->di_size), lino);
5e656dbb 1101 return 1;
2bd0ea18
NS
1102 }
1103
5e656dbb 1104 rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
56b2de80 1105 numrecs = be32_to_cpu(dino->di_nextents);
2bd0ea18
NS
1106
1107 /*
1108 * the max # of extents in a symlink inode is equal to the
dfc130f3 1109 * number of max # of blocks required to store the symlink
2bd0ea18
NS
1110 */
1111 if (numrecs > max_symlink_blocks) {
1112 do_warn(
5d1b7f0f 1113_("bad number of extents (%d) in symlink %" PRIu64 " data fork\n"),
2bd0ea18
NS
1114 numrecs, lino);
1115 return(1);
1116 }
1117
1118 max_blocks = max_symlink_blocks;
1119 expected_offset = 0;
1120
5e656dbb 1121 for (i = 0; i < numrecs; i++) {
ff105f75 1122 libxfs_bmbt_disk_get_all((rp +i), &irec);
e0a12bda 1123 if (irec.br_startoff != expected_offset) {
2bd0ea18 1124 do_warn(
5d1b7f0f 1125_("bad extent #%d offset (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"),
e0a12bda 1126 i, irec.br_startoff, lino);
2bd0ea18
NS
1127 return(1);
1128 }
e0a12bda 1129 if (irec.br_blockcount == 0 || irec.br_blockcount > max_blocks) {
2bd0ea18 1130 do_warn(
5d1b7f0f 1131_("bad extent #%d count (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"),
e0a12bda 1132 i, irec.br_blockcount, lino);
2bd0ea18
NS
1133 return(1);
1134 }
1135
e0a12bda
BN
1136 max_blocks -= irec.br_blockcount;
1137 expected_offset += irec.br_blockcount;
2bd0ea18
NS
1138 }
1139
1140 return(0);
1141}
1142
1143/*
1144 * takes a name and length and returns 1 if the name contains
1145 * a \0, returns 0 otherwise
1146 */
8b8a6b02 1147static int
2bd0ea18
NS
1148null_check(char *name, int length)
1149{
1150 int i;
1151
5a707ca1 1152 ASSERT(length < XFS_SYMLINK_MAXLEN);
2bd0ea18
NS
1153
1154 for (i = 0; i < length; i++, name++) {
1155 if (*name == '\0')
1156 return(1);
1157 }
1158
1159 return(0);
1160}
1161
5857dce9
ES
1162/*
1163 * This does /not/ do quotacheck, it validates the basic quota
1164 * inode metadata, checksums, etc.
1165 */
1166#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0)
1167static int
1168process_quota_inode(
1169 struct xfs_mount *mp,
1170 xfs_ino_t lino,
1171 struct xfs_dinode *dino,
1172 uint ino_type,
1173 struct blkmap *blkmap)
1174{
1175 xfs_fsblock_t fsbno;
1176 struct xfs_buf *bp;
1177 xfs_filblks_t dqchunklen;
1178 uint dqperchunk;
83695f94
DW
1179 int quota_type = 0;
1180 char *quota_string = NULL;
5857dce9
ES
1181 xfs_dqid_t dqid;
1182 xfs_fileoff_t qbno;
1183 int i;
1184 int t = 0;
1185
1186 switch (ino_type) {
1187 case XR_INO_UQUOTA:
1188 quota_type = XFS_DQ_USER;
1189 quota_string = _("User quota");
1190 break;
1191 case XR_INO_GQUOTA:
1192 quota_type = XFS_DQ_GROUP;
1193 quota_string = _("Group quota");
1194 break;
1195 case XR_INO_PQUOTA:
1196 quota_type = XFS_DQ_PROJ;
1197 quota_string = _("Project quota");
1198 break;
1199 default:
1200 ASSERT(0);
1201 }
1202
1203 dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
585acbe8 1204 dqperchunk = libxfs_calc_dquots_per_chunk(dqchunklen);
5857dce9
ES
1205 dqid = 0;
1206 qbno = NULLFILEOFF;
1207
1208 while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != NULLFILEOFF) {
1209 xfs_dqblk_t *dqb;
1210 int writebuf = 0;
1211
1212 fsbno = blkmap_get(blkmap, qbno);
1213 dqid = (xfs_dqid_t)qbno * dqperchunk;
1214
1215 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
1216 dqchunklen, 0, &xfs_dquot_buf_ops);
1217 if (!bp) {
1218 do_warn(
1219_("cannot read inode %" PRIu64 ", file block %" PRIu64 ", disk block %" PRIu64 "\n"),
1220 lino, qbno, fsbno);
1221 return 1;
1222 }
1223
1224 dqb = bp->b_addr;
1225 for (i = 0; i < dqperchunk; i++, dqid++, dqb++) {
5857dce9
ES
1226 int bad_dqb = 0;
1227
1228 /* We only print the first problem we find */
1229 if (xfs_sb_version_hascrc(&mp->m_sb)) {
585acbe8
ES
1230 if (!libxfs_verify_cksum((char *)dqb,
1231 sizeof(*dqb),
5857dce9
ES
1232 XFS_DQUOT_CRC_OFF)) {
1233 do_warn(_("%s: bad CRC for id %u. "),
1234 quota_string, dqid);
1235 bad_dqb = 1;
1236 goto bad;
1237 }
1238
1239 if (!uuid_equal(&dqb->dd_uuid,
1240 &mp->m_sb.sb_meta_uuid)) {
1241 do_warn(_("%s: bad UUID for id %u. "),
1242 quota_string, dqid);
1243 bad_dqb = 1;
1244 goto bad;
1245 }
1246 }
585acbe8 1247 if (libxfs_dquot_verify(mp, &dqb->dd_diskdq, dqid,
160942bc 1248 quota_type) != NULL) {
5857dce9
ES
1249 do_warn(_("%s: Corrupt quota for id %u. "),
1250 quota_string, dqid);
1251 bad_dqb = 1;
1252 }
1253
1254bad:
1255 if (bad_dqb) {
1256 if (no_modify)
1257 do_warn(_("Would correct.\n"));
1258 else {
1259 do_warn(_("Corrected.\n"));
e1d3178a 1260 libxfs_dqblk_repair(mp, dqb,
585acbe8 1261 dqid, quota_type);
5857dce9
ES
1262 writebuf = 1;
1263 }
1264 }
1265 }
1266
1267 if (writebuf && !no_modify)
1268 libxfs_writebuf(bp, 0);
1269 else
1270 libxfs_putbuf(bp);
1271 }
1272 return 0;
1273}
1274
2019931a
DC
1275static int
1276process_symlink_remote(
1277 struct xfs_mount *mp,
1278 xfs_ino_t lino,
1279 struct xfs_dinode *dino,
1280 struct blkmap *blkmap,
1281 char *dst)
1282{
5a35bf2c 1283 xfs_fsblock_t fsbno;
2019931a
DC
1284 struct xfs_buf *bp;
1285 char *src;
1286 int pathlen;
1287 int offset;
1288 int i;
1289
1290 offset = 0;
1291 pathlen = be64_to_cpu(dino->di_size);
1292 i = 0;
1293
1294 while (pathlen > 0) {
1295 int blk_cnt = 1;
1296 int byte_cnt;
7cb3f7fe 1297 int badcrc = 0;
2019931a
DC
1298
1299 fsbno = blkmap_get(blkmap, i);
5a35bf2c 1300 if (fsbno == NULLFSBLOCK) {
2019931a
DC
1301 do_warn(
1302_("cannot read inode %" PRIu64 ", file block %d, NULL disk block\n"),
1303 lino, i);
1304 return 1;
1305 }
1306
1307 /*
1308 * There's a symlink header for each contiguous extent. If
1309 * there are contiguous blocks, read them in one go.
1310 */
1311 while (blk_cnt <= max_symlink_blocks) {
1312 if (blkmap_get(blkmap, i + 1) != fsbno + 1)
1313 break;
1314 blk_cnt++;
1315 i++;
1316 }
1317
1318 byte_cnt = XFS_FSB_TO_B(mp, blk_cnt);
1319
1320 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno),
1321 BTOBB(byte_cnt), 0, &xfs_symlink_buf_ops);
1322 if (!bp) {
1323 do_warn(
1324_("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
1325 lino, i, fsbno);
1326 return 1;
1327 }
d2be29d4
DW
1328 if (bp->b_error == -EFSCORRUPTED) {
1329 do_warn(
1330_("Corrupt symlink remote block %" PRIu64 ", inode %" PRIu64 ".\n"),
1331 fsbno, lino);
1332 libxfs_putbuf(bp);
1333 return 1;
1334 }
12b53197 1335 if (bp->b_error == -EFSBADCRC) {
7cb3f7fe
DC
1336 do_warn(
1337_("Bad symlink buffer CRC, block %" PRIu64 ", inode %" PRIu64 ".\n"
1338 "Correcting CRC, but symlink may be bad.\n"), fsbno, lino);
1339 badcrc = 1;
1340 }
2019931a
DC
1341
1342 byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
68d16907 1343 byte_cnt = min(pathlen, byte_cnt);
2019931a
DC
1344
1345 src = bp->b_addr;
1346 if (xfs_sb_version_hascrc(&mp->m_sb)) {
ff105f75
DC
1347 if (!libxfs_symlink_hdr_ok(lino, offset,
1348 byte_cnt, bp)) {
2019931a
DC
1349 do_warn(
1350_("bad symlink header ino %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
1351 lino, i, fsbno);
1352 libxfs_putbuf(bp);
1353 return 1;
1354 }
1355 src += sizeof(struct xfs_dsymlink_hdr);
1356 }
1357
1358 memmove(dst + offset, src, byte_cnt);
1359
1360 pathlen -= byte_cnt;
1361 offset += byte_cnt;
1362 i++;
1363
7cb3f7fe
DC
1364 if (badcrc && !no_modify)
1365 libxfs_writebuf(bp, 0);
1366 else
1367 libxfs_putbuf(bp);
2019931a
DC
1368 }
1369 return 0;
1370}
1371
2bd0ea18
NS
1372/*
1373 * like usual, returns 0 if everything's ok and 1 if something's
1374 * bogus
1375 */
8b8a6b02 1376static int
0459b626
BN
1377process_symlink(
1378 xfs_mount_t *mp,
1379 xfs_ino_t lino,
1380 xfs_dinode_t *dino,
1381 blkmap_t *blkmap)
2bd0ea18 1382{
2116b6a6 1383 char *symlink;
5a707ca1 1384 char data[XFS_SYMLINK_MAXLEN];
2bd0ea18
NS
1385
1386 /*
1387 * check size against kernel symlink limits. we know
1388 * size is consistent with inode storage format -- e.g.
1389 * the inode is structurally ok so we don't have to check
1390 * for that
1391 */
5a707ca1 1392 if (be64_to_cpu(dino->di_size) >= XFS_SYMLINK_MAXLEN) {
5d1b7f0f
CH
1393 do_warn(_("symlink in inode %" PRIu64 " too long (%llu chars)\n"),
1394 lino, (unsigned long long) be64_to_cpu(dino->di_size));
2bd0ea18
NS
1395 return(1);
1396 }
1397
948ade75
BF
1398 if (be64_to_cpu(dino->di_size) == 0) {
1399 do_warn(_("zero size symlink in inode %" PRIu64 "\n"), lino);
1400 return 1;
1401 }
1402
2bd0ea18
NS
1403 /*
1404 * have to check symlink component by component.
1405 * get symlink contents into data area
1406 */
1407 symlink = &data[0];
56b2de80 1408 if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
2bd0ea18
NS
1409 /*
1410 * local symlink, just copy the symlink out of the
1411 * inode into the data area
1412 */
f8149110 1413 memmove(symlink, XFS_DFORK_DPTR(dino),
56b2de80 1414 be64_to_cpu(dino->di_size));
2bd0ea18 1415 } else {
2019931a 1416 int error;
e0607266 1417
2019931a
DC
1418 error = process_symlink_remote(mp, lino, dino, blkmap, symlink);
1419 if (error)
1420 return error;
2bd0ea18 1421 }
2019931a 1422
56b2de80 1423 data[be64_to_cpu(dino->di_size)] = '\0';
2bd0ea18
NS
1424
1425 /*
1426 * check for nulls
1427 */
56b2de80 1428 if (null_check(symlink, be64_to_cpu(dino->di_size))) {
507f4e33 1429 do_warn(
5d1b7f0f 1430_("found illegal null character in symlink inode %" PRIu64 "\n"),
2bd0ea18
NS
1431 lino);
1432 return(1);
1433 }
1434
2bd0ea18
NS
1435 return(0);
1436}
1437
1438/*
1439 * called to process the set of misc inode special inode types
1440 * that have no associated data storage (fifos, pipes, devices, etc.).
1441 */
0459b626 1442static int
2bd0ea18
NS
1443process_misc_ino_types(xfs_mount_t *mp,
1444 xfs_dinode_t *dino,
1445 xfs_ino_t lino,
1446 int type)
1447{
1448 /*
1449 * disallow mountpoint inodes until such time as the
1450 * kernel actually allows them to be created (will
1451 * probably require a superblock version rev, sigh).
1452 */
1453 if (type == XR_INO_MOUNTPOINT) {
5d1b7f0f
CH
1454 do_warn(
1455_("inode %" PRIu64 " has bad inode type (IFMNT)\n"), lino);
2bd0ea18
NS
1456 return(1);
1457 }
1458
1459 /*
1460 * must also have a zero size
1461 */
56b2de80 1462 if (be64_to_cpu(dino->di_size) != 0) {
2bd0ea18
NS
1463 switch (type) {
1464 case XR_INO_CHRDEV:
5d1b7f0f
CH
1465 do_warn(
1466_("size of character device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1467 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1468 break;
1469 case XR_INO_BLKDEV:
5d1b7f0f
CH
1470 do_warn(
1471_("size of block device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1472 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1473 break;
1474 case XR_INO_SOCK:
5d1b7f0f
CH
1475 do_warn(
1476_("size of socket inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1477 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1478 break;
1479 case XR_INO_FIFO:
5d1b7f0f
CH
1480 do_warn(
1481_("size of fifo inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1482 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18 1483 break;
5857dce9
ES
1484 case XR_INO_UQUOTA:
1485 case XR_INO_GQUOTA:
1486 case XR_INO_PQUOTA:
1487 do_warn(
1488_("size of quota inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
1489 (int64_t)be64_to_cpu(dino->di_size));
1490 break;
2bd0ea18 1491 default:
507f4e33
NS
1492 do_warn(_("Internal error - process_misc_ino_types, "
1493 "illegal type %d\n"), type);
2bd0ea18
NS
1494 abort();
1495 }
1496
1497 return(1);
1498 }
1499
1500 return(0);
1501}
1502
5e656dbb 1503static int
5a35bf2c 1504process_misc_ino_types_blocks(xfs_rfsblock_t totblocks, xfs_ino_t lino, int type)
2bd0ea18
NS
1505{
1506 /*
1507 * you can not enforce all misc types have zero data fork blocks
56b2de80 1508 * by checking dino->di_nblocks because atotblocks (attribute
2bd0ea18 1509 * blocks) are part of nblocks. We must check this later when atotblocks
dfc130f3 1510 * has been calculated or by doing a simple check that anExtents == 0.
2bd0ea18
NS
1511 * We must also guarantee that totblocks is 0. Thus nblocks checking
1512 * will be done later in process_dinode_int for misc types.
1513 */
1514
1515 if (totblocks != 0) {
1516 switch (type) {
1517 case XR_INO_CHRDEV:
1518 do_warn(
5d1b7f0f 1519_("size of character device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1520 lino, totblocks);
1521 break;
1522 case XR_INO_BLKDEV:
1523 do_warn(
5d1b7f0f 1524_("size of block device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1525 lino, totblocks);
1526 break;
1527 case XR_INO_SOCK:
1528 do_warn(
5d1b7f0f 1529_("size of socket inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1530 lino, totblocks);
1531 break;
1532 case XR_INO_FIFO:
1533 do_warn(
5d1b7f0f 1534_("size of fifo inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1535 lino, totblocks);
1536 break;
1537 default:
1538 return(0);
1539 }
1540 return(1);
1541 }
1542 return (0);
1543}
1544
0459b626
BN
1545static inline int
1546dinode_fmt(
56b2de80 1547 xfs_dinode_t *dino)
2bd0ea18 1548{
56b2de80 1549 return be16_to_cpu(dino->di_mode) & S_IFMT;
0459b626 1550}
2bd0ea18 1551
0459b626
BN
1552static inline void
1553change_dinode_fmt(
56b2de80 1554 xfs_dinode_t *dino,
0459b626
BN
1555 int new_fmt)
1556{
56b2de80 1557 int mode = be16_to_cpu(dino->di_mode);
2bd0ea18 1558
0459b626 1559 ASSERT((new_fmt & ~S_IFMT) == 0);
2bd0ea18 1560
0459b626
BN
1561 mode &= ~S_IFMT;
1562 mode |= new_fmt;
56b2de80 1563 dino->di_mode = cpu_to_be16(mode);
0459b626
BN
1564}
1565
1566static int
1567check_dinode_mode_format(
56b2de80 1568 xfs_dinode_t *dinoc)
0459b626 1569{
5e656dbb 1570 if (dinoc->di_format >= XFS_DINODE_FMT_UUID)
0459b626
BN
1571 return -1; /* FMT_UUID is not used */
1572
1573 switch (dinode_fmt(dinoc)) {
1574 case S_IFIFO:
1575 case S_IFCHR:
1576 case S_IFBLK:
1577 case S_IFSOCK:
1578 return (dinoc->di_format != XFS_DINODE_FMT_DEV) ? -1 : 0;
1579
1580 case S_IFDIR:
1581 return (dinoc->di_format < XFS_DINODE_FMT_LOCAL ||
1582 dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0;
1583
1584 case S_IFREG:
1585 return (dinoc->di_format < XFS_DINODE_FMT_EXTENTS ||
1586 dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0;
1587
1588 case S_IFLNK:
1589 return (dinoc->di_format < XFS_DINODE_FMT_LOCAL ||
1590 dinoc->di_format > XFS_DINODE_FMT_EXTENTS) ? -1 : 0;
1591
1592 default: ;
1593 }
1594 return 0; /* invalid modes are checked elsewhere */
1595}
1596
1597/*
1598 * If inode is a superblock inode, does type check to make sure is it valid.
1599 * Returns 0 if it's valid, non-zero if it needs to be cleared.
1600 */
1601
1602static int
1603process_check_sb_inodes(
1604 xfs_mount_t *mp,
56b2de80 1605 xfs_dinode_t *dinoc,
0459b626
BN
1606 xfs_ino_t lino,
1607 int *type,
1608 int *dirty)
1609{
1610 if (lino == mp->m_sb.sb_rootino) {
5857dce9 1611 if (*type != XR_INO_DIR) {
5d1b7f0f 1612 do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1613 lino, dinode_fmt(dinoc));
1614 *type = XR_INO_DIR;
2bd0ea18 1615 if (!no_modify) {
0459b626
BN
1616 do_warn(_("resetting to directory\n"));
1617 change_dinode_fmt(dinoc, S_IFDIR);
2bd0ea18 1618 *dirty = 1;
0459b626
BN
1619 } else
1620 do_warn(_("would reset to directory\n"));
2bd0ea18 1621 }
0459b626 1622 return 0;
2bd0ea18 1623 }
0459b626 1624 if (lino == mp->m_sb.sb_uquotino) {
5857dce9 1625 if (*type != XR_INO_UQUOTA) {
5d1b7f0f 1626 do_warn(_("user quota inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1627 lino, dinode_fmt(dinoc));
1628 mp->m_sb.sb_uquotino = NULLFSINO;
1629 return 1;
1630 }
1631 return 0;
1632 }
1633 if (lino == mp->m_sb.sb_gquotino) {
5857dce9 1634 if (*type != XR_INO_GQUOTA) {
5d1b7f0f 1635 do_warn(_("group quota inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1636 lino, dinode_fmt(dinoc));
1637 mp->m_sb.sb_gquotino = NULLFSINO;
1638 return 1;
1639 }
1640 return 0;
1641 }
0340d706 1642 if (lino == mp->m_sb.sb_pquotino) {
5857dce9 1643 if (*type != XR_INO_PQUOTA) {
0340d706
CS
1644 do_warn(_("project quota inode %" PRIu64 " has bad type 0x%x\n"),
1645 lino, dinode_fmt(dinoc));
1646 mp->m_sb.sb_pquotino = NULLFSINO;
1647 return 1;
1648 }
1649 return 0;
1650 }
0459b626
BN
1651 if (lino == mp->m_sb.sb_rsumino) {
1652 if (*type != XR_INO_RTSUM) {
5d1b7f0f
CH
1653 do_warn(
1654_("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
0459b626 1655 lino, dinode_fmt(dinoc));
2bd0ea18 1656 if (!no_modify) {
0459b626
BN
1657 do_warn(_("resetting to regular file\n"));
1658 change_dinode_fmt(dinoc, S_IFREG);
2bd0ea18 1659 *dirty = 1;
2bd0ea18 1660 } else {
0459b626 1661 do_warn(_("would reset to regular file\n"));
2bd0ea18 1662 }
2bd0ea18 1663 }
0459b626 1664 if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
5d1b7f0f
CH
1665 do_warn(
1666_("bad # of extents (%u) for realtime summary inode %" PRIu64 "\n"),
0459b626
BN
1667 be32_to_cpu(dinoc->di_nextents), lino);
1668 return 1;
1669 }
1670 return 0;
2bd0ea18 1671 }
0459b626
BN
1672 if (lino == mp->m_sb.sb_rbmino) {
1673 if (*type != XR_INO_RTBITMAP) {
5d1b7f0f
CH
1674 do_warn(
1675_("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
0459b626 1676 lino, dinode_fmt(dinoc));
2bd0ea18 1677 if (!no_modify) {
0459b626
BN
1678 do_warn(_("resetting to regular file\n"));
1679 change_dinode_fmt(dinoc, S_IFREG);
2bd0ea18 1680 *dirty = 1;
0459b626
BN
1681 } else {
1682 do_warn(_("would reset to regular file\n"));
2bd0ea18 1683 }
2bd0ea18 1684 }
0459b626 1685 if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
5d1b7f0f
CH
1686 do_warn(
1687_("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"),
0459b626
BN
1688 be32_to_cpu(dinoc->di_nextents), lino);
1689 return 1;
2bd0ea18 1690 }
0459b626
BN
1691 return 0;
1692 }
1693 return 0;
1694}
2bd0ea18 1695
0459b626
BN
1696/*
1697 * general size/consistency checks:
1698 *
1699 * if the size <= size of the data fork, directories must be
1700 * local inodes unlike regular files which would be extent inodes.
1701 * all the other mentioned types have to have a zero size value.
1702 *
1703 * if the size and format don't match, get out now rather than
1704 * risk trying to process a non-existent extents or btree
1705 * type data fork.
1706 */
1707static int
1708process_check_inode_sizes(
1709 xfs_mount_t *mp,
1710 xfs_dinode_t *dino,
1711 xfs_ino_t lino,
1712 int type)
1713{
56b2de80 1714 xfs_fsize_t size = be64_to_cpu(dino->di_size);
2bd0ea18 1715
0459b626 1716 switch (type) {
2bd0ea18 1717
0459b626
BN
1718 case XR_INO_DIR:
1719 if (size <= XFS_DFORK_DSIZE(dino, mp) &&
56b2de80 1720 dino->di_format != XFS_DINODE_FMT_LOCAL) {
5d1b7f0f
CH
1721 do_warn(
1722_("mismatch between format (%d) and size (%" PRId64 ") in directory ino %" PRIu64 "\n"),
56b2de80 1723 dino->di_format, size, lino);
0459b626 1724 return 1;
2bd0ea18 1725 }
42237e34 1726 if (size > XFS_DIR2_LEAF_OFFSET) {
5d1b7f0f
CH
1727 do_warn(
1728_("directory inode %" PRIu64 " has bad size %" PRId64 "\n"),
42237e34
BN
1729 lino, size);
1730 return 1;
1731 }
0459b626 1732 break;
2bd0ea18 1733
0459b626
BN
1734 case XR_INO_SYMLINK:
1735 if (process_symlink_extlist(mp, lino, dino)) {
5d1b7f0f 1736 do_warn(_("bad data fork in symlink %" PRIu64 "\n"), lino);
0459b626
BN
1737 return 1;
1738 }
1739 break;
2bd0ea18 1740
0459b626
BN
1741 case XR_INO_CHRDEV: /* fall through to FIFO case ... */
1742 case XR_INO_BLKDEV: /* fall through to FIFO case ... */
1743 case XR_INO_SOCK: /* fall through to FIFO case ... */
1744 case XR_INO_MOUNTPOINT: /* fall through to FIFO case ... */
1745 case XR_INO_FIFO:
1746 if (process_misc_ino_types(mp, dino, lino, type))
1747 return 1;
1748 break;
2bd0ea18 1749
5857dce9
ES
1750 case XR_INO_UQUOTA:
1751 case XR_INO_GQUOTA:
1752 case XR_INO_PQUOTA:
1753 /* Quota inodes have same restrictions as above types */
1754 if (process_misc_ino_types(mp, dino, lino, type))
1755 return 1;
1756 break;
1757
0459b626
BN
1758 case XR_INO_RTDATA:
1759 /*
1760 * if we have no realtime blocks, any inode claiming
1761 * to be a real-time file is bogus
1762 */
1763 if (mp->m_sb.sb_rblocks == 0) {
5d1b7f0f
CH
1764 do_warn(
1765_("found inode %" PRIu64 " claiming to be a real-time file\n"), lino);
0459b626 1766 return 1;
2bd0ea18 1767 }
0459b626 1768 break;
2bd0ea18 1769
0459b626 1770 case XR_INO_RTBITMAP:
14f8b681 1771 if (size != (int64_t)mp->m_sb.sb_rbmblocks *
0459b626 1772 mp->m_sb.sb_blocksize) {
5d1b7f0f
CH
1773 do_warn(
1774_("realtime bitmap inode %" PRIu64 " has bad size %" PRId64 " (should be %" PRIu64 ")\n"),
1775 lino, size,
14f8b681 1776 (int64_t) mp->m_sb.sb_rbmblocks *
0459b626
BN
1777 mp->m_sb.sb_blocksize);
1778 return 1;
1779 }
1780 break;
2bd0ea18 1781
0459b626
BN
1782 case XR_INO_RTSUM:
1783 if (size != mp->m_rsumsize) {
5d1b7f0f
CH
1784 do_warn(
1785_("realtime summary inode %" PRIu64 " has bad size %" PRId64 " (should be %d)\n"),
0459b626
BN
1786 lino, size, mp->m_rsumsize);
1787 return 1;
1788 }
1789 break;
2bd0ea18 1790
0459b626
BN
1791 default:
1792 break;
1793 }
1794 return 0;
1795}
2bd0ea18 1796
0459b626
BN
1797/*
1798 * check for illegal values of forkoff
1799 */
1800static int
1801process_check_inode_forkoff(
1802 xfs_mount_t *mp,
56b2de80 1803 xfs_dinode_t *dino,
0459b626
BN
1804 xfs_ino_t lino)
1805{
56b2de80 1806 if (dino->di_forkoff == 0)
0459b626 1807 return 0;
2bd0ea18 1808
56b2de80 1809 switch (dino->di_format) {
0459b626 1810 case XFS_DINODE_FMT_DEV:
56b2de80 1811 if (dino->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3)) {
5d1b7f0f
CH
1812 do_warn(
1813_("bad attr fork offset %d in dev inode %" PRIu64 ", should be %d\n"),
1814 dino->di_forkoff, lino,
0459b626
BN
1815 (int)(roundup(sizeof(xfs_dev_t), 8) >> 3));
1816 return 1;
1817 }
2bd0ea18 1818 break;
0459b626
BN
1819 case XFS_DINODE_FMT_LOCAL: /* fall through ... */
1820 case XFS_DINODE_FMT_EXTENTS: /* fall through ... */
1821 case XFS_DINODE_FMT_BTREE:
49f693fa
DC
1822 if (dino->di_forkoff >=
1823 (XFS_LITINO(mp, dino->di_version) >> 3)) {
5d1b7f0f
CH
1824 do_warn(
1825_("bad attr fork offset %d in inode %" PRIu64 ", max=%d\n"),
1826 dino->di_forkoff, lino,
49f693fa 1827 XFS_LITINO(mp, dino->di_version) >> 3);
0459b626
BN
1828 return 1;
1829 }
2bd0ea18 1830 break;
2bd0ea18 1831 default:
56b2de80 1832 do_error(_("unexpected inode format %d\n"), dino->di_format);
0459b626 1833 break;
2bd0ea18 1834 }
0459b626
BN
1835 return 0;
1836}
2bd0ea18 1837
0459b626
BN
1838/*
1839 * Updates the inodes block and extent counts if they are wrong
1840 */
1841static int
1842process_inode_blocks_and_extents(
56b2de80 1843 xfs_dinode_t *dino,
5a35bf2c 1844 xfs_rfsblock_t nblocks,
14f8b681
DW
1845 uint64_t nextents,
1846 uint64_t anextents,
0459b626
BN
1847 xfs_ino_t lino,
1848 int *dirty)
1849{
56b2de80 1850 if (nblocks != be64_to_cpu(dino->di_nblocks)) {
2bd0ea18 1851 if (!no_modify) {
5d1b7f0f
CH
1852 do_warn(
1853_("correcting nblocks for inode %" PRIu64 ", was %llu - counted %" PRIu64 "\n"), lino,
1854 (unsigned long long) be64_to_cpu(dino->di_nblocks),
1855 nblocks);
56b2de80 1856 dino->di_nblocks = cpu_to_be64(nblocks);
0459b626 1857 *dirty = 1;
2bd0ea18 1858 } else {
5d1b7f0f
CH
1859 do_warn(
1860_("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
1861 (unsigned long long) be64_to_cpu(dino->di_nblocks),
1862 lino, nblocks);
2bd0ea18
NS
1863 }
1864 }
1865
0459b626 1866 if (nextents > MAXEXTNUM) {
5d1b7f0f
CH
1867 do_warn(
1868_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
0459b626
BN
1869 nextents, lino);
1870 return 1;
1871 }
56b2de80 1872 if (nextents != be32_to_cpu(dino->di_nextents)) {
2bd0ea18 1873 if (!no_modify) {
5d1b7f0f
CH
1874 do_warn(
1875_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
1876 lino,
1877 be32_to_cpu(dino->di_nextents),
1878 nextents);
56b2de80 1879 dino->di_nextents = cpu_to_be32(nextents);
0459b626 1880 *dirty = 1;
2bd0ea18 1881 } else {
5d1b7f0f
CH
1882 do_warn(
1883_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
1884 be32_to_cpu(dino->di_nextents),
0459b626 1885 lino, nextents);
2bd0ea18
NS
1886 }
1887 }
1888
0459b626 1889 if (anextents > MAXAEXTNUM) {
5d1b7f0f
CH
1890 do_warn(
1891_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
0459b626
BN
1892 anextents, lino);
1893 return 1;
2bd0ea18 1894 }
56b2de80 1895 if (anextents != be16_to_cpu(dino->di_anextents)) {
2bd0ea18 1896 if (!no_modify) {
5d1b7f0f
CH
1897 do_warn(
1898_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
1899 lino,
56b2de80
DC
1900 be16_to_cpu(dino->di_anextents), anextents);
1901 dino->di_anextents = cpu_to_be16(anextents);
0459b626
BN
1902 *dirty = 1;
1903 } else {
5d1b7f0f
CH
1904 do_warn(
1905_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
1906 be16_to_cpu(dino->di_anextents),
0459b626 1907 lino, anextents);
2bd0ea18 1908 }
2bd0ea18 1909 }
e1f43b4c
CH
1910
1911 /*
1912 * We are comparing different units here, but that's fine given that
1913 * an extent has to have at least a block in it.
1914 */
1915 if (nblocks < nextents + anextents) {
1916 do_warn(
1917_("nblocks (%" PRIu64 ") smaller than nextents for inode %" PRIu64 "\n"), nblocks, lino);
1918 return 1;
1919 }
1920
0459b626
BN
1921 return 0;
1922}
2bd0ea18 1923
0459b626
BN
1924/*
1925 * check data fork -- if it's bad, clear the inode
1926 */
1927static int
1928process_inode_data_fork(
1929 xfs_mount_t *mp,
1930 xfs_agnumber_t agno,
1931 xfs_agino_t ino,
1932 xfs_dinode_t *dino,
1933 int type,
1934 int *dirty,
5a35bf2c 1935 xfs_rfsblock_t *totblocks,
14f8b681 1936 uint64_t *nextents,
0459b626
BN
1937 blkmap_t **dblkmap,
1938 int check_dups)
1939{
0459b626
BN
1940 xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
1941 int err = 0;
5fa28531
DC
1942 int nex;
1943
1944 /*
1945 * extent count on disk is only valid for positive values. The kernel
1946 * uses negative values in memory. hence if we see negative numbers
1947 * here, trash it!
1948 */
1949 nex = be32_to_cpu(dino->di_nextents);
1950 if (nex < 0)
1951 *nextents = 1;
1952 else
1953 *nextents = nex;
2bd0ea18 1954
56b2de80 1955 if (*nextents > be64_to_cpu(dino->di_nblocks))
0459b626 1956 *nextents = 1;
2bd0ea18 1957
5fa28531 1958
56b2de80 1959 if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA)
610f3285 1960 *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK);
0459b626 1961 *nextents = 0;
2bd0ea18 1962
56b2de80 1963 switch (dino->di_format) {
2bd0ea18 1964 case XFS_DINODE_FMT_LOCAL:
5e656dbb
BN
1965 err = process_lclinode(mp, agno, ino, dino, XFS_DATA_FORK);
1966 *totblocks = 0;
2bd0ea18
NS
1967 break;
1968 case XFS_DINODE_FMT_EXTENTS:
0459b626
BN
1969 err = process_exinode(mp, agno, ino, dino, type, dirty,
1970 totblocks, nextents, dblkmap, XFS_DATA_FORK,
1971 check_dups);
2bd0ea18
NS
1972 break;
1973 case XFS_DINODE_FMT_BTREE:
0459b626
BN
1974 err = process_btinode(mp, agno, ino, dino, type, dirty,
1975 totblocks, nextents, dblkmap, XFS_DATA_FORK,
1976 check_dups);
2bd0ea18
NS
1977 break;
1978 case XFS_DINODE_FMT_DEV: /* fall through */
2bd0ea18
NS
1979 err = 0;
1980 break;
1981 default:
5d1b7f0f 1982 do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"),
56b2de80 1983 dino->di_format, lino, be16_to_cpu(dino->di_mode));
2bd0ea18
NS
1984 }
1985
1986 if (err) {
5d1b7f0f 1987 do_warn(_("bad data fork in inode %" PRIu64 "\n"), lino);
2bd0ea18 1988 if (!no_modify) {
0724d0f4
ES
1989 clear_dinode(mp, dino, lino);
1990 *dirty += 1;
2bd0ea18 1991 }
0459b626 1992 return 1;
2bd0ea18
NS
1993 }
1994
1995 if (check_dups) {
1996 /*
1997 * if check_dups was non-zero, we have to
1998 * re-process data fork to set bitmap since the
1999 * bitmap wasn't set the first time through
2000 */
56b2de80 2001 switch (dino->di_format) {
2bd0ea18 2002 case XFS_DINODE_FMT_LOCAL:
f8149110 2003 err = process_lclinode(mp, agno, ino, dino,
5e656dbb 2004 XFS_DATA_FORK);
2bd0ea18
NS
2005 break;
2006 case XFS_DINODE_FMT_EXTENTS:
2007 err = process_exinode(mp, agno, ino, dino, type,
0459b626 2008 dirty, totblocks, nextents, dblkmap,
2bd0ea18
NS
2009 XFS_DATA_FORK, 0);
2010 break;
2011 case XFS_DINODE_FMT_BTREE:
2012 err = process_btinode(mp, agno, ino, dino, type,
0459b626 2013 dirty, totblocks, nextents, dblkmap,
2bd0ea18
NS
2014 XFS_DATA_FORK, 0);
2015 break;
2016 case XFS_DINODE_FMT_DEV: /* fall through */
2bd0ea18
NS
2017 err = 0;
2018 break;
2019 default:
5d1b7f0f 2020 do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"),
56b2de80
DC
2021 dino->di_format, lino,
2022 be16_to_cpu(dino->di_mode));
2bd0ea18
NS
2023 }
2024
0459b626
BN
2025 if (no_modify && err != 0)
2026 return 1;
2bd0ea18
NS
2027
2028 ASSERT(err == 0);
2029 }
0459b626
BN
2030 return 0;
2031}
2bd0ea18 2032
0459b626
BN
2033/*
2034 * Process extended attribute fork in inode
2035 */
2036static int
2037process_inode_attr_fork(
2038 xfs_mount_t *mp,
2039 xfs_agnumber_t agno,
2040 xfs_agino_t ino,
2041 xfs_dinode_t *dino,
2042 int type,
2043 int *dirty,
5a35bf2c 2044 xfs_rfsblock_t *atotblocks,
14f8b681 2045 uint64_t *anextents,
0459b626
BN
2046 int check_dups,
2047 int extra_attr_check,
2048 int *retval)
2049{
0459b626
BN
2050 xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
2051 blkmap_t *ablkmap = NULL;
2052 int repair = 0;
2053 int err;
2054
2055 if (!XFS_DFORK_Q(dino)) {
2056 *anextents = 0;
56b2de80 2057 if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
5d1b7f0f 2058 do_warn(_("bad attribute format %d in inode %" PRIu64 ", "),
56b2de80 2059 dino->di_aformat, lino);
0459b626
BN
2060 if (!no_modify) {
2061 do_warn(_("resetting value\n"));
56b2de80 2062 dino->di_aformat = XFS_DINODE_FMT_EXTENTS;
0459b626
BN
2063 *dirty = 1;
2064 } else
2065 do_warn(_("would reset value\n"));
2066 }
2067 return 0;
2068 }
2bd0ea18 2069
56b2de80
DC
2070 *anextents = be16_to_cpu(dino->di_anextents);
2071 if (*anextents > be64_to_cpu(dino->di_nblocks))
0459b626
BN
2072 *anextents = 1;
2073
56b2de80 2074 switch (dino->di_aformat) {
0459b626
BN
2075 case XFS_DINODE_FMT_LOCAL:
2076 *anextents = 0;
5e656dbb
BN
2077 *atotblocks = 0;
2078 err = process_lclinode(mp, agno, ino, dino, XFS_ATTR_FORK);
0459b626
BN
2079 break;
2080 case XFS_DINODE_FMT_EXTENTS:
610f3285 2081 ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK);
0459b626
BN
2082 *anextents = 0;
2083 err = process_exinode(mp, agno, ino, dino, type, dirty,
2084 atotblocks, anextents, &ablkmap,
2bd0ea18 2085 XFS_ATTR_FORK, check_dups);
0459b626
BN
2086 break;
2087 case XFS_DINODE_FMT_BTREE:
610f3285 2088 ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK);
0459b626
BN
2089 *anextents = 0;
2090 err = process_btinode(mp, agno, ino, dino, type, dirty,
2091 atotblocks, anextents, &ablkmap,
2bd0ea18 2092 XFS_ATTR_FORK, check_dups);
0459b626
BN
2093 break;
2094 default:
5d1b7f0f 2095 do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"),
56b2de80 2096 dino->di_aformat, lino);
0459b626
BN
2097 err = 1;
2098 break;
2099 }
2bd0ea18 2100
0459b626
BN
2101 if (err) {
2102 /*
2103 * clear the attribute fork if necessary. we can't
2104 * clear the inode because we've already put the
2105 * inode space info into the blockmap.
2106 *
2107 * XXX - put the inode onto the "move it" list and
2108 * log the the attribute scrubbing
2109 */
5d1b7f0f 2110 do_warn(_("bad attribute fork in inode %" PRIu64), lino);
2bd0ea18 2111
0459b626 2112 if (!no_modify) {
28a4f9c0
ES
2113 do_warn(_(", clearing attr fork\n"));
2114 *dirty += clear_dinode_attr(mp, dino, lino);
2115 dino->di_aformat = XFS_DINODE_FMT_LOCAL;
0459b626
BN
2116 ASSERT(*dirty > 0);
2117 } else {
2118 do_warn(_(", would clear attr fork\n"));
2bd0ea18
NS
2119 }
2120
0459b626
BN
2121 *atotblocks = 0;
2122 *anextents = 0;
2bd0ea18 2123 blkmap_free(ablkmap);
0459b626 2124 *retval = 1;
2bd0ea18 2125
28a4f9c0 2126 return 0;
2bd0ea18
NS
2127 }
2128
0459b626 2129 if (check_dups) {
56b2de80 2130 switch (dino->di_aformat) {
0459b626 2131 case XFS_DINODE_FMT_LOCAL:
f8149110 2132 err = process_lclinode(mp, agno, ino, dino,
5e656dbb 2133 XFS_ATTR_FORK);
0459b626
BN
2134 break;
2135 case XFS_DINODE_FMT_EXTENTS:
2136 err = process_exinode(mp, agno, ino, dino,
2137 type, dirty, atotblocks, anextents,
2138 &ablkmap, XFS_ATTR_FORK, 0);
2139 break;
2140 case XFS_DINODE_FMT_BTREE:
2141 err = process_btinode(mp, agno, ino, dino,
2142 type, dirty, atotblocks, anextents,
2143 &ablkmap, XFS_ATTR_FORK, 0);
2144 break;
2145 default:
5d1b7f0f 2146 do_error(_("illegal attribute fmt %d, ino %" PRIu64 "\n"),
56b2de80 2147 dino->di_aformat, lino);
2bd0ea18 2148 }
2bd0ea18 2149
0459b626
BN
2150 if (no_modify && err != 0) {
2151 blkmap_free(ablkmap);
2152 return 1;
2bd0ea18 2153 }
2bd0ea18 2154
0459b626 2155 ASSERT(err == 0);
2bd0ea18
NS
2156 }
2157
0459b626
BN
2158 /*
2159 * do attribute semantic-based consistency checks now
2160 */
2bd0ea18 2161
0459b626
BN
2162 /* get this only in phase 3, not in both phase 3 and 4 */
2163 if (extra_attr_check &&
2164 process_attributes(mp, lino, dino, ablkmap, &repair)) {
5d1b7f0f
CH
2165 do_warn(
2166 _("problem with attribute contents in inode %" PRIu64 "\n"),
0459b626
BN
2167 lino);
2168 if (!repair) {
2169 /* clear attributes if not done already */
2170 if (!no_modify) {
2171 *dirty += clear_dinode_attr(mp, dino, lino);
56b2de80 2172 dino->di_aformat = XFS_DINODE_FMT_LOCAL;
0459b626
BN
2173 } else {
2174 do_warn(_("would clear attr fork\n"));
2175 }
2176 *atotblocks = 0;
2177 *anextents = 0;
2bd0ea18 2178 }
0459b626
BN
2179 else {
2180 *dirty = 1; /* it's been repaired */
2bd0ea18
NS
2181 }
2182 }
0459b626
BN
2183 blkmap_free(ablkmap);
2184 return 0;
2185}
2bd0ea18 2186
0459b626
BN
2187/*
2188 * check nlinks feature, if it's a version 1 inode,
2189 * just leave nlinks alone. even if it's set wrong,
2190 * it'll be reset when read in.
2191 */
2bd0ea18 2192
0459b626
BN
2193static int
2194process_check_inode_nlink_version(
56b2de80 2195 xfs_dinode_t *dino,
0459b626
BN
2196 xfs_ino_t lino)
2197{
2198 int dirty = 0;
2bd0ea18 2199
2bd0ea18 2200 /*
5f6f3660 2201 * if it's a version 2 inode, it should have a zero
2bd0ea18
NS
2202 * onlink field, so clear it.
2203 */
5f6f3660 2204 if (dino->di_version > 1 && dino->di_onlink != 0) {
0459b626 2205 if (!no_modify) {
5d1b7f0f
CH
2206 do_warn(
2207_("clearing obsolete nlink field in version 2 inode %" PRIu64 ", was %d, now 0\n"),
56b2de80
DC
2208 lino, be16_to_cpu(dino->di_onlink));
2209 dino->di_onlink = 0;
0459b626 2210 dirty = 1;
2bd0ea18 2211 } else {
5d1b7f0f
CH
2212 do_warn(
2213_("would clear obsolete nlink field in version 2 inode %" PRIu64 ", currently %d\n"),
56b2de80 2214 lino, be16_to_cpu(dino->di_onlink));
0459b626
BN
2215 }
2216 }
2217 return dirty;
2218}
2219
8fec4f7c
DW
2220/* Check nanoseconds of a timestamp don't exceed 1 second. */
2221static void
2222check_nsec(
2223 const char *name,
2224 xfs_ino_t lino,
2225 struct xfs_timestamp *t,
2226 int *dirty)
2227{
2228 if (be32_to_cpu(t->t_nsec) < 1000000000)
2229 return;
2230
2231 do_warn(
2232_("Bad %s nsec %u on inode %" PRIu64 ", "), name, be32_to_cpu(t->t_nsec), lino);
2233 if (no_modify) {
2234 do_warn(_("would reset to zero\n"));
2235 } else {
2236 do_warn(_("resetting to zero\n"));
2237 t->t_nsec = 0;
2238 *dirty = 1;
2239 }
2240}
2241
0459b626
BN
2242/*
2243 * returns 0 if the inode is ok, 1 if the inode is corrupt
2244 * check_dups can be set to 1 *only* when called by the
2245 * first pass of the duplicate block checking of phase 4.
2246 * *dirty is set > 0 if the dinode has been altered and
2247 * needs to be written out.
2248 *
2249 * for detailed, info, look at process_dinode() comments.
2250 */
8b8a6b02 2251static int
0459b626
BN
2252process_dinode_int(xfs_mount_t *mp,
2253 xfs_dinode_t *dino,
2254 xfs_agnumber_t agno,
2255 xfs_agino_t ino,
2256 int was_free, /* 1 if inode is currently free */
2257 int *dirty, /* out == > 0 if inode is now dirty */
2258 int *used, /* out == 1 if inode is in use */
2259 int verify_mode, /* 1 == verify but don't modify inode */
2260 int uncertain, /* 1 == inode is uncertain */
2261 int ino_discovery, /* 1 == check dirs for unknown inodes */
2262 int check_dups, /* 1 == check if inode claims
2263 * duplicate blocks */
2264 int extra_attr_check, /* 1 == do attribute format and value checks */
2265 int *isa_dir, /* out == 1 if inode is a directory */
2266 xfs_ino_t *parent) /* out -- parent if ino is a dir */
2267{
5a35bf2c
DC
2268 xfs_rfsblock_t totblocks = 0;
2269 xfs_rfsblock_t atotblocks = 0;
0459b626
BN
2270 int di_mode;
2271 int type;
2272 int retval = 0;
14f8b681
DW
2273 uint64_t nextents;
2274 uint64_t anextents;
0459b626
BN
2275 xfs_ino_t lino;
2276 const int is_free = 0;
2277 const int is_used = 1;
2278 blkmap_t *dblkmap = NULL;
2279
2280 *dirty = *isa_dir = 0;
2281 *used = is_used;
2282 type = XR_INO_UNKNOWN;
2283
0459b626 2284 lino = XFS_AGINO_TO_INO(mp, agno, ino);
56b2de80 2285 di_mode = be16_to_cpu(dino->di_mode);
0459b626
BN
2286
2287 /*
2288 * if in verify mode, don't modify the inode.
2289 *
2290 * if correcting, reset stuff that has known values
2291 *
2292 * if in uncertain mode, be silent on errors since we're
2293 * trying to find out if these are inodes as opposed
2294 * to assuming that they are. Just return the appropriate
2295 * return code in that case.
2296 *
2297 * If uncertain is set, verify_mode MUST be set.
2298 */
2299 ASSERT(uncertain == 0 || verify_mode != 0);
2300
7d7c5553
ES
2301 /*
2302 * This is the only valid point to check the CRC; after this we may have
2303 * made changes which invalidate it, and the CRC is only updated again
2304 * when it gets written out.
2305 *
2306 * Of course if we make any modifications after this, the inode gets
2307 * rewritten, and the CRC is updated automagically.
2308 */
2309 if (xfs_sb_version_hascrc(&mp->m_sb) &&
e2f60652 2310 !libxfs_verify_cksum((char *)dino, mp->m_sb.sb_inodesize,
7d7c5553
ES
2311 XFS_DINODE_CRC_OFF)) {
2312 retval = 1;
2313 if (!uncertain)
2314 do_warn(_("bad CRC for inode %" PRIu64 "%c"),
2315 lino, verify_mode ? '\n' : ',');
2316 if (!verify_mode) {
2317 if (!no_modify) {
2318 do_warn(_(" will rewrite\n"));
2319 *dirty = 1;
2320 } else
2321 do_warn(_(" would rewrite\n"));
2322 }
2323 }
2324
56b2de80 2325 if (be16_to_cpu(dino->di_magic) != XFS_DINODE_MAGIC) {
0459b626
BN
2326 retval = 1;
2327 if (!uncertain)
5d1b7f0f 2328 do_warn(_("bad magic number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2329 be16_to_cpu(dino->di_magic), lino,
0459b626
BN
2330 verify_mode ? '\n' : ',');
2331 if (!verify_mode) {
2332 if (!no_modify) {
2333 do_warn(_(" resetting magic number\n"));
56b2de80 2334 dino->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
0459b626
BN
2335 *dirty = 1;
2336 } else
2337 do_warn(_(" would reset magic number\n"));
2338 }
2339 }
2340
e2f60652 2341 if (!libxfs_dinode_good_version(mp, dino->di_version)) {
0459b626
BN
2342 retval = 1;
2343 if (!uncertain)
5d1b7f0f 2344 do_warn(_("bad version number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2345 (__s8)dino->di_version, lino,
0459b626
BN
2346 verify_mode ? '\n' : ',');
2347 if (!verify_mode) {
2348 if (!no_modify) {
2349 do_warn(_(" resetting version number\n"));
e0607266 2350 dino->di_version =
5f6f3660 2351 xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 2;
0459b626
BN
2352 *dirty = 1;
2353 } else
2354 do_warn(_(" would reset version number\n"));
2355 }
2356 }
2357
e0607266
DC
2358 /*
2359 * We don't bother checking the CRC here - we cannot guarantee that when
2360 * we are called here that the inode has not already been modified in
2361 * memory and hence invalidated the CRC.
2362 */
2363 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2364 if (be64_to_cpu(dino->di_ino) != lino) {
2365 if (!uncertain)
2366 do_warn(
2367_("inode identifier %llu mismatch on inode %" PRIu64 "\n"),
51073f86
DW
2368 (unsigned long long)be64_to_cpu(dino->di_ino),
2369 lino);
e0607266
DC
2370 if (verify_mode)
2371 return 1;
2372 goto clear_bad_out;
2373 }
9c4e12fb
ES
2374 if (platform_uuid_compare(&dino->di_uuid,
2375 &mp->m_sb.sb_meta_uuid)) {
e0607266
DC
2376 if (!uncertain)
2377 do_warn(
2378 _("UUID mismatch on inode %" PRIu64 "\n"), lino);
2379 if (verify_mode)
2380 return 1;
2381 goto clear_bad_out;
2382 }
2383 }
2384
0459b626
BN
2385 /*
2386 * blow out of here if the inode size is < 0
2387 */
56b2de80 2388 if ((xfs_fsize_t)be64_to_cpu(dino->di_size) < 0) {
0459b626 2389 if (!uncertain)
5d1b7f0f
CH
2390 do_warn(
2391_("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
14f8b681 2392 (int64_t)be64_to_cpu(dino->di_size),
5d1b7f0f 2393 lino);
0459b626
BN
2394 if (verify_mode)
2395 return 1;
2396 goto clear_bad_out;
2397 }
2398
2399 /*
0724d0f4 2400 * if not in verify mode, check to see if the inode and imap
0459b626
BN
2401 * agree that the inode is free
2402 */
2403 if (!verify_mode && di_mode == 0) {
2404 /*
2405 * was_free value is not meaningful if we're in verify mode
2406 */
2407 if (was_free) {
2408 /*
2e1bf6c5 2409 * easy case, inode free -- inode and map agree, check
0459b626
BN
2410 * it just in case to ensure that format, etc. are
2411 * set correctly
2412 */
2e1bf6c5
ES
2413 if (libxfs_dinode_verify(mp, lino, dino) != NULL) {
2414 do_warn(
2415 _("free inode %" PRIu64 " contains errors, "), lino);
2416 if (!no_modify) {
0724d0f4 2417 clear_dinode(mp, dino, lino);
2e1bf6c5 2418 do_warn(_("corrected\n"));
0724d0f4 2419 *dirty += 1;
2e1bf6c5
ES
2420 } else {
2421 do_warn(_("would correct\n"));
2422 }
2423 }
0459b626
BN
2424 *used = is_free;
2425 return 0;
2426 }
2427 /*
2428 * the inode looks free but the map says it's in use.
2429 * clear the inode just to be safe and mark the inode
2430 * free.
2431 */
5d1b7f0f
CH
2432 do_warn(
2433 _("imap claims a free inode %" PRIu64 " is in use, "), lino);
0459b626
BN
2434 if (!no_modify) {
2435 do_warn(_("correcting imap and clearing inode\n"));
0724d0f4
ES
2436 clear_dinode(mp, dino, lino);
2437 *dirty += 1;
0459b626
BN
2438 retval = 1;
2439 } else
2440 do_warn(_("would correct imap and clear inode\n"));
2441 *used = is_free;
2442 return retval;
2443 }
2444
2445 /*
2446 * because of the lack of any write ordering guarantee, it's
2447 * possible that the core got updated but the forks didn't.
2448 * so rather than be ambitious (and probably incorrect),
2449 * if there's an inconsistency, we get conservative and
2450 * just pitch the file. blow off checking formats of
2451 * free inodes since technically any format is legal
2452 * as we reset the inode when we re-use it.
2453 */
56b2de80 2454 if (di_mode != 0 && check_dinode_mode_format(dino) != 0) {
0459b626 2455 if (!uncertain)
5d1b7f0f
CH
2456 do_warn(
2457 _("bad inode format in inode %" PRIu64 "\n"), lino);
0459b626
BN
2458 if (verify_mode)
2459 return 1;
2460 goto clear_bad_out;
2461 }
2462
bd5683fe
DC
2463 /*
2464 * check that we only have valid flags set, and those that are set make
2465 * sense.
2466 */
56b2de80
DC
2467 if (dino->di_flags) {
2468 uint16_t flags = be16_to_cpu(dino->di_flags);
bd5683fe
DC
2469
2470 if (flags & ~XFS_DIFLAG_ANY) {
c98f31a5
CH
2471 if (!uncertain) {
2472 do_warn(
2473 _("Bad flags set in inode %" PRIu64 "\n"),
2474 lino);
2475 }
5cd0710a 2476 flags &= XFS_DIFLAG_ANY;
bd5683fe
DC
2477 }
2478
2479 if (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT)) {
2480 /* need an rt-dev! */
2481 if (!rt_name) {
c98f31a5
CH
2482 if (!uncertain) {
2483 do_warn(
2484 _("inode %" PRIu64 " has RT flag set but there is no RT device\n"),
2485 lino);
2486 }
bd5683fe
DC
2487 flags &= ~(XFS_DIFLAG_REALTIME |
2488 XFS_DIFLAG_RTINHERIT);
2489 }
2490 }
fb380cb7 2491 if (flags & XFS_DIFLAG_NEWRTBM) {
bd5683fe
DC
2492 /* must be a rt bitmap inode */
2493 if (lino != mp->m_sb.sb_rbmino) {
c98f31a5
CH
2494 if (!uncertain) {
2495 do_warn(
2496 _("inode %" PRIu64 " not rt bitmap\n"),
2497 lino);
2498 }
fb380cb7 2499 flags &= ~XFS_DIFLAG_NEWRTBM;
bd5683fe
DC
2500 }
2501 }
2502 if (flags & (XFS_DIFLAG_RTINHERIT |
2503 XFS_DIFLAG_EXTSZINHERIT |
2504 XFS_DIFLAG_PROJINHERIT |
2505 XFS_DIFLAG_NOSYMLINKS)) {
2506 /* must be a directory */
2507 if (di_mode && !S_ISDIR(di_mode)) {
c98f31a5
CH
2508 if (!uncertain) {
2509 do_warn(
2510 _("directory flags set on non-directory inode %" PRIu64 "\n" ),
2511 lino);
2512 }
bd5683fe
DC
2513 flags &= ~(XFS_DIFLAG_RTINHERIT |
2514 XFS_DIFLAG_EXTSZINHERIT |
2515 XFS_DIFLAG_PROJINHERIT |
2516 XFS_DIFLAG_NOSYMLINKS);
2517 }
2518 }
83f4b5ac 2519 if (flags & (XFS_DIFLAG_REALTIME | FS_XFLAG_EXTSIZE)) {
bd5683fe
DC
2520 /* must be a file */
2521 if (di_mode && !S_ISREG(di_mode)) {
c98f31a5
CH
2522 if (!uncertain) {
2523 do_warn(
2524 _("file flags set on non-file inode %" PRIu64 "\n"),
2525 lino);
2526 }
bd5683fe 2527 flags &= ~(XFS_DIFLAG_REALTIME |
83f4b5ac 2528 FS_XFLAG_EXTSIZE);
bd5683fe
DC
2529 }
2530 }
56b2de80 2531 if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) {
bd5683fe 2532 if (!no_modify) {
5cd0710a 2533 do_warn(_("fixing bad flags.\n"));
56b2de80 2534 dino->di_flags = cpu_to_be16(flags);
bd5683fe
DC
2535 *dirty = 1;
2536 } else
5cd0710a 2537 do_warn(_("would fix bad flags.\n"));
bd5683fe
DC
2538 }
2539 }
2540
a406779b
DW
2541 /*
2542 * check that we only have valid flags2 set, and those that are set make
2543 * sense.
2544 */
2545 if (dino->di_version >= 3) {
2546 uint16_t flags = be16_to_cpu(dino->di_flags);
2547 uint64_t flags2 = be64_to_cpu(dino->di_flags2);
2548
2549 if (flags2 & ~XFS_DIFLAG2_ANY) {
2550 if (!uncertain) {
2551 do_warn(
2552 _("Bad flags2 set in inode %" PRIu64 "\n"),
2553 lino);
2554 }
2555 flags2 &= XFS_DIFLAG2_ANY;
2556 }
2557
c1604fa4
DW
2558 if (flags2 & XFS_DIFLAG2_DAX) {
2559 /* must be a file or dir */
2560 if (di_mode && !(S_ISREG(di_mode) || S_ISDIR(di_mode))) {
2561 if (!uncertain) {
2562 do_warn(
2563 _("DAX flag set on special inode %" PRIu64 "\n"),
2564 lino);
2565 }
2566 flags2 &= ~XFS_DIFLAG2_DAX;
2567 }
2568 }
2569
a406779b
DW
2570 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2571 !xfs_sb_version_hasreflink(&mp->m_sb)) {
2572 if (!uncertain) {
2573 do_warn(
2574 _("inode %" PRIu64 " is marked reflinked but file system does not support reflink\n"),
2575 lino);
2576 }
2577 goto clear_bad_out;
2578 }
2579
2580 if (flags2 & XFS_DIFLAG2_REFLINK) {
2581 /* must be a file */
2582 if (di_mode && !S_ISREG(di_mode)) {
2583 if (!uncertain) {
2584 do_warn(
2585 _("reflink flag set on non-file inode %" PRIu64 "\n"),
2586 lino);
2587 }
2588 goto clear_bad_out;
2589 }
2590 }
2591
2592 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2593 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2594 if (!uncertain) {
2595 do_warn(
2596 _("Cannot have a reflinked realtime inode %" PRIu64 "\n"),
2597 lino);
2598 }
2599 goto clear_bad_out;
2600 }
2601
42627ba6
DW
2602 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2603 !xfs_sb_version_hasreflink(&mp->m_sb)) {
2604 if (!uncertain) {
2605 do_warn(
2606 _("inode %" PRIu64 " has CoW extent size hint but file system does not support reflink\n"),
2607 lino);
2608 }
2609 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2610 }
2611
2612 if (flags2 & XFS_DIFLAG2_COWEXTSIZE) {
2613 /* must be a directory or file */
2614 if (di_mode && !S_ISDIR(di_mode) && !S_ISREG(di_mode)) {
2615 if (!uncertain) {
2616 do_warn(
2617 _("CoW extent size flag set on non-file, non-directory inode %" PRIu64 "\n" ),
2618 lino);
2619 }
2620 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2621 }
2622 }
2623
2624 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2625 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2626 if (!uncertain) {
2627 do_warn(
2628 _("Cannot have CoW extent size hint on a realtime inode %" PRIu64 "\n"),
2629 lino);
2630 }
2631 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2632 }
2633
a406779b
DW
2634 if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) {
2635 if (!no_modify) {
2636 do_warn(_("fixing bad flags2.\n"));
2637 dino->di_flags2 = cpu_to_be64(flags2);
2638 *dirty = 1;
2639 } else
2640 do_warn(_("would fix bad flags2.\n"));
2641 }
2642 }
2643
0459b626
BN
2644 if (verify_mode)
2645 return retval;
2646
2647 /*
2648 * clear the next unlinked field if necessary on a good
2649 * inode only during phase 4 -- when checking for inodes
2650 * referencing duplicate blocks. then it's safe because
2651 * we've done the inode discovery and have found all the inodes
2652 * we're going to find. check_dups is set to 1 only during
2653 * phase 4. Ugly.
2654 */
119383bf
DC
2655 if (check_dups && be32_to_cpu(dino->di_next_unlinked) != NULLAGINO) {
2656 if (no_modify) {
2657 do_warn(
2658 _("Would clear next_unlinked in inode %" PRIu64 "\n"), lino);
2659 } else {
2660 clear_dinode_unlinked(mp, dino);
2661 do_warn(
2662 _("Cleared next_unlinked in inode %" PRIu64 "\n"), lino);
2663 *dirty += 1;
2664 }
0724d0f4 2665 }
0459b626
BN
2666
2667 /* set type and map type info */
2668
2669 switch (di_mode & S_IFMT) {
2670 case S_IFDIR:
2671 type = XR_INO_DIR;
2672 *isa_dir = 1;
2673 break;
2674 case S_IFREG:
56b2de80 2675 if (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_REALTIME)
0459b626
BN
2676 type = XR_INO_RTDATA;
2677 else if (lino == mp->m_sb.sb_rbmino)
2678 type = XR_INO_RTBITMAP;
2679 else if (lino == mp->m_sb.sb_rsumino)
2680 type = XR_INO_RTSUM;
5857dce9
ES
2681 else if (lino == mp->m_sb.sb_uquotino)
2682 type = XR_INO_UQUOTA;
2683 else if (lino == mp->m_sb.sb_gquotino)
2684 type = XR_INO_GQUOTA;
2685 else if (lino == mp->m_sb.sb_pquotino)
2686 type = XR_INO_PQUOTA;
0459b626
BN
2687 else
2688 type = XR_INO_DATA;
2689 break;
2690 case S_IFLNK:
2691 type = XR_INO_SYMLINK;
2692 break;
2693 case S_IFCHR:
2694 type = XR_INO_CHRDEV;
2695 break;
2696 case S_IFBLK:
2697 type = XR_INO_BLKDEV;
2698 break;
2699 case S_IFSOCK:
2700 type = XR_INO_SOCK;
2701 break;
2702 case S_IFIFO:
2703 type = XR_INO_FIFO;
2704 break;
2705 default:
5d1b7f0f 2706 do_warn(_("bad inode type %#o inode %" PRIu64 "\n"),
0459b626
BN
2707 di_mode & S_IFMT, lino);
2708 goto clear_bad_out;
2709 }
2710
2711 /*
2712 * type checks for superblock inodes
2713 */
56b2de80 2714 if (process_check_sb_inodes(mp, dino, lino, &type, dirty) != 0)
0459b626
BN
2715 goto clear_bad_out;
2716
2717 /*
2718 * only regular files with REALTIME or EXTSIZE flags set can have
2719 * extsize set, or directories with EXTSZINHERIT.
2720 */
db3d080b
DW
2721 if (libxfs_inode_validate_extsize(mp,
2722 be32_to_cpu(dino->di_extsize),
2723 be16_to_cpu(dino->di_mode),
2724 be16_to_cpu(dino->di_flags)) != NULL) {
2725 do_warn(
2726_("Bad extent size %u on inode %" PRIu64 ", "),
2727 be32_to_cpu(dino->di_extsize), lino);
2728 if (!no_modify) {
2729 do_warn(_("resetting to zero\n"));
2730 dino->di_extsize = 0;
2731 dino->di_flags &= ~cpu_to_be16(XFS_DIFLAG_EXTSIZE |
2732 XFS_DIFLAG_EXTSZINHERIT);
2733 *dirty = 1;
2734 } else
2735 do_warn(_("would reset to zero\n"));
0459b626
BN
2736 }
2737
42627ba6
DW
2738 /*
2739 * Only (regular files and directories) with COWEXTSIZE flags
2740 * set can have extsize set.
2741 */
2742 if (dino->di_version >= 3 &&
db3d080b
DW
2743 libxfs_inode_validate_cowextsize(mp,
2744 be32_to_cpu(dino->di_cowextsize),
2745 be16_to_cpu(dino->di_mode),
2746 be16_to_cpu(dino->di_flags),
2747 be64_to_cpu(dino->di_flags2)) != NULL) {
1c744e94 2748 do_warn(
db3d080b
DW
2749_("Bad CoW extent size %u on inode %" PRIu64 ", "),
2750 be32_to_cpu(dino->di_cowextsize), lino);
1c744e94 2751 if (!no_modify) {
db3d080b 2752 do_warn(_("resetting to zero\n"));
1c744e94 2753 dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_COWEXTSIZE);
db3d080b 2754 dino->di_cowextsize = 0;
1c744e94 2755 *dirty = 1;
db3d080b
DW
2756 } else
2757 do_warn(_("would reset to zero\n"));
1c744e94
DW
2758 }
2759
8fec4f7c
DW
2760 /* nsec fields cannot be larger than 1 billion */
2761 check_nsec("atime", lino, &dino->di_atime, dirty);
2762 check_nsec("mtime", lino, &dino->di_mtime, dirty);
2763 check_nsec("ctime", lino, &dino->di_ctime, dirty);
2764 if (dino->di_version >= 3)
2765 check_nsec("crtime", lino, &dino->di_crtime, dirty);
2766
0459b626
BN
2767 /*
2768 * general size/consistency checks:
2769 */
2770 if (process_check_inode_sizes(mp, dino, lino, type) != 0)
2771 goto clear_bad_out;
2772
2773 /*
2774 * check for illegal values of forkoff
2775 */
56b2de80 2776 if (process_check_inode_forkoff(mp, dino, lino) != 0)
0459b626
BN
2777 goto clear_bad_out;
2778
7e174ec7
DW
2779 /*
2780 * record the state of the reflink flag
2781 */
2782 if (collect_rmaps)
2783 record_inode_reflink_flag(mp, dino, agno, ino, lino);
2784
0459b626
BN
2785 /*
2786 * check data fork -- if it's bad, clear the inode
2787 */
2788 if (process_inode_data_fork(mp, agno, ino, dino, type, dirty,
2789 &totblocks, &nextents, &dblkmap, check_dups) != 0)
2790 goto bad_out;
2791
2792 /*
2793 * check attribute fork if necessary. attributes are
2794 * always stored in the regular filesystem.
2795 */
2796 if (process_inode_attr_fork(mp, agno, ino, dino, type, dirty,
2797 &atotblocks, &anextents, check_dups, extra_attr_check,
2798 &retval))
2799 goto bad_out;
2800
2801 /*
2802 * enforce totblocks is 0 for misc types
2803 */
2804 if (process_misc_ino_types_blocks(totblocks, lino, type))
2805 goto clear_bad_out;
2806
2807 /*
2808 * correct space counters if required
2809 */
56b2de80 2810 if (process_inode_blocks_and_extents(dino, totblocks + atotblocks,
0459b626
BN
2811 nextents, anextents, lino, dirty) != 0)
2812 goto clear_bad_out;
2813
2814 /*
2815 * do any semantic type-based checking here
2816 */
2817 switch (type) {
2818 case XR_INO_DIR:
9a048535 2819 if (process_dir2(mp, lino, dino, ino_discovery,
0459b626 2820 dirty, "", parent, dblkmap)) {
5d1b7f0f
CH
2821 do_warn(
2822 _("problem with directory contents in inode %" PRIu64 "\n"),
2823 lino);
0459b626
BN
2824 goto clear_bad_out;
2825 }
2826 break;
2827 case XR_INO_SYMLINK:
2828 if (process_symlink(mp, lino, dino, dblkmap) != 0) {
5d1b7f0f
CH
2829 do_warn(
2830 _("problem with symbolic link in inode %" PRIu64 "\n"),
0459b626
BN
2831 lino);
2832 goto clear_bad_out;
2bd0ea18 2833 }
0459b626 2834 break;
5857dce9
ES
2835 case XR_INO_UQUOTA:
2836 case XR_INO_GQUOTA:
2837 case XR_INO_PQUOTA:
2838 if (process_quota_inode(mp, lino, dino, type, dblkmap) != 0) {
2839 do_warn(
2840 _("problem with quota inode %" PRIu64 "\n"), lino);
2841 goto clear_bad_out;
2842 }
2843 break;
0459b626
BN
2844 default:
2845 break;
2bd0ea18
NS
2846 }
2847
55d35a39 2848 blkmap_free(dblkmap);
0459b626
BN
2849
2850 /*
2851 * check nlinks feature, if it's a version 1 inode,
2852 * just leave nlinks alone. even if it's set wrong,
2853 * it'll be reset when read in.
2854 */
56b2de80 2855 *dirty += process_check_inode_nlink_version(dino, lino);
0459b626
BN
2856
2857 return retval;
2858
2859clear_bad_out:
2860 if (!no_modify) {
0724d0f4
ES
2861 clear_dinode(mp, dino, lino);
2862 *dirty += 1;
0459b626
BN
2863 }
2864bad_out:
2865 *used = is_free;
2866 *isa_dir = 0;
55d35a39 2867 blkmap_free(dblkmap);
0459b626 2868 return 1;
2bd0ea18
NS
2869}
2870
2871/*
2872 * returns 1 if inode is used, 0 if free.
2873 * performs any necessary salvaging actions.
2874 * note that we leave the generation count alone
2875 * because nothing we could set it to would be
2876 * guaranteed to be correct so the best guess for
2877 * the correct value is just to leave it alone.
2878 *
2879 * The trick is detecting empty files. For those,
2880 * the core and the forks should all be in the "empty"
2881 * or zero-length state -- a zero or possibly minimum length
2882 * (in the case of dirs) extent list -- although inline directories
2883 * and symlinks might be handled differently. So it should be
2884 * possible to sanity check them against each other.
2885 *
2886 * If the forks are an empty extent list though, then forget it.
2887 * The file is toast anyway since we can't recover its storage.
2888 *
2889 * Parameters:
2890 * Ins:
2891 * mp -- mount structure
2892 * dino -- pointer to on-disk inode structure
2893 * agno/ino -- inode numbers
2894 * free -- whether the map thinks the inode is free (1 == free)
2895 * ino_discovery -- whether we should examine directory
2896 * contents to discover new inodes
2897 * check_dups -- whether we should check to see if the
2898 * inode references duplicate blocks
2899 * if so, we compare the inode's claimed
2900 * blocks against the contents of the
2901 * duplicate extent list but we don't
2902 * set the bitmap. If not, we set the
2903 * bitmap and try and detect multiply
2904 * claimed blocks using the bitmap.
2905 * Outs:
2906 * dirty -- whether we changed the inode (1 == yes)
2bd0ea18
NS
2907 * used -- 1 if the inode is used, 0 if free. In no modify
2908 * mode, whether the inode should be used or free
2909 * isa_dir -- 1 if the inode is a directory, 0 if not. In
2910 * no modify mode, if the inode would be a dir or not.
2911 *
2912 * Return value -- 0 if the inode is good, 1 if it is/was corrupt
2913 */
2914
2915int
0459b626
BN
2916process_dinode(
2917 xfs_mount_t *mp,
2918 xfs_dinode_t *dino,
2919 xfs_agnumber_t agno,
2920 xfs_agino_t ino,
2921 int was_free,
2922 int *dirty,
2923 int *used,
2924 int ino_discovery,
2925 int check_dups,
2926 int extra_attr_check,
2927 int *isa_dir,
2928 xfs_ino_t *parent)
2bd0ea18 2929{
0459b626
BN
2930 const int verify_mode = 0;
2931 const int uncertain = 0;
2bd0ea18
NS
2932
2933#ifdef XR_INODE_TRACE
9ee7055c 2934 fprintf(stderr, _("processing inode %d/%d\n"), agno, ino);
2bd0ea18 2935#endif
0459b626
BN
2936 return process_dinode_int(mp, dino, agno, ino, was_free, dirty, used,
2937 verify_mode, uncertain, ino_discovery,
2938 check_dups, extra_attr_check, isa_dir, parent);
2bd0ea18
NS
2939}
2940
2941/*
2942 * a more cursory check, check inode core, *DON'T* check forks
2943 * this basically just verifies whether the inode is an inode
2944 * and whether or not it has been totally trashed. returns 0
2945 * if the inode passes the cursory sanity check, 1 otherwise.
2946 */
2947int
0459b626
BN
2948verify_dinode(
2949 xfs_mount_t *mp,
2950 xfs_dinode_t *dino,
2951 xfs_agnumber_t agno,
2952 xfs_agino_t ino)
2bd0ea18 2953{
0459b626
BN
2954 xfs_ino_t parent;
2955 int used = 0;
2956 int dirty = 0;
2957 int isa_dir = 0;
2958 const int verify_mode = 1;
2959 const int check_dups = 0;
2960 const int ino_discovery = 0;
2961 const int uncertain = 0;
2962
2963 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
2964 verify_mode, uncertain, ino_discovery,
2965 check_dups, 0, &isa_dir, &parent);
2bd0ea18
NS
2966}
2967
2968/*
2969 * like above only for inode on the uncertain list. it sets
2970 * the uncertain flag which makes process_dinode_int quieter.
2971 * returns 0 if the inode passes the cursory sanity check, 1 otherwise.
2972 */
2973int
0459b626
BN
2974verify_uncertain_dinode(
2975 xfs_mount_t *mp,
2976 xfs_dinode_t *dino,
2977 xfs_agnumber_t agno,
2978 xfs_agino_t ino)
2bd0ea18 2979{
0459b626
BN
2980 xfs_ino_t parent;
2981 int used = 0;
2982 int dirty = 0;
2983 int isa_dir = 0;
2984 const int verify_mode = 1;
2985 const int check_dups = 0;
2986 const int ino_discovery = 0;
2987 const int uncertain = 1;
2988
2989 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
2990 verify_mode, uncertain, ino_discovery,
2991 check_dups, 0, &isa_dir, &parent);
2bd0ea18 2992}