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