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