]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/dinode.c
xfs: Pre-calculate per-AG agbno geometry
[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;
95e3fc7f 945 xfs_extnum_t numrecs, max_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 */
95e3fc7f
DW
959 max_numrecs = xfs_iext_max_nextents(
960 xfs_dinode_has_large_extent_counts(dip),
961 whichfork);
962 if (numrecs > max_numrecs)
5fa28531
DC
963 numrecs = *nex;
964
2bd0ea18
NS
965 /*
966 * XXX - if we were going to fix up the btree record,
967 * we'd do it right here. For now, if there's a problem,
968 * we'll bail out and presumably clear the inode.
969 */
970 if (check_dups == 0)
e1f43b4c 971 ret = process_bmbt_reclist(mp, rp, &numrecs, type, lino,
2bd0ea18 972 tot, blkmapp, &first_key, &last_key,
e1f43b4c 973 whichfork);
2bd0ea18 974 else
e1f43b4c
CH
975 ret = scan_bmbt_reclist(mp, rp, &numrecs, type, lino, tot,
976 whichfork);
977
978 *nex = numrecs;
979 return ret;
2bd0ea18
NS
980}
981
982/*
983 * return 1 if inode should be cleared, 0 otherwise
984 */
5e656dbb 985static int
2bd0ea18 986process_lclinode(
2fd09353
CM
987 xfs_mount_t *mp,
988 xfs_agnumber_t agno,
989 xfs_agino_t ino,
7328ea6e 990 struct xfs_dinode *dip,
2fd09353 991 int whichfork)
2bd0ea18 992{
2fd09353
CM
993 struct xfs_attr_shortform *asf;
994 xfs_ino_t lino;
2bd0ea18 995
2bd0ea18 996 lino = XFS_AGINO_TO_INO(mp, agno, ino);
56b2de80 997 if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_size) >
5e656dbb 998 XFS_DFORK_DSIZE(dip, mp)) {
2bd0ea18 999 do_warn(
4de63245 1000 _("local inode %" PRIu64 " data fork is too large (size = %lld, max = %zu)\n"),
5d1b7f0f 1001 lino, (unsigned long long) be64_to_cpu(dip->di_size),
46eca962 1002 XFS_DFORK_DSIZE(dip, mp));
2bd0ea18
NS
1003 return(1);
1004 } else if (whichfork == XFS_ATTR_FORK) {
2fd09353 1005 asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
5e656dbb 1006 if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) {
2bd0ea18 1007 do_warn(
4de63245 1008 _("local inode %" PRIu64 " attr fork too large (size %d, max = %zu)\n"),
5e656dbb 1009 lino, be16_to_cpu(asf->hdr.totsize),
46eca962 1010 XFS_DFORK_ASIZE(dip, mp));
2bd0ea18
NS
1011 return(1);
1012 }
5e656dbb 1013 if (be16_to_cpu(asf->hdr.totsize) < sizeof(xfs_attr_sf_hdr_t)) {
2bd0ea18 1014 do_warn(
5d1b7f0f 1015 _("local inode %" PRIu64 " attr too small (size = %d, min size = %zd)\n"),
5e656dbb 1016 lino, be16_to_cpu(asf->hdr.totsize),
507f4e33 1017 sizeof(xfs_attr_sf_hdr_t));
2bd0ea18
NS
1018 return(1);
1019 }
1020 }
1021
1022 return(0);
1023}
1024
8b8a6b02 1025static int
7328ea6e
CH
1026process_symlink_extlist(
1027 xfs_mount_t *mp,
1028 xfs_ino_t lino,
1029 struct xfs_dinode *dino)
2bd0ea18 1030{
5a35bf2c 1031 xfs_fileoff_t expected_offset;
e0a12bda
BN
1032 xfs_bmbt_rec_t *rp;
1033 xfs_bmbt_irec_t irec;
3a2414fa
CB
1034 xfs_extnum_t numrecs;
1035 xfs_extnum_t i;
2bd0ea18 1036 int max_blocks;
2bd0ea18 1037
56b2de80 1038 if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
f8149110 1039 if (dino->di_format == XFS_DINODE_FMT_LOCAL)
5e656dbb 1040 return 0;
5d1b7f0f
CH
1041 do_warn(
1042_("mismatch between format (%d) and size (%" PRId64 ") in symlink ino %" PRIu64 "\n"),
1043 dino->di_format,
14f8b681 1044 (int64_t)be64_to_cpu(dino->di_size), lino);
5e656dbb
BN
1045 return 1;
1046 }
56b2de80 1047 if (dino->di_format == XFS_DINODE_FMT_LOCAL) {
5d1b7f0f 1048 do_warn(
b52923f3 1049_("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu64 "\n"),
5d1b7f0f 1050 dino->di_format,
14f8b681 1051 (int64_t)be64_to_cpu(dino->di_size), lino);
5e656dbb 1052 return 1;
2bd0ea18
NS
1053 }
1054
5e656dbb 1055 rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
5f70c91b 1056 numrecs = xfs_dfork_data_extents(dino);
2bd0ea18
NS
1057
1058 /*
1059 * the max # of extents in a symlink inode is equal to the
dfc130f3 1060 * number of max # of blocks required to store the symlink
2bd0ea18
NS
1061 */
1062 if (numrecs > max_symlink_blocks) {
1063 do_warn(
4b85994a 1064_("bad number of extents (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"),
2bd0ea18
NS
1065 numrecs, lino);
1066 return(1);
1067 }
1068
1069 max_blocks = max_symlink_blocks;
1070 expected_offset = 0;
1071
5e656dbb 1072 for (i = 0; i < numrecs; i++) {
ff105f75 1073 libxfs_bmbt_disk_get_all((rp +i), &irec);
e0a12bda 1074 if (irec.br_startoff != expected_offset) {
2bd0ea18 1075 do_warn(
4b85994a 1076_("bad extent #%" PRIu64 " offset (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"),
e0a12bda 1077 i, irec.br_startoff, lino);
2bd0ea18
NS
1078 return(1);
1079 }
e0a12bda 1080 if (irec.br_blockcount == 0 || irec.br_blockcount > max_blocks) {
2bd0ea18 1081 do_warn(
4b85994a 1082_("bad extent #%" PRIu64 " count (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"),
e0a12bda 1083 i, irec.br_blockcount, lino);
2bd0ea18
NS
1084 return(1);
1085 }
1086
e0a12bda
BN
1087 max_blocks -= irec.br_blockcount;
1088 expected_offset += irec.br_blockcount;
2bd0ea18
NS
1089 }
1090
1091 return(0);
1092}
1093
1094/*
1095 * takes a name and length and returns 1 if the name contains
1096 * a \0, returns 0 otherwise
1097 */
8b8a6b02 1098static int
2bd0ea18
NS
1099null_check(char *name, int length)
1100{
1101 int i;
1102
5a707ca1 1103 ASSERT(length < XFS_SYMLINK_MAXLEN);
2bd0ea18
NS
1104
1105 for (i = 0; i < length; i++, name++) {
1106 if (*name == '\0')
1107 return(1);
1108 }
1109
1110 return(0);
1111}
1112
5857dce9
ES
1113/*
1114 * This does /not/ do quotacheck, it validates the basic quota
1115 * inode metadata, checksums, etc.
1116 */
1117#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0)
1118static int
1119process_quota_inode(
1120 struct xfs_mount *mp,
1121 xfs_ino_t lino,
1122 struct xfs_dinode *dino,
1123 uint ino_type,
1124 struct blkmap *blkmap)
1125{
1126 xfs_fsblock_t fsbno;
1127 struct xfs_buf *bp;
1128 xfs_filblks_t dqchunklen;
1129 uint dqperchunk;
83695f94
DW
1130 int quota_type = 0;
1131 char *quota_string = NULL;
5857dce9
ES
1132 xfs_dqid_t dqid;
1133 xfs_fileoff_t qbno;
1134 int i;
1135 int t = 0;
31079e67 1136 int error;
5857dce9
ES
1137
1138 switch (ino_type) {
1139 case XR_INO_UQUOTA:
8e4128a7 1140 quota_type = XFS_DQTYPE_USER;
5857dce9
ES
1141 quota_string = _("User quota");
1142 break;
1143 case XR_INO_GQUOTA:
8e4128a7 1144 quota_type = XFS_DQTYPE_GROUP;
5857dce9
ES
1145 quota_string = _("Group quota");
1146 break;
1147 case XR_INO_PQUOTA:
8e4128a7 1148 quota_type = XFS_DQTYPE_PROJ;
5857dce9
ES
1149 quota_string = _("Project quota");
1150 break;
1151 default:
1152 ASSERT(0);
1153 }
1154
1155 dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
585acbe8 1156 dqperchunk = libxfs_calc_dquots_per_chunk(dqchunklen);
5857dce9
ES
1157 dqid = 0;
1158 qbno = NULLFILEOFF;
1159
1160 while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != NULLFILEOFF) {
bf0f6e17
CH
1161 struct xfs_dqblk *dqb;
1162 int writebuf = 0;
5857dce9
ES
1163
1164 fsbno = blkmap_get(blkmap, qbno);
1165 dqid = (xfs_dqid_t)qbno * dqperchunk;
1166
31079e67
DW
1167 error = -libxfs_buf_read(mp->m_dev,
1168 XFS_FSB_TO_DADDR(mp, fsbno), dqchunklen,
1169 LIBXFS_READBUF_SALVAGE, &bp,
1170 &xfs_dquot_buf_ops);
1171 if (error) {
5857dce9
ES
1172 do_warn(
1173_("cannot read inode %" PRIu64 ", file block %" PRIu64 ", disk block %" PRIu64 "\n"),
1174 lino, qbno, fsbno);
1175 return 1;
1176 }
1177
1178 dqb = bp->b_addr;
1179 for (i = 0; i < dqperchunk; i++, dqid++, dqb++) {
5857dce9
ES
1180 int bad_dqb = 0;
1181
1182 /* We only print the first problem we find */
2660e653 1183 if (xfs_has_crc(mp)) {
585acbe8
ES
1184 if (!libxfs_verify_cksum((char *)dqb,
1185 sizeof(*dqb),
5857dce9
ES
1186 XFS_DQUOT_CRC_OFF)) {
1187 do_warn(_("%s: bad CRC for id %u. "),
1188 quota_string, dqid);
1189 bad_dqb = 1;
1190 goto bad;
1191 }
1192
1193 if (!uuid_equal(&dqb->dd_uuid,
1194 &mp->m_sb.sb_meta_uuid)) {
1195 do_warn(_("%s: bad UUID for id %u. "),
1196 quota_string, dqid);
1197 bad_dqb = 1;
1198 goto bad;
1199 }
1200 }
bce109af
DW
1201 if (libxfs_dquot_verify(mp, &dqb->dd_diskdq, dqid)
1202 != NULL ||
cde0e6a6 1203 (dqb->dd_diskdq.d_type & XFS_DQTYPE_REC_MASK)
bce109af 1204 != quota_type) {
5857dce9
ES
1205 do_warn(_("%s: Corrupt quota for id %u. "),
1206 quota_string, dqid);
1207 bad_dqb = 1;
1208 }
1209
1210bad:
1211 if (bad_dqb) {
1212 if (no_modify)
1213 do_warn(_("Would correct.\n"));
1214 else {
1215 do_warn(_("Corrected.\n"));
e1d3178a 1216 libxfs_dqblk_repair(mp, dqb,
585acbe8 1217 dqid, quota_type);
5857dce9
ES
1218 writebuf = 1;
1219 }
1220 }
1221 }
1222
18b4f688 1223 if (writebuf && !no_modify) {
f524ae04 1224 libxfs_buf_mark_dirty(bp);
18b4f688
DW
1225 libxfs_buf_relse(bp);
1226 }
5857dce9 1227 else
e02ba985 1228 libxfs_buf_relse(bp);
5857dce9
ES
1229 }
1230 return 0;
1231}
1232
2019931a
DC
1233static int
1234process_symlink_remote(
1235 struct xfs_mount *mp,
1236 xfs_ino_t lino,
1237 struct xfs_dinode *dino,
1238 struct blkmap *blkmap,
1239 char *dst)
1240{
5a35bf2c 1241 xfs_fsblock_t fsbno;
2019931a
DC
1242 struct xfs_buf *bp;
1243 char *src;
1244 int pathlen;
1245 int offset;
1246 int i;
31079e67 1247 int error;
2019931a
DC
1248
1249 offset = 0;
1250 pathlen = be64_to_cpu(dino->di_size);
1251 i = 0;
1252
1253 while (pathlen > 0) {
1254 int blk_cnt = 1;
1255 int byte_cnt;
7cb3f7fe 1256 int badcrc = 0;
2019931a
DC
1257
1258 fsbno = blkmap_get(blkmap, i);
5a35bf2c 1259 if (fsbno == NULLFSBLOCK) {
2019931a
DC
1260 do_warn(
1261_("cannot read inode %" PRIu64 ", file block %d, NULL disk block\n"),
1262 lino, i);
1263 return 1;
1264 }
1265
1266 /*
1267 * There's a symlink header for each contiguous extent. If
1268 * there are contiguous blocks, read them in one go.
1269 */
1270 while (blk_cnt <= max_symlink_blocks) {
1271 if (blkmap_get(blkmap, i + 1) != fsbno + 1)
1272 break;
1273 blk_cnt++;
1274 i++;
1275 }
1276
1277 byte_cnt = XFS_FSB_TO_B(mp, blk_cnt);
1278
31079e67
DW
1279 error = -libxfs_buf_read(mp->m_dev,
1280 XFS_FSB_TO_DADDR(mp, fsbno), BTOBB(byte_cnt),
1281 LIBXFS_READBUF_SALVAGE, &bp,
1282 &xfs_symlink_buf_ops);
1283 if (error) {
2019931a
DC
1284 do_warn(
1285_("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
1286 lino, i, fsbno);
1287 return 1;
1288 }
d2be29d4
DW
1289 if (bp->b_error == -EFSCORRUPTED) {
1290 do_warn(
1291_("Corrupt symlink remote block %" PRIu64 ", inode %" PRIu64 ".\n"),
1292 fsbno, lino);
e02ba985 1293 libxfs_buf_relse(bp);
d2be29d4
DW
1294 return 1;
1295 }
12b53197 1296 if (bp->b_error == -EFSBADCRC) {
7cb3f7fe
DC
1297 do_warn(
1298_("Bad symlink buffer CRC, block %" PRIu64 ", inode %" PRIu64 ".\n"
1299 "Correcting CRC, but symlink may be bad.\n"), fsbno, lino);
1300 badcrc = 1;
1301 }
2019931a
DC
1302
1303 byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
68d16907 1304 byte_cnt = min(pathlen, byte_cnt);
2019931a
DC
1305
1306 src = bp->b_addr;
2660e653 1307 if (xfs_has_crc(mp)) {
ff105f75
DC
1308 if (!libxfs_symlink_hdr_ok(lino, offset,
1309 byte_cnt, bp)) {
2019931a
DC
1310 do_warn(
1311_("bad symlink header ino %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
1312 lino, i, fsbno);
e02ba985 1313 libxfs_buf_relse(bp);
2019931a
DC
1314 return 1;
1315 }
1316 src += sizeof(struct xfs_dsymlink_hdr);
1317 }
1318
1319 memmove(dst + offset, src, byte_cnt);
1320
1321 pathlen -= byte_cnt;
1322 offset += byte_cnt;
1323 i++;
1324
18b4f688 1325 if (badcrc && !no_modify) {
f524ae04 1326 libxfs_buf_mark_dirty(bp);
18b4f688
DW
1327 libxfs_buf_relse(bp);
1328 }
7cb3f7fe 1329 else
e02ba985 1330 libxfs_buf_relse(bp);
2019931a
DC
1331 }
1332 return 0;
1333}
1334
2bd0ea18
NS
1335/*
1336 * like usual, returns 0 if everything's ok and 1 if something's
1337 * bogus
1338 */
8b8a6b02 1339static int
0459b626 1340process_symlink(
7328ea6e
CH
1341 xfs_mount_t *mp,
1342 xfs_ino_t lino,
1343 struct xfs_dinode *dino,
1344 blkmap_t *blkmap)
2bd0ea18 1345{
2116b6a6 1346 char *symlink;
5a707ca1 1347 char data[XFS_SYMLINK_MAXLEN];
2bd0ea18
NS
1348
1349 /*
1350 * check size against kernel symlink limits. we know
1351 * size is consistent with inode storage format -- e.g.
1352 * the inode is structurally ok so we don't have to check
1353 * for that
1354 */
5a707ca1 1355 if (be64_to_cpu(dino->di_size) >= XFS_SYMLINK_MAXLEN) {
5d1b7f0f
CH
1356 do_warn(_("symlink in inode %" PRIu64 " too long (%llu chars)\n"),
1357 lino, (unsigned long long) be64_to_cpu(dino->di_size));
2bd0ea18
NS
1358 return(1);
1359 }
1360
948ade75
BF
1361 if (be64_to_cpu(dino->di_size) == 0) {
1362 do_warn(_("zero size symlink in inode %" PRIu64 "\n"), lino);
1363 return 1;
1364 }
1365
2bd0ea18
NS
1366 /*
1367 * have to check symlink component by component.
1368 * get symlink contents into data area
1369 */
1370 symlink = &data[0];
56b2de80 1371 if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
2bd0ea18
NS
1372 /*
1373 * local symlink, just copy the symlink out of the
1374 * inode into the data area
1375 */
f8149110 1376 memmove(symlink, XFS_DFORK_DPTR(dino),
56b2de80 1377 be64_to_cpu(dino->di_size));
2bd0ea18 1378 } else {
2019931a 1379 int error;
e0607266 1380
2019931a
DC
1381 error = process_symlink_remote(mp, lino, dino, blkmap, symlink);
1382 if (error)
1383 return error;
2bd0ea18 1384 }
2019931a 1385
56b2de80 1386 data[be64_to_cpu(dino->di_size)] = '\0';
2bd0ea18
NS
1387
1388 /*
1389 * check for nulls
1390 */
56b2de80 1391 if (null_check(symlink, be64_to_cpu(dino->di_size))) {
507f4e33 1392 do_warn(
5d1b7f0f 1393_("found illegal null character in symlink inode %" PRIu64 "\n"),
2bd0ea18
NS
1394 lino);
1395 return(1);
1396 }
1397
2bd0ea18
NS
1398 return(0);
1399}
1400
1401/*
1402 * called to process the set of misc inode special inode types
1403 * that have no associated data storage (fifos, pipes, devices, etc.).
1404 */
0459b626 1405static int
7328ea6e
CH
1406process_misc_ino_types(
1407 xfs_mount_t *mp,
1408 struct xfs_dinode *dino,
1409 xfs_ino_t lino,
1410 int type)
2bd0ea18 1411{
2bd0ea18
NS
1412 /*
1413 * must also have a zero size
1414 */
56b2de80 1415 if (be64_to_cpu(dino->di_size) != 0) {
2bd0ea18
NS
1416 switch (type) {
1417 case XR_INO_CHRDEV:
5d1b7f0f
CH
1418 do_warn(
1419_("size of character device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1420 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1421 break;
1422 case XR_INO_BLKDEV:
5d1b7f0f
CH
1423 do_warn(
1424_("size of block device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1425 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1426 break;
1427 case XR_INO_SOCK:
5d1b7f0f
CH
1428 do_warn(
1429_("size of socket inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1430 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18
NS
1431 break;
1432 case XR_INO_FIFO:
5d1b7f0f
CH
1433 do_warn(
1434_("size of fifo inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
14f8b681 1435 (int64_t)be64_to_cpu(dino->di_size));
2bd0ea18 1436 break;
5857dce9
ES
1437 case XR_INO_UQUOTA:
1438 case XR_INO_GQUOTA:
1439 case XR_INO_PQUOTA:
1440 do_warn(
1441_("size of quota inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino,
1442 (int64_t)be64_to_cpu(dino->di_size));
1443 break;
2bd0ea18 1444 default:
507f4e33
NS
1445 do_warn(_("Internal error - process_misc_ino_types, "
1446 "illegal type %d\n"), type);
2bd0ea18
NS
1447 abort();
1448 }
1449
1450 return(1);
1451 }
1452
1453 return(0);
1454}
1455
5e656dbb 1456static int
5a35bf2c 1457process_misc_ino_types_blocks(xfs_rfsblock_t totblocks, xfs_ino_t lino, int type)
2bd0ea18
NS
1458{
1459 /*
1460 * you can not enforce all misc types have zero data fork blocks
56b2de80 1461 * by checking dino->di_nblocks because atotblocks (attribute
2bd0ea18 1462 * blocks) are part of nblocks. We must check this later when atotblocks
dfc130f3 1463 * has been calculated or by doing a simple check that anExtents == 0.
2bd0ea18
NS
1464 * We must also guarantee that totblocks is 0. Thus nblocks checking
1465 * will be done later in process_dinode_int for misc types.
1466 */
1467
1468 if (totblocks != 0) {
1469 switch (type) {
1470 case XR_INO_CHRDEV:
1471 do_warn(
5d1b7f0f 1472_("size of character device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1473 lino, totblocks);
1474 break;
1475 case XR_INO_BLKDEV:
1476 do_warn(
5d1b7f0f 1477_("size of block device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1478 lino, totblocks);
1479 break;
1480 case XR_INO_SOCK:
1481 do_warn(
5d1b7f0f 1482_("size of socket inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1483 lino, totblocks);
1484 break;
1485 case XR_INO_FIFO:
1486 do_warn(
5d1b7f0f 1487_("size of fifo inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"),
2bd0ea18
NS
1488 lino, totblocks);
1489 break;
1490 default:
1491 return(0);
1492 }
1493 return(1);
1494 }
1495 return (0);
1496}
1497
0459b626
BN
1498static inline int
1499dinode_fmt(
7328ea6e 1500 struct xfs_dinode *dino)
2bd0ea18 1501{
56b2de80 1502 return be16_to_cpu(dino->di_mode) & S_IFMT;
0459b626 1503}
2bd0ea18 1504
0459b626
BN
1505static inline void
1506change_dinode_fmt(
7328ea6e
CH
1507 struct xfs_dinode *dino,
1508 int new_fmt)
0459b626 1509{
7328ea6e 1510 int mode = be16_to_cpu(dino->di_mode);
2bd0ea18 1511
0459b626 1512 ASSERT((new_fmt & ~S_IFMT) == 0);
2bd0ea18 1513
0459b626
BN
1514 mode &= ~S_IFMT;
1515 mode |= new_fmt;
56b2de80 1516 dino->di_mode = cpu_to_be16(mode);
0459b626
BN
1517}
1518
1519static int
1520check_dinode_mode_format(
7328ea6e 1521 struct xfs_dinode *dinoc)
0459b626 1522{
5e656dbb 1523 if (dinoc->di_format >= XFS_DINODE_FMT_UUID)
0459b626
BN
1524 return -1; /* FMT_UUID is not used */
1525
1526 switch (dinode_fmt(dinoc)) {
1527 case S_IFIFO:
1528 case S_IFCHR:
1529 case S_IFBLK:
1530 case S_IFSOCK:
1531 return (dinoc->di_format != XFS_DINODE_FMT_DEV) ? -1 : 0;
1532
1533 case S_IFDIR:
1534 return (dinoc->di_format < XFS_DINODE_FMT_LOCAL ||
1535 dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0;
1536
1537 case S_IFREG:
1538 return (dinoc->di_format < XFS_DINODE_FMT_EXTENTS ||
1539 dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0;
1540
1541 case S_IFLNK:
1542 return (dinoc->di_format < XFS_DINODE_FMT_LOCAL ||
1543 dinoc->di_format > XFS_DINODE_FMT_EXTENTS) ? -1 : 0;
1544
1545 default: ;
1546 }
1547 return 0; /* invalid modes are checked elsewhere */
1548}
1549
1550/*
1551 * If inode is a superblock inode, does type check to make sure is it valid.
1552 * Returns 0 if it's valid, non-zero if it needs to be cleared.
1553 */
1554
1555static int
1556process_check_sb_inodes(
7328ea6e
CH
1557 xfs_mount_t *mp,
1558 struct xfs_dinode *dinoc,
1559 xfs_ino_t lino,
1560 int *type,
1561 int *dirty)
0459b626 1562{
5f70c91b
CB
1563 xfs_extnum_t dnextents;
1564
0459b626 1565 if (lino == mp->m_sb.sb_rootino) {
5857dce9 1566 if (*type != XR_INO_DIR) {
5d1b7f0f 1567 do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1568 lino, dinode_fmt(dinoc));
1569 *type = XR_INO_DIR;
2bd0ea18 1570 if (!no_modify) {
0459b626
BN
1571 do_warn(_("resetting to directory\n"));
1572 change_dinode_fmt(dinoc, S_IFDIR);
2bd0ea18 1573 *dirty = 1;
0459b626
BN
1574 } else
1575 do_warn(_("would reset to directory\n"));
2bd0ea18 1576 }
0459b626 1577 return 0;
2bd0ea18 1578 }
0459b626 1579 if (lino == mp->m_sb.sb_uquotino) {
5857dce9 1580 if (*type != XR_INO_UQUOTA) {
5d1b7f0f 1581 do_warn(_("user quota inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1582 lino, dinode_fmt(dinoc));
1583 mp->m_sb.sb_uquotino = NULLFSINO;
1584 return 1;
1585 }
1586 return 0;
1587 }
1588 if (lino == mp->m_sb.sb_gquotino) {
5857dce9 1589 if (*type != XR_INO_GQUOTA) {
5d1b7f0f 1590 do_warn(_("group quota inode %" PRIu64 " has bad type 0x%x\n"),
0459b626
BN
1591 lino, dinode_fmt(dinoc));
1592 mp->m_sb.sb_gquotino = NULLFSINO;
1593 return 1;
1594 }
1595 return 0;
1596 }
0340d706 1597 if (lino == mp->m_sb.sb_pquotino) {
5857dce9 1598 if (*type != XR_INO_PQUOTA) {
0340d706
CS
1599 do_warn(_("project quota inode %" PRIu64 " has bad type 0x%x\n"),
1600 lino, dinode_fmt(dinoc));
1601 mp->m_sb.sb_pquotino = NULLFSINO;
1602 return 1;
1603 }
1604 return 0;
1605 }
5f70c91b 1606 dnextents = xfs_dfork_data_extents(dinoc);
0459b626
BN
1607 if (lino == mp->m_sb.sb_rsumino) {
1608 if (*type != XR_INO_RTSUM) {
5d1b7f0f
CH
1609 do_warn(
1610_("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
0459b626 1611 lino, dinode_fmt(dinoc));
2bd0ea18 1612 if (!no_modify) {
0459b626
BN
1613 do_warn(_("resetting to regular file\n"));
1614 change_dinode_fmt(dinoc, S_IFREG);
2bd0ea18 1615 *dirty = 1;
2bd0ea18 1616 } else {
0459b626 1617 do_warn(_("would reset to regular file\n"));
2bd0ea18 1618 }
2bd0ea18 1619 }
5f70c91b 1620 if (mp->m_sb.sb_rblocks == 0 && dnextents != 0) {
5d1b7f0f 1621 do_warn(
4b85994a 1622_("bad # of extents (%" PRIu64 ") for realtime summary inode %" PRIu64 "\n"),
5f70c91b 1623 dnextents, lino);
0459b626
BN
1624 return 1;
1625 }
1626 return 0;
2bd0ea18 1627 }
0459b626
BN
1628 if (lino == mp->m_sb.sb_rbmino) {
1629 if (*type != XR_INO_RTBITMAP) {
5d1b7f0f
CH
1630 do_warn(
1631_("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
0459b626 1632 lino, dinode_fmt(dinoc));
2bd0ea18 1633 if (!no_modify) {
0459b626
BN
1634 do_warn(_("resetting to regular file\n"));
1635 change_dinode_fmt(dinoc, S_IFREG);
2bd0ea18 1636 *dirty = 1;
0459b626
BN
1637 } else {
1638 do_warn(_("would reset to regular file\n"));
2bd0ea18 1639 }
2bd0ea18 1640 }
5f70c91b 1641 if (mp->m_sb.sb_rblocks == 0 && dnextents != 0) {
5d1b7f0f 1642 do_warn(
4b85994a 1643_("bad # of extents (%" PRIu64 ") for realtime bitmap inode %" PRIu64 "\n"),
5f70c91b 1644 dnextents, lino);
0459b626 1645 return 1;
2bd0ea18 1646 }
0459b626
BN
1647 return 0;
1648 }
1649 return 0;
1650}
2bd0ea18 1651
0459b626
BN
1652/*
1653 * general size/consistency checks:
1654 *
1655 * if the size <= size of the data fork, directories must be
1656 * local inodes unlike regular files which would be extent inodes.
1657 * all the other mentioned types have to have a zero size value.
1658 *
1659 * if the size and format don't match, get out now rather than
1660 * risk trying to process a non-existent extents or btree
1661 * type data fork.
1662 */
1663static int
1664process_check_inode_sizes(
7328ea6e
CH
1665 xfs_mount_t *mp,
1666 struct xfs_dinode *dino,
1667 xfs_ino_t lino,
1668 int type)
0459b626 1669{
7328ea6e 1670 xfs_fsize_t size = be64_to_cpu(dino->di_size);
2bd0ea18 1671
0459b626 1672 switch (type) {
2bd0ea18 1673
0459b626
BN
1674 case XR_INO_DIR:
1675 if (size <= XFS_DFORK_DSIZE(dino, mp) &&
56b2de80 1676 dino->di_format != XFS_DINODE_FMT_LOCAL) {
5d1b7f0f
CH
1677 do_warn(
1678_("mismatch between format (%d) and size (%" PRId64 ") in directory ino %" PRIu64 "\n"),
56b2de80 1679 dino->di_format, size, lino);
0459b626 1680 return 1;
2bd0ea18 1681 }
42237e34 1682 if (size > XFS_DIR2_LEAF_OFFSET) {
5d1b7f0f
CH
1683 do_warn(
1684_("directory inode %" PRIu64 " has bad size %" PRId64 "\n"),
42237e34
BN
1685 lino, size);
1686 return 1;
1687 }
0459b626 1688 break;
2bd0ea18 1689
0459b626
BN
1690 case XR_INO_SYMLINK:
1691 if (process_symlink_extlist(mp, lino, dino)) {
5d1b7f0f 1692 do_warn(_("bad data fork in symlink %" PRIu64 "\n"), lino);
0459b626
BN
1693 return 1;
1694 }
1695 break;
2bd0ea18 1696
7c432f77
DW
1697 case XR_INO_CHRDEV:
1698 case XR_INO_BLKDEV:
1699 case XR_INO_SOCK:
0459b626
BN
1700 case XR_INO_FIFO:
1701 if (process_misc_ino_types(mp, dino, lino, type))
1702 return 1;
1703 break;
2bd0ea18 1704
5857dce9
ES
1705 case XR_INO_UQUOTA:
1706 case XR_INO_GQUOTA:
1707 case XR_INO_PQUOTA:
1708 /* Quota inodes have same restrictions as above types */
1709 if (process_misc_ino_types(mp, dino, lino, type))
1710 return 1;
1711 break;
1712
0459b626
BN
1713 case XR_INO_RTDATA:
1714 /*
1715 * if we have no realtime blocks, any inode claiming
1716 * to be a real-time file is bogus
1717 */
1718 if (mp->m_sb.sb_rblocks == 0) {
5d1b7f0f
CH
1719 do_warn(
1720_("found inode %" PRIu64 " claiming to be a real-time file\n"), lino);
0459b626 1721 return 1;
2bd0ea18 1722 }
0459b626 1723 break;
2bd0ea18 1724
0459b626 1725 case XR_INO_RTBITMAP:
14f8b681 1726 if (size != (int64_t)mp->m_sb.sb_rbmblocks *
0459b626 1727 mp->m_sb.sb_blocksize) {
5d1b7f0f
CH
1728 do_warn(
1729_("realtime bitmap inode %" PRIu64 " has bad size %" PRId64 " (should be %" PRIu64 ")\n"),
1730 lino, size,
14f8b681 1731 (int64_t) mp->m_sb.sb_rbmblocks *
0459b626
BN
1732 mp->m_sb.sb_blocksize);
1733 return 1;
1734 }
1735 break;
2bd0ea18 1736
0459b626
BN
1737 case XR_INO_RTSUM:
1738 if (size != mp->m_rsumsize) {
5d1b7f0f
CH
1739 do_warn(
1740_("realtime summary inode %" PRIu64 " has bad size %" PRId64 " (should be %d)\n"),
0459b626
BN
1741 lino, size, mp->m_rsumsize);
1742 return 1;
1743 }
1744 break;
2bd0ea18 1745
0459b626
BN
1746 default:
1747 break;
1748 }
1749 return 0;
1750}
2bd0ea18 1751
0459b626
BN
1752/*
1753 * check for illegal values of forkoff
1754 */
1755static int
1756process_check_inode_forkoff(
7328ea6e
CH
1757 xfs_mount_t *mp,
1758 struct xfs_dinode *dino,
1759 xfs_ino_t lino)
0459b626 1760{
56b2de80 1761 if (dino->di_forkoff == 0)
0459b626 1762 return 0;
2bd0ea18 1763
56b2de80 1764 switch (dino->di_format) {
0459b626 1765 case XFS_DINODE_FMT_DEV:
56b2de80 1766 if (dino->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3)) {
5d1b7f0f
CH
1767 do_warn(
1768_("bad attr fork offset %d in dev inode %" PRIu64 ", should be %d\n"),
1769 dino->di_forkoff, lino,
0459b626
BN
1770 (int)(roundup(sizeof(xfs_dev_t), 8) >> 3));
1771 return 1;
1772 }
2bd0ea18 1773 break;
7c432f77
DW
1774 case XFS_DINODE_FMT_LOCAL:
1775 case XFS_DINODE_FMT_EXTENTS:
0459b626 1776 case XFS_DINODE_FMT_BTREE:
4de63245 1777 if (dino->di_forkoff >= (XFS_LITINO(mp) >> 3)) {
5d1b7f0f 1778 do_warn(
4de63245
CH
1779_("bad attr fork offset %d in inode %" PRIu64 ", max=%zu\n"),
1780 dino->di_forkoff, lino, XFS_LITINO(mp) >> 3);
0459b626
BN
1781 return 1;
1782 }
2bd0ea18 1783 break;
2bd0ea18 1784 default:
56b2de80 1785 do_error(_("unexpected inode format %d\n"), dino->di_format);
0459b626 1786 break;
2bd0ea18 1787 }
0459b626
BN
1788 return 0;
1789}
2bd0ea18 1790
0459b626
BN
1791/*
1792 * Updates the inodes block and extent counts if they are wrong
1793 */
1794static int
1795process_inode_blocks_and_extents(
7328ea6e
CH
1796 struct xfs_dinode *dino,
1797 xfs_rfsblock_t nblocks,
1798 uint64_t nextents,
1799 uint64_t anextents,
1800 xfs_ino_t lino,
1801 int *dirty)
0459b626 1802{
5f70c91b
CB
1803 xfs_extnum_t dnextents;
1804 xfs_extnum_t danextents;
1805
56b2de80 1806 if (nblocks != be64_to_cpu(dino->di_nblocks)) {
2bd0ea18 1807 if (!no_modify) {
5d1b7f0f
CH
1808 do_warn(
1809_("correcting nblocks for inode %" PRIu64 ", was %llu - counted %" PRIu64 "\n"), lino,
1810 (unsigned long long) be64_to_cpu(dino->di_nblocks),
1811 nblocks);
56b2de80 1812 dino->di_nblocks = cpu_to_be64(nblocks);
0459b626 1813 *dirty = 1;
2bd0ea18 1814 } else {
5d1b7f0f
CH
1815 do_warn(
1816_("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
1817 (unsigned long long) be64_to_cpu(dino->di_nblocks),
1818 lino, nblocks);
2bd0ea18
NS
1819 }
1820 }
1821
5a8b4d6a
CB
1822 if (nextents > xfs_iext_max_nextents(
1823 xfs_dinode_has_large_extent_counts(dino),
1824 XFS_DATA_FORK)) {
5d1b7f0f
CH
1825 do_warn(
1826_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
0459b626
BN
1827 nextents, lino);
1828 return 1;
1829 }
5f70c91b
CB
1830 dnextents = xfs_dfork_data_extents(dino);
1831 if (nextents != dnextents) {
2bd0ea18 1832 if (!no_modify) {
5d1b7f0f 1833 do_warn(
4b85994a 1834_("correcting nextents for inode %" PRIu64 ", was %" PRIu64 " - counted %" PRIu64 "\n"),
5f70c91b 1835 lino, dnextents, nextents);
8be26c6a
CB
1836 if (xfs_dinode_has_large_extent_counts(dino))
1837 dino->di_big_nextents = cpu_to_be64(nextents);
1838 else
1839 dino->di_nextents = cpu_to_be32(nextents);
0459b626 1840 *dirty = 1;
2bd0ea18 1841 } else {
5d1b7f0f 1842 do_warn(
4b85994a 1843_("bad nextents %" PRIu64 " for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
5f70c91b 1844 dnextents, lino, nextents);
2bd0ea18
NS
1845 }
1846 }
1847
5a8b4d6a
CB
1848 if (anextents > xfs_iext_max_nextents(
1849 xfs_dinode_has_large_extent_counts(dino),
1850 XFS_ATTR_FORK)) {
5d1b7f0f
CH
1851 do_warn(
1852_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
0459b626
BN
1853 anextents, lino);
1854 return 1;
2bd0ea18 1855 }
5f70c91b
CB
1856 danextents = xfs_dfork_attr_extents(dino);
1857 if (anextents != danextents) {
2bd0ea18 1858 if (!no_modify) {
5d1b7f0f 1859 do_warn(
4b85994a 1860_("correcting anextents for inode %" PRIu64 ", was %" PRIu64 " - counted %" PRIu64 "\n"),
5f70c91b 1861 lino, danextents, anextents);
8be26c6a
CB
1862 if (xfs_dinode_has_large_extent_counts(dino))
1863 dino->di_big_anextents = cpu_to_be32(anextents);
1864 else
1865 dino->di_anextents = cpu_to_be16(anextents);
0459b626
BN
1866 *dirty = 1;
1867 } else {
5d1b7f0f 1868 do_warn(
4b85994a 1869_("bad anextents %" PRIu64 " for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
5f70c91b 1870 danextents, lino, anextents);
2bd0ea18 1871 }
2bd0ea18 1872 }
e1f43b4c
CH
1873
1874 /*
1875 * We are comparing different units here, but that's fine given that
1876 * an extent has to have at least a block in it.
1877 */
1878 if (nblocks < nextents + anextents) {
1879 do_warn(
1880_("nblocks (%" PRIu64 ") smaller than nextents for inode %" PRIu64 "\n"), nblocks, lino);
1881 return 1;
1882 }
1883
0459b626
BN
1884 return 0;
1885}
2bd0ea18 1886
0459b626
BN
1887/*
1888 * check data fork -- if it's bad, clear the inode
1889 */
1890static int
1891process_inode_data_fork(
7328ea6e
CH
1892 xfs_mount_t *mp,
1893 xfs_agnumber_t agno,
1894 xfs_agino_t ino,
1895 struct xfs_dinode *dino,
1896 int type,
1897 int *dirty,
1898 xfs_rfsblock_t *totblocks,
3a2414fa 1899 xfs_extnum_t *nextents,
7328ea6e
CH
1900 blkmap_t **dblkmap,
1901 int check_dups)
0459b626 1902{
7328ea6e
CH
1903 xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
1904 int err = 0;
95e3fc7f 1905 xfs_extnum_t nex, max_nex;
5fa28531
DC
1906
1907 /*
1908 * extent count on disk is only valid for positive values. The kernel
1909 * uses negative values in memory. hence if we see negative numbers
1910 * here, trash it!
1911 */
5f70c91b 1912 nex = xfs_dfork_data_extents(dino);
95e3fc7f
DW
1913 max_nex = xfs_iext_max_nextents(
1914 xfs_dinode_has_large_extent_counts(dino),
1915 XFS_DATA_FORK);
1916 if (nex > max_nex)
5fa28531
DC
1917 *nextents = 1;
1918 else
1919 *nextents = nex;
2bd0ea18 1920
56b2de80 1921 if (*nextents > be64_to_cpu(dino->di_nblocks))
0459b626 1922 *nextents = 1;
2bd0ea18 1923
5fa28531 1924
56b2de80 1925 if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA)
610f3285 1926 *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK);
0459b626 1927 *nextents = 0;
2bd0ea18 1928
56b2de80 1929 switch (dino->di_format) {
2bd0ea18 1930 case XFS_DINODE_FMT_LOCAL:
5e656dbb
BN
1931 err = process_lclinode(mp, agno, ino, dino, XFS_DATA_FORK);
1932 *totblocks = 0;
2bd0ea18
NS
1933 break;
1934 case XFS_DINODE_FMT_EXTENTS:
0459b626
BN
1935 err = process_exinode(mp, agno, ino, dino, type, dirty,
1936 totblocks, nextents, dblkmap, XFS_DATA_FORK,
1937 check_dups);
2bd0ea18
NS
1938 break;
1939 case XFS_DINODE_FMT_BTREE:
0459b626
BN
1940 err = process_btinode(mp, agno, ino, dino, type, dirty,
1941 totblocks, nextents, dblkmap, XFS_DATA_FORK,
1942 check_dups);
2bd0ea18 1943 break;
7c432f77 1944 case XFS_DINODE_FMT_DEV:
2bd0ea18
NS
1945 err = 0;
1946 break;
1947 default:
5d1b7f0f 1948 do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"),
56b2de80 1949 dino->di_format, lino, be16_to_cpu(dino->di_mode));
2bd0ea18
NS
1950 }
1951
1952 if (err) {
5d1b7f0f 1953 do_warn(_("bad data fork in inode %" PRIu64 "\n"), lino);
2bd0ea18 1954 if (!no_modify) {
0724d0f4
ES
1955 clear_dinode(mp, dino, lino);
1956 *dirty += 1;
2bd0ea18 1957 }
0459b626 1958 return 1;
2bd0ea18
NS
1959 }
1960
1961 if (check_dups) {
1962 /*
1963 * if check_dups was non-zero, we have to
1964 * re-process data fork to set bitmap since the
1965 * bitmap wasn't set the first time through
1966 */
56b2de80 1967 switch (dino->di_format) {
2bd0ea18 1968 case XFS_DINODE_FMT_LOCAL:
f8149110 1969 err = process_lclinode(mp, agno, ino, dino,
5e656dbb 1970 XFS_DATA_FORK);
2bd0ea18
NS
1971 break;
1972 case XFS_DINODE_FMT_EXTENTS:
1973 err = process_exinode(mp, agno, ino, dino, type,
0459b626 1974 dirty, totblocks, nextents, dblkmap,
2bd0ea18
NS
1975 XFS_DATA_FORK, 0);
1976 break;
1977 case XFS_DINODE_FMT_BTREE:
1978 err = process_btinode(mp, agno, ino, dino, type,
0459b626 1979 dirty, totblocks, nextents, dblkmap,
2bd0ea18
NS
1980 XFS_DATA_FORK, 0);
1981 break;
7c432f77 1982 case XFS_DINODE_FMT_DEV:
2bd0ea18
NS
1983 err = 0;
1984 break;
1985 default:
5d1b7f0f 1986 do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"),
56b2de80
DC
1987 dino->di_format, lino,
1988 be16_to_cpu(dino->di_mode));
2bd0ea18
NS
1989 }
1990
0459b626
BN
1991 if (no_modify && err != 0)
1992 return 1;
2bd0ea18
NS
1993
1994 ASSERT(err == 0);
1995 }
0459b626
BN
1996 return 0;
1997}
2bd0ea18 1998
0459b626
BN
1999/*
2000 * Process extended attribute fork in inode
2001 */
2002static int
2003process_inode_attr_fork(
7328ea6e
CH
2004 xfs_mount_t *mp,
2005 xfs_agnumber_t agno,
2006 xfs_agino_t ino,
2007 struct xfs_dinode *dino,
2008 int type,
2009 int *dirty,
2010 xfs_rfsblock_t *atotblocks,
3a2414fa 2011 xfs_extnum_t *anextents,
7328ea6e
CH
2012 int check_dups,
2013 int extra_attr_check,
2014 int *retval)
0459b626 2015{
7328ea6e
CH
2016 xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
2017 blkmap_t *ablkmap = NULL;
2018 int repair = 0;
2019 int err;
0459b626 2020
8c6cccd7 2021 if (!dino->di_forkoff) {
0459b626 2022 *anextents = 0;
56b2de80 2023 if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
5d1b7f0f 2024 do_warn(_("bad attribute format %d in inode %" PRIu64 ", "),
56b2de80 2025 dino->di_aformat, lino);
0459b626
BN
2026 if (!no_modify) {
2027 do_warn(_("resetting value\n"));
56b2de80 2028 dino->di_aformat = XFS_DINODE_FMT_EXTENTS;
0459b626
BN
2029 *dirty = 1;
2030 } else
2031 do_warn(_("would reset value\n"));
2032 }
2033 return 0;
2034 }
2bd0ea18 2035
5f70c91b 2036 *anextents = xfs_dfork_attr_extents(dino);
56b2de80 2037 if (*anextents > be64_to_cpu(dino->di_nblocks))
0459b626
BN
2038 *anextents = 1;
2039
56b2de80 2040 switch (dino->di_aformat) {
0459b626
BN
2041 case XFS_DINODE_FMT_LOCAL:
2042 *anextents = 0;
5e656dbb
BN
2043 *atotblocks = 0;
2044 err = process_lclinode(mp, agno, ino, dino, XFS_ATTR_FORK);
0459b626
BN
2045 break;
2046 case XFS_DINODE_FMT_EXTENTS:
610f3285 2047 ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK);
0459b626
BN
2048 *anextents = 0;
2049 err = process_exinode(mp, agno, ino, dino, type, dirty,
2050 atotblocks, anextents, &ablkmap,
2bd0ea18 2051 XFS_ATTR_FORK, check_dups);
0459b626
BN
2052 break;
2053 case XFS_DINODE_FMT_BTREE:
610f3285 2054 ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK);
0459b626
BN
2055 *anextents = 0;
2056 err = process_btinode(mp, agno, ino, dino, type, dirty,
2057 atotblocks, anextents, &ablkmap,
2bd0ea18 2058 XFS_ATTR_FORK, check_dups);
0459b626
BN
2059 break;
2060 default:
5d1b7f0f 2061 do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"),
56b2de80 2062 dino->di_aformat, lino);
0459b626
BN
2063 err = 1;
2064 break;
2065 }
2bd0ea18 2066
0459b626
BN
2067 if (err) {
2068 /*
2069 * clear the attribute fork if necessary. we can't
2070 * clear the inode because we've already put the
2071 * inode space info into the blockmap.
2072 *
2073 * XXX - put the inode onto the "move it" list and
2074 * log the the attribute scrubbing
2075 */
5d1b7f0f 2076 do_warn(_("bad attribute fork in inode %" PRIu64), lino);
2bd0ea18 2077
0459b626 2078 if (!no_modify) {
28a4f9c0
ES
2079 do_warn(_(", clearing attr fork\n"));
2080 *dirty += clear_dinode_attr(mp, dino, lino);
2081 dino->di_aformat = XFS_DINODE_FMT_LOCAL;
0459b626
BN
2082 ASSERT(*dirty > 0);
2083 } else {
2084 do_warn(_(", would clear attr fork\n"));
2bd0ea18
NS
2085 }
2086
0459b626
BN
2087 *atotblocks = 0;
2088 *anextents = 0;
2bd0ea18 2089 blkmap_free(ablkmap);
0459b626 2090 *retval = 1;
2bd0ea18 2091
28a4f9c0 2092 return 0;
2bd0ea18
NS
2093 }
2094
0459b626 2095 if (check_dups) {
56b2de80 2096 switch (dino->di_aformat) {
0459b626 2097 case XFS_DINODE_FMT_LOCAL:
f8149110 2098 err = process_lclinode(mp, agno, ino, dino,
5e656dbb 2099 XFS_ATTR_FORK);
0459b626
BN
2100 break;
2101 case XFS_DINODE_FMT_EXTENTS:
2102 err = process_exinode(mp, agno, ino, dino,
2103 type, dirty, atotblocks, anextents,
2104 &ablkmap, XFS_ATTR_FORK, 0);
2105 break;
2106 case XFS_DINODE_FMT_BTREE:
2107 err = process_btinode(mp, agno, ino, dino,
2108 type, dirty, atotblocks, anextents,
2109 &ablkmap, XFS_ATTR_FORK, 0);
2110 break;
2111 default:
5d1b7f0f 2112 do_error(_("illegal attribute fmt %d, ino %" PRIu64 "\n"),
56b2de80 2113 dino->di_aformat, lino);
2bd0ea18 2114 }
2bd0ea18 2115
0459b626
BN
2116 if (no_modify && err != 0) {
2117 blkmap_free(ablkmap);
2118 return 1;
2bd0ea18 2119 }
2bd0ea18 2120
0459b626 2121 ASSERT(err == 0);
2bd0ea18
NS
2122 }
2123
0459b626
BN
2124 /*
2125 * do attribute semantic-based consistency checks now
2126 */
2bd0ea18 2127
0459b626
BN
2128 /* get this only in phase 3, not in both phase 3 and 4 */
2129 if (extra_attr_check &&
2130 process_attributes(mp, lino, dino, ablkmap, &repair)) {
5d1b7f0f
CH
2131 do_warn(
2132 _("problem with attribute contents in inode %" PRIu64 "\n"),
0459b626
BN
2133 lino);
2134 if (!repair) {
2135 /* clear attributes if not done already */
2136 if (!no_modify) {
2137 *dirty += clear_dinode_attr(mp, dino, lino);
56b2de80 2138 dino->di_aformat = XFS_DINODE_FMT_LOCAL;
0459b626
BN
2139 } else {
2140 do_warn(_("would clear attr fork\n"));
2141 }
2142 *atotblocks = 0;
2143 *anextents = 0;
2bd0ea18 2144 }
0459b626
BN
2145 else {
2146 *dirty = 1; /* it's been repaired */
2bd0ea18
NS
2147 }
2148 }
0459b626
BN
2149 blkmap_free(ablkmap);
2150 return 0;
2151}
2bd0ea18 2152
0459b626
BN
2153/*
2154 * check nlinks feature, if it's a version 1 inode,
2155 * just leave nlinks alone. even if it's set wrong,
2156 * it'll be reset when read in.
2157 */
2bd0ea18 2158
0459b626
BN
2159static int
2160process_check_inode_nlink_version(
7328ea6e
CH
2161 struct xfs_dinode *dino,
2162 xfs_ino_t lino)
0459b626 2163{
7328ea6e 2164 int dirty = 0;
2bd0ea18 2165
2bd0ea18 2166 /*
5f6f3660 2167 * if it's a version 2 inode, it should have a zero
2bd0ea18
NS
2168 * onlink field, so clear it.
2169 */
5f6f3660 2170 if (dino->di_version > 1 && dino->di_onlink != 0) {
0459b626 2171 if (!no_modify) {
5d1b7f0f
CH
2172 do_warn(
2173_("clearing obsolete nlink field in version 2 inode %" PRIu64 ", was %d, now 0\n"),
56b2de80
DC
2174 lino, be16_to_cpu(dino->di_onlink));
2175 dino->di_onlink = 0;
0459b626 2176 dirty = 1;
2bd0ea18 2177 } else {
5d1b7f0f
CH
2178 do_warn(
2179_("would clear obsolete nlink field in version 2 inode %" PRIu64 ", currently %d\n"),
56b2de80 2180 lino, be16_to_cpu(dino->di_onlink));
0459b626
BN
2181 }
2182 }
2183 return dirty;
2184}
2185
8fec4f7c
DW
2186/* Check nanoseconds of a timestamp don't exceed 1 second. */
2187static void
2188check_nsec(
2189 const char *name,
2190 xfs_ino_t lino,
37c7dda1 2191 struct xfs_dinode *dip,
a252aadf 2192 xfs_timestamp_t *ts,
8fec4f7c
DW
2193 int *dirty)
2194{
a252aadf
DW
2195 struct xfs_legacy_timestamp *t;
2196
37c7dda1
DW
2197 if (xfs_dinode_has_bigtime(dip))
2198 return;
2199
a252aadf 2200 t = (struct xfs_legacy_timestamp *)ts;
c0e58015 2201 if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
8fec4f7c
DW
2202 return;
2203
2204 do_warn(
2205_("Bad %s nsec %u on inode %" PRIu64 ", "), name, be32_to_cpu(t->t_nsec), lino);
2206 if (no_modify) {
2207 do_warn(_("would reset to zero\n"));
2208 } else {
2209 do_warn(_("resetting to zero\n"));
2210 t->t_nsec = 0;
2211 *dirty = 1;
2212 }
2213}
2214
5f062427
DW
2215static void
2216validate_extsize(
2217 struct xfs_mount *mp,
2218 struct xfs_dinode *dino,
2219 xfs_ino_t lino,
2220 int *dirty)
2221{
2222 uint16_t flags = be16_to_cpu(dino->di_flags);
2223 unsigned int value = be32_to_cpu(dino->di_extsize);
2224 bool misaligned = false;
2225 bool bad;
2226
2227 /*
2228 * XFS allows a sysadmin to change the rt extent size when adding a rt
2229 * section to a filesystem after formatting. If there are any
2230 * directories with extszinherit and rtinherit set, the hint could
2231 * become misaligned with the new rextsize. The verifier doesn't check
2232 * this, because we allow rtinherit directories even without an rt
2233 * device.
2234 */
2235 if ((flags & XFS_DIFLAG_EXTSZINHERIT) &&
2236 (flags & XFS_DIFLAG_RTINHERIT) &&
2237 value % mp->m_sb.sb_rextsize > 0)
2238 misaligned = true;
2239
2240 /*
2241 * Complain if the verifier fails.
2242 *
2243 * Old kernels didn't check the alignment of extsize hints when copying
2244 * them to new regular realtime files. The inode verifier now checks
2245 * the alignment (because misaligned hints cause misbehavior in the rt
2246 * allocator), so we have to complain and fix them.
2247 */
2248 bad = libxfs_inode_validate_extsize(mp, value,
2249 be16_to_cpu(dino->di_mode), flags) != NULL;
2250 if (bad || misaligned) {
2251 do_warn(
2252_("Bad extent size hint %u on inode %" PRIu64 ", "),
2253 value, lino);
2254 if (!no_modify) {
2255 do_warn(_("resetting to zero\n"));
2256 dino->di_extsize = 0;
2257 dino->di_flags &= ~cpu_to_be16(XFS_DIFLAG_EXTSIZE |
2258 XFS_DIFLAG_EXTSZINHERIT);
2259 *dirty = 1;
2260 } else
2261 do_warn(_("would reset to zero\n"));
2262 }
2263}
2264
0459b626
BN
2265/*
2266 * returns 0 if the inode is ok, 1 if the inode is corrupt
2267 * check_dups can be set to 1 *only* when called by the
2268 * first pass of the duplicate block checking of phase 4.
2269 * *dirty is set > 0 if the dinode has been altered and
2270 * needs to be written out.
2271 *
2272 * for detailed, info, look at process_dinode() comments.
2273 */
8b8a6b02 2274static int
0459b626 2275process_dinode_int(xfs_mount_t *mp,
7328ea6e 2276 struct xfs_dinode *dino,
0459b626
BN
2277 xfs_agnumber_t agno,
2278 xfs_agino_t ino,
2279 int was_free, /* 1 if inode is currently free */
2280 int *dirty, /* out == > 0 if inode is now dirty */
2281 int *used, /* out == 1 if inode is in use */
2282 int verify_mode, /* 1 == verify but don't modify inode */
2283 int uncertain, /* 1 == inode is uncertain */
2284 int ino_discovery, /* 1 == check dirs for unknown inodes */
2285 int check_dups, /* 1 == check if inode claims
2286 * duplicate blocks */
2287 int extra_attr_check, /* 1 == do attribute format and value checks */
2288 int *isa_dir, /* out == 1 if inode is a directory */
2289 xfs_ino_t *parent) /* out -- parent if ino is a dir */
2290{
5a35bf2c
DC
2291 xfs_rfsblock_t totblocks = 0;
2292 xfs_rfsblock_t atotblocks = 0;
0459b626
BN
2293 int di_mode;
2294 int type;
2295 int retval = 0;
3a2414fa
CB
2296 xfs_extnum_t nextents;
2297 xfs_extnum_t anextents;
0459b626
BN
2298 xfs_ino_t lino;
2299 const int is_free = 0;
2300 const int is_used = 1;
2301 blkmap_t *dblkmap = NULL;
6bd73d16 2302 xfs_agino_t unlinked_ino;
0459b626
BN
2303
2304 *dirty = *isa_dir = 0;
2305 *used = is_used;
2306 type = XR_INO_UNKNOWN;
2307
0459b626 2308 lino = XFS_AGINO_TO_INO(mp, agno, ino);
56b2de80 2309 di_mode = be16_to_cpu(dino->di_mode);
0459b626
BN
2310
2311 /*
2312 * if in verify mode, don't modify the inode.
2313 *
2314 * if correcting, reset stuff that has known values
2315 *
2316 * if in uncertain mode, be silent on errors since we're
2317 * trying to find out if these are inodes as opposed
2318 * to assuming that they are. Just return the appropriate
2319 * return code in that case.
2320 *
2321 * If uncertain is set, verify_mode MUST be set.
2322 */
2323 ASSERT(uncertain == 0 || verify_mode != 0);
2324
7d7c5553
ES
2325 /*
2326 * This is the only valid point to check the CRC; after this we may have
2327 * made changes which invalidate it, and the CRC is only updated again
2328 * when it gets written out.
2329 *
2330 * Of course if we make any modifications after this, the inode gets
2331 * rewritten, and the CRC is updated automagically.
2332 */
2660e653 2333 if (xfs_has_crc(mp) &&
e2f60652 2334 !libxfs_verify_cksum((char *)dino, mp->m_sb.sb_inodesize,
7d7c5553
ES
2335 XFS_DINODE_CRC_OFF)) {
2336 retval = 1;
2337 if (!uncertain)
2338 do_warn(_("bad CRC for inode %" PRIu64 "%c"),
2339 lino, verify_mode ? '\n' : ',');
2340 if (!verify_mode) {
2341 if (!no_modify) {
2342 do_warn(_(" will rewrite\n"));
2343 *dirty = 1;
2344 } else
2345 do_warn(_(" would rewrite\n"));
2346 }
2347 }
2348
56b2de80 2349 if (be16_to_cpu(dino->di_magic) != XFS_DINODE_MAGIC) {
0459b626
BN
2350 retval = 1;
2351 if (!uncertain)
5d1b7f0f 2352 do_warn(_("bad magic number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2353 be16_to_cpu(dino->di_magic), lino,
0459b626
BN
2354 verify_mode ? '\n' : ',');
2355 if (!verify_mode) {
2356 if (!no_modify) {
2357 do_warn(_(" resetting magic number\n"));
56b2de80 2358 dino->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
0459b626
BN
2359 *dirty = 1;
2360 } else
2361 do_warn(_(" would reset magic number\n"));
2362 }
2363 }
2364
03d8044d 2365 if (!libxfs_dinode_good_version(mp, dino->di_version)) {
0459b626
BN
2366 retval = 1;
2367 if (!uncertain)
5d1b7f0f 2368 do_warn(_("bad version number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2369 (__s8)dino->di_version, lino,
0459b626
BN
2370 verify_mode ? '\n' : ',');
2371 if (!verify_mode) {
2372 if (!no_modify) {
2373 do_warn(_(" resetting version number\n"));
e0607266 2374 dino->di_version =
2660e653 2375 xfs_has_crc(mp) ? 3 : 2;
0459b626
BN
2376 *dirty = 1;
2377 } else
2378 do_warn(_(" would reset version number\n"));
2379 }
2380 }
2381
6bd73d16
ES
2382 unlinked_ino = be32_to_cpu(dino->di_next_unlinked);
2383 if (!xfs_verify_agino_or_null(mp, agno, unlinked_ino)) {
2384 retval = 1;
2385 if (!uncertain)
2386 do_warn(_("bad next_unlinked 0x%x on inode %" PRIu64 "%c"),
2387 be32_to_cpu(dino->di_next_unlinked), lino,
2388 verify_mode ? '\n' : ',');
2389 if (!verify_mode) {
2390 if (!no_modify) {
2391 do_warn(_(" resetting next_unlinked\n"));
2392 clear_dinode_unlinked(mp, dino);
2393 *dirty = 1;
2394 } else
2395 do_warn(_(" would reset next_unlinked\n"));
2396 }
2397 }
2398
e0607266
DC
2399 /*
2400 * We don't bother checking the CRC here - we cannot guarantee that when
2401 * we are called here that the inode has not already been modified in
2402 * memory and hence invalidated the CRC.
2403 */
2660e653 2404 if (xfs_has_crc(mp)) {
e0607266
DC
2405 if (be64_to_cpu(dino->di_ino) != lino) {
2406 if (!uncertain)
2407 do_warn(
2408_("inode identifier %llu mismatch on inode %" PRIu64 "\n"),
51073f86
DW
2409 (unsigned long long)be64_to_cpu(dino->di_ino),
2410 lino);
e0607266
DC
2411 if (verify_mode)
2412 return 1;
2413 goto clear_bad_out;
2414 }
9c4e12fb
ES
2415 if (platform_uuid_compare(&dino->di_uuid,
2416 &mp->m_sb.sb_meta_uuid)) {
e0607266
DC
2417 if (!uncertain)
2418 do_warn(
2419 _("UUID mismatch on inode %" PRIu64 "\n"), lino);
2420 if (verify_mode)
2421 return 1;
2422 goto clear_bad_out;
2423 }
2424 }
2425
0459b626
BN
2426 /*
2427 * blow out of here if the inode size is < 0
2428 */
56b2de80 2429 if ((xfs_fsize_t)be64_to_cpu(dino->di_size) < 0) {
0459b626 2430 if (!uncertain)
5d1b7f0f
CH
2431 do_warn(
2432_("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
14f8b681 2433 (int64_t)be64_to_cpu(dino->di_size),
5d1b7f0f 2434 lino);
0459b626
BN
2435 if (verify_mode)
2436 return 1;
2437 goto clear_bad_out;
2438 }
2439
2440 /*
0724d0f4 2441 * if not in verify mode, check to see if the inode and imap
0459b626
BN
2442 * agree that the inode is free
2443 */
2444 if (!verify_mode && di_mode == 0) {
2445 /*
2446 * was_free value is not meaningful if we're in verify mode
2447 */
2448 if (was_free) {
2449 /*
2e1bf6c5 2450 * easy case, inode free -- inode and map agree, check
0459b626
BN
2451 * it just in case to ensure that format, etc. are
2452 * set correctly
2453 */
2e1bf6c5
ES
2454 if (libxfs_dinode_verify(mp, lino, dino) != NULL) {
2455 do_warn(
2456 _("free inode %" PRIu64 " contains errors, "), lino);
2457 if (!no_modify) {
0724d0f4 2458 clear_dinode(mp, dino, lino);
2e1bf6c5 2459 do_warn(_("corrected\n"));
0724d0f4 2460 *dirty += 1;
2e1bf6c5
ES
2461 } else {
2462 do_warn(_("would correct\n"));
2463 }
2464 }
0459b626
BN
2465 *used = is_free;
2466 return 0;
2467 }
2468 /*
2469 * the inode looks free but the map says it's in use.
2470 * clear the inode just to be safe and mark the inode
2471 * free.
2472 */
5d1b7f0f
CH
2473 do_warn(
2474 _("imap claims a free inode %" PRIu64 " is in use, "), lino);
0459b626
BN
2475 if (!no_modify) {
2476 do_warn(_("correcting imap and clearing inode\n"));
0724d0f4
ES
2477 clear_dinode(mp, dino, lino);
2478 *dirty += 1;
0459b626
BN
2479 retval = 1;
2480 } else
2481 do_warn(_("would correct imap and clear inode\n"));
2482 *used = is_free;
2483 return retval;
2484 }
2485
2486 /*
2487 * because of the lack of any write ordering guarantee, it's
2488 * possible that the core got updated but the forks didn't.
2489 * so rather than be ambitious (and probably incorrect),
2490 * if there's an inconsistency, we get conservative and
2491 * just pitch the file. blow off checking formats of
2492 * free inodes since technically any format is legal
2493 * as we reset the inode when we re-use it.
2494 */
56b2de80 2495 if (di_mode != 0 && check_dinode_mode_format(dino) != 0) {
0459b626 2496 if (!uncertain)
5d1b7f0f
CH
2497 do_warn(
2498 _("bad inode format in inode %" PRIu64 "\n"), lino);
0459b626
BN
2499 if (verify_mode)
2500 return 1;
2501 goto clear_bad_out;
2502 }
2503
bd5683fe
DC
2504 /*
2505 * check that we only have valid flags set, and those that are set make
2506 * sense.
2507 */
56b2de80
DC
2508 if (dino->di_flags) {
2509 uint16_t flags = be16_to_cpu(dino->di_flags);
bd5683fe
DC
2510
2511 if (flags & ~XFS_DIFLAG_ANY) {
c98f31a5
CH
2512 if (!uncertain) {
2513 do_warn(
2514 _("Bad flags set in inode %" PRIu64 "\n"),
2515 lino);
2516 }
5cd0710a 2517 flags &= XFS_DIFLAG_ANY;
bd5683fe
DC
2518 }
2519
e8e72c93
DW
2520 /* need an rt-dev for the realtime flag! */
2521 if ((flags & XFS_DIFLAG_REALTIME) && !rt_name) {
2522 if (!uncertain) {
2523 do_warn(
c98f31a5 2524 _("inode %" PRIu64 " has RT flag set but there is no RT device\n"),
e8e72c93 2525 lino);
bd5683fe 2526 }
e8e72c93 2527 flags &= ~XFS_DIFLAG_REALTIME;
bd5683fe 2528 }
fb380cb7 2529 if (flags & XFS_DIFLAG_NEWRTBM) {
bd5683fe
DC
2530 /* must be a rt bitmap inode */
2531 if (lino != mp->m_sb.sb_rbmino) {
c98f31a5
CH
2532 if (!uncertain) {
2533 do_warn(
2534 _("inode %" PRIu64 " not rt bitmap\n"),
2535 lino);
2536 }
fb380cb7 2537 flags &= ~XFS_DIFLAG_NEWRTBM;
bd5683fe
DC
2538 }
2539 }
2540 if (flags & (XFS_DIFLAG_RTINHERIT |
2541 XFS_DIFLAG_EXTSZINHERIT |
2542 XFS_DIFLAG_PROJINHERIT |
2543 XFS_DIFLAG_NOSYMLINKS)) {
2544 /* must be a directory */
2545 if (di_mode && !S_ISDIR(di_mode)) {
c98f31a5
CH
2546 if (!uncertain) {
2547 do_warn(
2548 _("directory flags set on non-directory inode %" PRIu64 "\n" ),
2549 lino);
2550 }
bd5683fe
DC
2551 flags &= ~(XFS_DIFLAG_RTINHERIT |
2552 XFS_DIFLAG_EXTSZINHERIT |
2553 XFS_DIFLAG_PROJINHERIT |
2554 XFS_DIFLAG_NOSYMLINKS);
2555 }
2556 }
83f4b5ac 2557 if (flags & (XFS_DIFLAG_REALTIME | FS_XFLAG_EXTSIZE)) {
bd5683fe
DC
2558 /* must be a file */
2559 if (di_mode && !S_ISREG(di_mode)) {
c98f31a5
CH
2560 if (!uncertain) {
2561 do_warn(
2562 _("file flags set on non-file inode %" PRIu64 "\n"),
2563 lino);
2564 }
bd5683fe 2565 flags &= ~(XFS_DIFLAG_REALTIME |
83f4b5ac 2566 FS_XFLAG_EXTSIZE);
bd5683fe
DC
2567 }
2568 }
56b2de80 2569 if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) {
bd5683fe 2570 if (!no_modify) {
5cd0710a 2571 do_warn(_("fixing bad flags.\n"));
56b2de80 2572 dino->di_flags = cpu_to_be16(flags);
bd5683fe
DC
2573 *dirty = 1;
2574 } else
5cd0710a 2575 do_warn(_("would fix bad flags.\n"));
bd5683fe
DC
2576 }
2577 }
2578
a406779b
DW
2579 /*
2580 * check that we only have valid flags2 set, and those that are set make
2581 * sense.
2582 */
2583 if (dino->di_version >= 3) {
2584 uint16_t flags = be16_to_cpu(dino->di_flags);
2585 uint64_t flags2 = be64_to_cpu(dino->di_flags2);
2586
2587 if (flags2 & ~XFS_DIFLAG2_ANY) {
2588 if (!uncertain) {
2589 do_warn(
2590 _("Bad flags2 set in inode %" PRIu64 "\n"),
2591 lino);
2592 }
2593 flags2 &= XFS_DIFLAG2_ANY;
2594 }
2595
c1604fa4
DW
2596 if (flags2 & XFS_DIFLAG2_DAX) {
2597 /* must be a file or dir */
2598 if (di_mode && !(S_ISREG(di_mode) || S_ISDIR(di_mode))) {
2599 if (!uncertain) {
2600 do_warn(
2601 _("DAX flag set on special inode %" PRIu64 "\n"),
2602 lino);
2603 }
2604 flags2 &= ~XFS_DIFLAG2_DAX;
2605 }
2606 }
2607
a406779b 2608 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2660e653 2609 !xfs_has_reflink(mp)) {
a406779b
DW
2610 if (!uncertain) {
2611 do_warn(
2612 _("inode %" PRIu64 " is marked reflinked but file system does not support reflink\n"),
2613 lino);
2614 }
2615 goto clear_bad_out;
2616 }
2617
2618 if (flags2 & XFS_DIFLAG2_REFLINK) {
2619 /* must be a file */
2620 if (di_mode && !S_ISREG(di_mode)) {
2621 if (!uncertain) {
2622 do_warn(
2623 _("reflink flag set on non-file inode %" PRIu64 "\n"),
2624 lino);
2625 }
2626 goto clear_bad_out;
2627 }
2628 }
2629
2630 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2631 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2632 if (!uncertain) {
2633 do_warn(
2634 _("Cannot have a reflinked realtime inode %" PRIu64 "\n"),
2635 lino);
2636 }
2637 goto clear_bad_out;
2638 }
2639
42627ba6 2640 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2660e653 2641 !xfs_has_reflink(mp)) {
42627ba6
DW
2642 if (!uncertain) {
2643 do_warn(
2644 _("inode %" PRIu64 " has CoW extent size hint but file system does not support reflink\n"),
2645 lino);
2646 }
2647 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2648 }
2649
2650 if (flags2 & XFS_DIFLAG2_COWEXTSIZE) {
2651 /* must be a directory or file */
2652 if (di_mode && !S_ISDIR(di_mode) && !S_ISREG(di_mode)) {
2653 if (!uncertain) {
2654 do_warn(
2655 _("CoW extent size flag set on non-file, non-directory inode %" PRIu64 "\n" ),
2656 lino);
2657 }
2658 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2659 }
2660 }
2661
2662 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2663 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2664 if (!uncertain) {
2665 do_warn(
2666 _("Cannot have CoW extent size hint on a realtime inode %" PRIu64 "\n"),
2667 lino);
2668 }
2669 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2670 }
2671
37c7dda1 2672 if (xfs_dinode_has_bigtime(dino) &&
2660e653 2673 !xfs_has_bigtime(mp)) {
37c7dda1
DW
2674 if (!uncertain) {
2675 do_warn(
2676 _("inode %" PRIu64 " is marked bigtime but file system does not support large timestamps\n"),
2677 lino);
2678 }
2679 flags2 &= ~XFS_DIFLAG2_BIGTIME;
2680
2681 if (no_modify) {
2682 do_warn(_("would zero timestamps.\n"));
2683 } else {
2684 do_warn(_("zeroing timestamps.\n"));
2685 dino->di_atime = 0;
2686 dino->di_mtime = 0;
2687 dino->di_ctime = 0;
2688 dino->di_crtime = 0;
2689 *dirty = 1;
2690 }
2691 }
2692
b83b2ec0
DW
2693 if (xfs_dinode_has_large_extent_counts(dino) &&
2694 !xfs_has_large_extent_counts(mp)) {
2695 if (!uncertain) {
2696 do_warn(
2697 _("inode %" PRIu64 " is marked large extent counts but file system does not support large extent counts\n"),
2698 lino);
2699 }
2700 flags2 &= ~XFS_DIFLAG2_NREXT64;
2701
2702 if (!no_modify)
2703 *dirty = 1;
2704 }
2705
0ec4cd64
DW
2706 if (xfs_dinode_has_large_extent_counts(dino)) {
2707 if (dino->di_nrext64_pad) {
2708 if (!no_modify) {
2709 do_warn(_("fixing bad nrext64_pad.\n"));
2710 dino->di_nrext64_pad = 0;
2711 *dirty = 1;
2712 } else
2713 do_warn(_("would fix bad nrext64_pad.\n"));
2714 }
2715 } else if (dino->di_version >= 3) {
2716 if (dino->di_v3_pad) {
2717 if (!no_modify) {
2718 do_warn(_("fixing bad v3_pad.\n"));
2719 dino->di_v3_pad = 0;
2720 *dirty = 1;
2721 } else
2722 do_warn(_("would fix bad v3_pad.\n"));
2723 }
2724 }
2725
a406779b
DW
2726 if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) {
2727 if (!no_modify) {
2728 do_warn(_("fixing bad flags2.\n"));
2729 dino->di_flags2 = cpu_to_be64(flags2);
2730 *dirty = 1;
2731 } else
2732 do_warn(_("would fix bad flags2.\n"));
2733 }
2734 }
2735
0459b626
BN
2736 if (verify_mode)
2737 return retval;
2738
2739 /*
2740 * clear the next unlinked field if necessary on a good
2741 * inode only during phase 4 -- when checking for inodes
2742 * referencing duplicate blocks. then it's safe because
2743 * we've done the inode discovery and have found all the inodes
2744 * we're going to find. check_dups is set to 1 only during
2745 * phase 4. Ugly.
2746 */
119383bf
DC
2747 if (check_dups && be32_to_cpu(dino->di_next_unlinked) != NULLAGINO) {
2748 if (no_modify) {
2749 do_warn(
2750 _("Would clear next_unlinked in inode %" PRIu64 "\n"), lino);
2751 } else {
2752 clear_dinode_unlinked(mp, dino);
2753 do_warn(
2754 _("Cleared next_unlinked in inode %" PRIu64 "\n"), lino);
2755 *dirty += 1;
2756 }
0724d0f4 2757 }
0459b626
BN
2758
2759 /* set type and map type info */
2760
2761 switch (di_mode & S_IFMT) {
2762 case S_IFDIR:
2763 type = XR_INO_DIR;
2764 *isa_dir = 1;
2765 break;
2766 case S_IFREG:
56b2de80 2767 if (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_REALTIME)
0459b626
BN
2768 type = XR_INO_RTDATA;
2769 else if (lino == mp->m_sb.sb_rbmino)
2770 type = XR_INO_RTBITMAP;
2771 else if (lino == mp->m_sb.sb_rsumino)
2772 type = XR_INO_RTSUM;
5857dce9
ES
2773 else if (lino == mp->m_sb.sb_uquotino)
2774 type = XR_INO_UQUOTA;
2775 else if (lino == mp->m_sb.sb_gquotino)
2776 type = XR_INO_GQUOTA;
2777 else if (lino == mp->m_sb.sb_pquotino)
2778 type = XR_INO_PQUOTA;
0459b626
BN
2779 else
2780 type = XR_INO_DATA;
2781 break;
2782 case S_IFLNK:
2783 type = XR_INO_SYMLINK;
2784 break;
2785 case S_IFCHR:
2786 type = XR_INO_CHRDEV;
2787 break;
2788 case S_IFBLK:
2789 type = XR_INO_BLKDEV;
2790 break;
2791 case S_IFSOCK:
2792 type = XR_INO_SOCK;
2793 break;
2794 case S_IFIFO:
2795 type = XR_INO_FIFO;
2796 break;
2797 default:
5d1b7f0f 2798 do_warn(_("bad inode type %#o inode %" PRIu64 "\n"),
0459b626
BN
2799 di_mode & S_IFMT, lino);
2800 goto clear_bad_out;
2801 }
2802
2803 /*
2804 * type checks for superblock inodes
2805 */
56b2de80 2806 if (process_check_sb_inodes(mp, dino, lino, &type, dirty) != 0)
0459b626
BN
2807 goto clear_bad_out;
2808
5f062427 2809 validate_extsize(mp, dino, lino, dirty);
0459b626 2810
42627ba6
DW
2811 /*
2812 * Only (regular files and directories) with COWEXTSIZE flags
2813 * set can have extsize set.
2814 */
2815 if (dino->di_version >= 3 &&
db3d080b
DW
2816 libxfs_inode_validate_cowextsize(mp,
2817 be32_to_cpu(dino->di_cowextsize),
2818 be16_to_cpu(dino->di_mode),
2819 be16_to_cpu(dino->di_flags),
2820 be64_to_cpu(dino->di_flags2)) != NULL) {
1c744e94 2821 do_warn(
db3d080b
DW
2822_("Bad CoW extent size %u on inode %" PRIu64 ", "),
2823 be32_to_cpu(dino->di_cowextsize), lino);
1c744e94 2824 if (!no_modify) {
db3d080b 2825 do_warn(_("resetting to zero\n"));
1c744e94 2826 dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_COWEXTSIZE);
db3d080b 2827 dino->di_cowextsize = 0;
1c744e94 2828 *dirty = 1;
db3d080b
DW
2829 } else
2830 do_warn(_("would reset to zero\n"));
1c744e94
DW
2831 }
2832
8fec4f7c 2833 /* nsec fields cannot be larger than 1 billion */
37c7dda1
DW
2834 check_nsec("atime", lino, dino, &dino->di_atime, dirty);
2835 check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);
2836 check_nsec("ctime", lino, dino, &dino->di_ctime, dirty);
8fec4f7c 2837 if (dino->di_version >= 3)
37c7dda1 2838 check_nsec("crtime", lino, dino, &dino->di_crtime, dirty);
8fec4f7c 2839
0459b626
BN
2840 /*
2841 * general size/consistency checks:
2842 */
2843 if (process_check_inode_sizes(mp, dino, lino, type) != 0)
2844 goto clear_bad_out;
2845
2846 /*
2847 * check for illegal values of forkoff
2848 */
56b2de80 2849 if (process_check_inode_forkoff(mp, dino, lino) != 0)
0459b626
BN
2850 goto clear_bad_out;
2851
7e174ec7
DW
2852 /*
2853 * record the state of the reflink flag
2854 */
2855 if (collect_rmaps)
2856 record_inode_reflink_flag(mp, dino, agno, ino, lino);
2857
0459b626
BN
2858 /*
2859 * check data fork -- if it's bad, clear the inode
2860 */
2861 if (process_inode_data_fork(mp, agno, ino, dino, type, dirty,
2862 &totblocks, &nextents, &dblkmap, check_dups) != 0)
2863 goto bad_out;
2864
2865 /*
2866 * check attribute fork if necessary. attributes are
2867 * always stored in the regular filesystem.
2868 */
2869 if (process_inode_attr_fork(mp, agno, ino, dino, type, dirty,
2870 &atotblocks, &anextents, check_dups, extra_attr_check,
2871 &retval))
2872 goto bad_out;
2873
2874 /*
2875 * enforce totblocks is 0 for misc types
2876 */
2877 if (process_misc_ino_types_blocks(totblocks, lino, type))
2878 goto clear_bad_out;
2879
2880 /*
2881 * correct space counters if required
2882 */
56b2de80 2883 if (process_inode_blocks_and_extents(dino, totblocks + atotblocks,
0459b626
BN
2884 nextents, anextents, lino, dirty) != 0)
2885 goto clear_bad_out;
2886
2887 /*
2888 * do any semantic type-based checking here
2889 */
2890 switch (type) {
2891 case XR_INO_DIR:
9a048535 2892 if (process_dir2(mp, lino, dino, ino_discovery,
0459b626 2893 dirty, "", parent, dblkmap)) {
5d1b7f0f
CH
2894 do_warn(
2895 _("problem with directory contents in inode %" PRIu64 "\n"),
2896 lino);
0459b626
BN
2897 goto clear_bad_out;
2898 }
2899 break;
2900 case XR_INO_SYMLINK:
2901 if (process_symlink(mp, lino, dino, dblkmap) != 0) {
5d1b7f0f
CH
2902 do_warn(
2903 _("problem with symbolic link in inode %" PRIu64 "\n"),
0459b626
BN
2904 lino);
2905 goto clear_bad_out;
2bd0ea18 2906 }
0459b626 2907 break;
5857dce9
ES
2908 case XR_INO_UQUOTA:
2909 case XR_INO_GQUOTA:
2910 case XR_INO_PQUOTA:
2911 if (process_quota_inode(mp, lino, dino, type, dblkmap) != 0) {
2912 do_warn(
2913 _("problem with quota inode %" PRIu64 "\n"), lino);
2914 goto clear_bad_out;
2915 }
2916 break;
0459b626
BN
2917 default:
2918 break;
2bd0ea18
NS
2919 }
2920
55d35a39 2921 blkmap_free(dblkmap);
0459b626
BN
2922
2923 /*
2924 * check nlinks feature, if it's a version 1 inode,
2925 * just leave nlinks alone. even if it's set wrong,
2926 * it'll be reset when read in.
2927 */
56b2de80 2928 *dirty += process_check_inode_nlink_version(dino, lino);
0459b626
BN
2929
2930 return retval;
2931
2932clear_bad_out:
2933 if (!no_modify) {
0724d0f4
ES
2934 clear_dinode(mp, dino, lino);
2935 *dirty += 1;
0459b626
BN
2936 }
2937bad_out:
2938 *used = is_free;
2939 *isa_dir = 0;
55d35a39 2940 blkmap_free(dblkmap);
0459b626 2941 return 1;
2bd0ea18
NS
2942}
2943
2944/*
2945 * returns 1 if inode is used, 0 if free.
2946 * performs any necessary salvaging actions.
2947 * note that we leave the generation count alone
2948 * because nothing we could set it to would be
2949 * guaranteed to be correct so the best guess for
2950 * the correct value is just to leave it alone.
2951 *
2952 * The trick is detecting empty files. For those,
2953 * the core and the forks should all be in the "empty"
2954 * or zero-length state -- a zero or possibly minimum length
2955 * (in the case of dirs) extent list -- although inline directories
2956 * and symlinks might be handled differently. So it should be
2957 * possible to sanity check them against each other.
2958 *
2959 * If the forks are an empty extent list though, then forget it.
2960 * The file is toast anyway since we can't recover its storage.
2961 *
2962 * Parameters:
2963 * Ins:
2964 * mp -- mount structure
2965 * dino -- pointer to on-disk inode structure
2966 * agno/ino -- inode numbers
2967 * free -- whether the map thinks the inode is free (1 == free)
2968 * ino_discovery -- whether we should examine directory
2969 * contents to discover new inodes
2970 * check_dups -- whether we should check to see if the
2971 * inode references duplicate blocks
2972 * if so, we compare the inode's claimed
2973 * blocks against the contents of the
2974 * duplicate extent list but we don't
2975 * set the bitmap. If not, we set the
2976 * bitmap and try and detect multiply
2977 * claimed blocks using the bitmap.
2978 * Outs:
2979 * dirty -- whether we changed the inode (1 == yes)
2bd0ea18
NS
2980 * used -- 1 if the inode is used, 0 if free. In no modify
2981 * mode, whether the inode should be used or free
2982 * isa_dir -- 1 if the inode is a directory, 0 if not. In
2983 * no modify mode, if the inode would be a dir or not.
2984 *
2985 * Return value -- 0 if the inode is good, 1 if it is/was corrupt
2986 */
2987
2988int
0459b626 2989process_dinode(
7328ea6e
CH
2990 xfs_mount_t *mp,
2991 struct xfs_dinode *dino,
2992 xfs_agnumber_t agno,
2993 xfs_agino_t ino,
2994 int was_free,
2995 int *dirty,
2996 int *used,
2997 int ino_discovery,
2998 int check_dups,
2999 int extra_attr_check,
3000 int *isa_dir,
3001 xfs_ino_t *parent)
2bd0ea18 3002{
7328ea6e
CH
3003 const int verify_mode = 0;
3004 const int uncertain = 0;
2bd0ea18
NS
3005
3006#ifdef XR_INODE_TRACE
9ee7055c 3007 fprintf(stderr, _("processing inode %d/%d\n"), agno, ino);
2bd0ea18 3008#endif
0459b626
BN
3009 return process_dinode_int(mp, dino, agno, ino, was_free, dirty, used,
3010 verify_mode, uncertain, ino_discovery,
3011 check_dups, extra_attr_check, isa_dir, parent);
2bd0ea18
NS
3012}
3013
3014/*
3015 * a more cursory check, check inode core, *DON'T* check forks
3016 * this basically just verifies whether the inode is an inode
3017 * and whether or not it has been totally trashed. returns 0
3018 * if the inode passes the cursory sanity check, 1 otherwise.
3019 */
3020int
0459b626 3021verify_dinode(
7328ea6e
CH
3022 xfs_mount_t *mp,
3023 struct xfs_dinode *dino,
3024 xfs_agnumber_t agno,
3025 xfs_agino_t ino)
2bd0ea18 3026{
7328ea6e
CH
3027 xfs_ino_t parent;
3028 int used = 0;
3029 int dirty = 0;
3030 int isa_dir = 0;
3031 const int verify_mode = 1;
3032 const int check_dups = 0;
3033 const int ino_discovery = 0;
3034 const int uncertain = 0;
0459b626
BN
3035
3036 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
3037 verify_mode, uncertain, ino_discovery,
3038 check_dups, 0, &isa_dir, &parent);
2bd0ea18
NS
3039}
3040
3041/*
3042 * like above only for inode on the uncertain list. it sets
3043 * the uncertain flag which makes process_dinode_int quieter.
3044 * returns 0 if the inode passes the cursory sanity check, 1 otherwise.
3045 */
3046int
0459b626 3047verify_uncertain_dinode(
7328ea6e
CH
3048 xfs_mount_t *mp,
3049 struct xfs_dinode *dino,
3050 xfs_agnumber_t agno,
3051 xfs_agino_t ino)
2bd0ea18 3052{
7328ea6e
CH
3053 xfs_ino_t parent;
3054 int used = 0;
3055 int dirty = 0;
3056 int isa_dir = 0;
3057 const int verify_mode = 1;
3058 const int check_dups = 0;
3059 const int ino_discovery = 0;
3060 const int uncertain = 1;
0459b626
BN
3061
3062 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
3063 verify_mode, uncertain, ino_discovery,
3064 check_dups, 0, &isa_dir, &parent);
2bd0ea18 3065}