]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/dinode.c
xfsprogs: Release v6.7.0
[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);
0459b626
BN
2081 ASSERT(*dirty > 0);
2082 } else {
2083 do_warn(_(", would clear attr fork\n"));
2bd0ea18
NS
2084 }
2085
0459b626
BN
2086 *atotblocks = 0;
2087 *anextents = 0;
2bd0ea18 2088 blkmap_free(ablkmap);
0459b626 2089 *retval = 1;
2bd0ea18 2090
28a4f9c0 2091 return 0;
2bd0ea18
NS
2092 }
2093
0459b626 2094 if (check_dups) {
56b2de80 2095 switch (dino->di_aformat) {
0459b626 2096 case XFS_DINODE_FMT_LOCAL:
f8149110 2097 err = process_lclinode(mp, agno, ino, dino,
5e656dbb 2098 XFS_ATTR_FORK);
0459b626
BN
2099 break;
2100 case XFS_DINODE_FMT_EXTENTS:
2101 err = process_exinode(mp, agno, ino, dino,
2102 type, dirty, atotblocks, anextents,
2103 &ablkmap, XFS_ATTR_FORK, 0);
2104 break;
2105 case XFS_DINODE_FMT_BTREE:
2106 err = process_btinode(mp, agno, ino, dino,
2107 type, dirty, atotblocks, anextents,
2108 &ablkmap, XFS_ATTR_FORK, 0);
2109 break;
2110 default:
5d1b7f0f 2111 do_error(_("illegal attribute fmt %d, ino %" PRIu64 "\n"),
56b2de80 2112 dino->di_aformat, lino);
2bd0ea18 2113 }
2bd0ea18 2114
0459b626
BN
2115 if (no_modify && err != 0) {
2116 blkmap_free(ablkmap);
2117 return 1;
2bd0ea18 2118 }
2bd0ea18 2119
0459b626 2120 ASSERT(err == 0);
2bd0ea18
NS
2121 }
2122
0459b626
BN
2123 /*
2124 * do attribute semantic-based consistency checks now
2125 */
2bd0ea18 2126
0459b626
BN
2127 /* get this only in phase 3, not in both phase 3 and 4 */
2128 if (extra_attr_check &&
2129 process_attributes(mp, lino, dino, ablkmap, &repair)) {
5d1b7f0f
CH
2130 do_warn(
2131 _("problem with attribute contents in inode %" PRIu64 "\n"),
0459b626
BN
2132 lino);
2133 if (!repair) {
2134 /* clear attributes if not done already */
2135 if (!no_modify) {
2136 *dirty += clear_dinode_attr(mp, dino, lino);
0459b626
BN
2137 } else {
2138 do_warn(_("would clear attr fork\n"));
2139 }
2140 *atotblocks = 0;
2141 *anextents = 0;
2bd0ea18 2142 }
0459b626
BN
2143 else {
2144 *dirty = 1; /* it's been repaired */
2bd0ea18
NS
2145 }
2146 }
0459b626
BN
2147 blkmap_free(ablkmap);
2148 return 0;
2149}
2bd0ea18 2150
0459b626
BN
2151/*
2152 * check nlinks feature, if it's a version 1 inode,
2153 * just leave nlinks alone. even if it's set wrong,
2154 * it'll be reset when read in.
2155 */
2bd0ea18 2156
0459b626
BN
2157static int
2158process_check_inode_nlink_version(
7328ea6e
CH
2159 struct xfs_dinode *dino,
2160 xfs_ino_t lino)
0459b626 2161{
7328ea6e 2162 int dirty = 0;
2bd0ea18 2163
2bd0ea18 2164 /*
5f6f3660 2165 * if it's a version 2 inode, it should have a zero
2bd0ea18
NS
2166 * onlink field, so clear it.
2167 */
5f6f3660 2168 if (dino->di_version > 1 && dino->di_onlink != 0) {
0459b626 2169 if (!no_modify) {
5d1b7f0f
CH
2170 do_warn(
2171_("clearing obsolete nlink field in version 2 inode %" PRIu64 ", was %d, now 0\n"),
56b2de80
DC
2172 lino, be16_to_cpu(dino->di_onlink));
2173 dino->di_onlink = 0;
0459b626 2174 dirty = 1;
2bd0ea18 2175 } else {
5d1b7f0f
CH
2176 do_warn(
2177_("would clear obsolete nlink field in version 2 inode %" PRIu64 ", currently %d\n"),
56b2de80 2178 lino, be16_to_cpu(dino->di_onlink));
0459b626
BN
2179 }
2180 }
2181 return dirty;
2182}
2183
8fec4f7c
DW
2184/* Check nanoseconds of a timestamp don't exceed 1 second. */
2185static void
2186check_nsec(
2187 const char *name,
2188 xfs_ino_t lino,
37c7dda1 2189 struct xfs_dinode *dip,
a252aadf 2190 xfs_timestamp_t *ts,
8fec4f7c
DW
2191 int *dirty)
2192{
a252aadf
DW
2193 struct xfs_legacy_timestamp *t;
2194
37c7dda1
DW
2195 if (xfs_dinode_has_bigtime(dip))
2196 return;
2197
a252aadf 2198 t = (struct xfs_legacy_timestamp *)ts;
c0e58015 2199 if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
8fec4f7c
DW
2200 return;
2201
2202 do_warn(
2203_("Bad %s nsec %u on inode %" PRIu64 ", "), name, be32_to_cpu(t->t_nsec), lino);
2204 if (no_modify) {
2205 do_warn(_("would reset to zero\n"));
2206 } else {
2207 do_warn(_("resetting to zero\n"));
2208 t->t_nsec = 0;
2209 *dirty = 1;
2210 }
2211}
2212
5f062427
DW
2213static void
2214validate_extsize(
2215 struct xfs_mount *mp,
2216 struct xfs_dinode *dino,
2217 xfs_ino_t lino,
2218 int *dirty)
2219{
2220 uint16_t flags = be16_to_cpu(dino->di_flags);
2221 unsigned int value = be32_to_cpu(dino->di_extsize);
2222 bool misaligned = false;
2223 bool bad;
2224
2225 /*
2226 * XFS allows a sysadmin to change the rt extent size when adding a rt
2227 * section to a filesystem after formatting. If there are any
2228 * directories with extszinherit and rtinherit set, the hint could
2229 * become misaligned with the new rextsize. The verifier doesn't check
2230 * this, because we allow rtinherit directories even without an rt
2231 * device.
2232 */
2233 if ((flags & XFS_DIFLAG_EXTSZINHERIT) &&
2234 (flags & XFS_DIFLAG_RTINHERIT) &&
2235 value % mp->m_sb.sb_rextsize > 0)
2236 misaligned = true;
2237
2238 /*
2239 * Complain if the verifier fails.
2240 *
2241 * Old kernels didn't check the alignment of extsize hints when copying
2242 * them to new regular realtime files. The inode verifier now checks
2243 * the alignment (because misaligned hints cause misbehavior in the rt
2244 * allocator), so we have to complain and fix them.
2245 */
2246 bad = libxfs_inode_validate_extsize(mp, value,
2247 be16_to_cpu(dino->di_mode), flags) != NULL;
2248 if (bad || misaligned) {
2249 do_warn(
2250_("Bad extent size hint %u on inode %" PRIu64 ", "),
2251 value, lino);
2252 if (!no_modify) {
2253 do_warn(_("resetting to zero\n"));
2254 dino->di_extsize = 0;
2255 dino->di_flags &= ~cpu_to_be16(XFS_DIFLAG_EXTSIZE |
2256 XFS_DIFLAG_EXTSZINHERIT);
2257 *dirty = 1;
2258 } else
2259 do_warn(_("would reset to zero\n"));
2260 }
2261}
2262
0459b626
BN
2263/*
2264 * returns 0 if the inode is ok, 1 if the inode is corrupt
2265 * check_dups can be set to 1 *only* when called by the
2266 * first pass of the duplicate block checking of phase 4.
2267 * *dirty is set > 0 if the dinode has been altered and
2268 * needs to be written out.
2269 *
2270 * for detailed, info, look at process_dinode() comments.
2271 */
8b8a6b02 2272static int
0459b626 2273process_dinode_int(xfs_mount_t *mp,
7328ea6e 2274 struct xfs_dinode *dino,
0459b626
BN
2275 xfs_agnumber_t agno,
2276 xfs_agino_t ino,
2277 int was_free, /* 1 if inode is currently free */
2278 int *dirty, /* out == > 0 if inode is now dirty */
2279 int *used, /* out == 1 if inode is in use */
2280 int verify_mode, /* 1 == verify but don't modify inode */
2281 int uncertain, /* 1 == inode is uncertain */
2282 int ino_discovery, /* 1 == check dirs for unknown inodes */
2283 int check_dups, /* 1 == check if inode claims
2284 * duplicate blocks */
2285 int extra_attr_check, /* 1 == do attribute format and value checks */
2286 int *isa_dir, /* out == 1 if inode is a directory */
2287 xfs_ino_t *parent) /* out -- parent if ino is a dir */
2288{
5a35bf2c
DC
2289 xfs_rfsblock_t totblocks = 0;
2290 xfs_rfsblock_t atotblocks = 0;
0459b626
BN
2291 int di_mode;
2292 int type;
2293 int retval = 0;
3a2414fa
CB
2294 xfs_extnum_t nextents;
2295 xfs_extnum_t anextents;
0459b626
BN
2296 xfs_ino_t lino;
2297 const int is_free = 0;
2298 const int is_used = 1;
2299 blkmap_t *dblkmap = NULL;
6bd73d16 2300 xfs_agino_t unlinked_ino;
8aa34dc9 2301 struct xfs_perag *pag;
0459b626
BN
2302
2303 *dirty = *isa_dir = 0;
2304 *used = is_used;
2305 type = XR_INO_UNKNOWN;
2306
0459b626 2307 lino = XFS_AGINO_TO_INO(mp, agno, ino);
56b2de80 2308 di_mode = be16_to_cpu(dino->di_mode);
0459b626
BN
2309
2310 /*
2311 * if in verify mode, don't modify the inode.
2312 *
2313 * if correcting, reset stuff that has known values
2314 *
2315 * if in uncertain mode, be silent on errors since we're
2316 * trying to find out if these are inodes as opposed
2317 * to assuming that they are. Just return the appropriate
2318 * return code in that case.
2319 *
2320 * If uncertain is set, verify_mode MUST be set.
2321 */
2322 ASSERT(uncertain == 0 || verify_mode != 0);
2323
7d7c5553
ES
2324 /*
2325 * This is the only valid point to check the CRC; after this we may have
2326 * made changes which invalidate it, and the CRC is only updated again
2327 * when it gets written out.
2328 *
2329 * Of course if we make any modifications after this, the inode gets
2330 * rewritten, and the CRC is updated automagically.
2331 */
2660e653 2332 if (xfs_has_crc(mp) &&
e2f60652 2333 !libxfs_verify_cksum((char *)dino, mp->m_sb.sb_inodesize,
7d7c5553
ES
2334 XFS_DINODE_CRC_OFF)) {
2335 retval = 1;
2336 if (!uncertain)
2337 do_warn(_("bad CRC for inode %" PRIu64 "%c"),
2338 lino, verify_mode ? '\n' : ',');
2339 if (!verify_mode) {
2340 if (!no_modify) {
2341 do_warn(_(" will rewrite\n"));
2342 *dirty = 1;
2343 } else
2344 do_warn(_(" would rewrite\n"));
2345 }
2346 }
2347
56b2de80 2348 if (be16_to_cpu(dino->di_magic) != XFS_DINODE_MAGIC) {
0459b626
BN
2349 retval = 1;
2350 if (!uncertain)
5d1b7f0f 2351 do_warn(_("bad magic number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2352 be16_to_cpu(dino->di_magic), lino,
0459b626
BN
2353 verify_mode ? '\n' : ',');
2354 if (!verify_mode) {
2355 if (!no_modify) {
2356 do_warn(_(" resetting magic number\n"));
56b2de80 2357 dino->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
0459b626
BN
2358 *dirty = 1;
2359 } else
2360 do_warn(_(" would reset magic number\n"));
2361 }
2362 }
2363
03d8044d 2364 if (!libxfs_dinode_good_version(mp, dino->di_version)) {
0459b626
BN
2365 retval = 1;
2366 if (!uncertain)
5d1b7f0f 2367 do_warn(_("bad version number 0x%x on inode %" PRIu64 "%c"),
56b2de80 2368 (__s8)dino->di_version, lino,
0459b626
BN
2369 verify_mode ? '\n' : ',');
2370 if (!verify_mode) {
2371 if (!no_modify) {
2372 do_warn(_(" resetting version number\n"));
e0607266 2373 dino->di_version =
2660e653 2374 xfs_has_crc(mp) ? 3 : 2;
0459b626
BN
2375 *dirty = 1;
2376 } else
2377 do_warn(_(" would reset version number\n"));
2378 }
2379 }
2380
6bd73d16 2381 unlinked_ino = be32_to_cpu(dino->di_next_unlinked);
8aa34dc9
DC
2382 pag = libxfs_perag_get(mp, agno);
2383 if (!xfs_verify_agino_or_null(pag, unlinked_ino)) {
6bd73d16
ES
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 }
8aa34dc9 2398 libxfs_perag_put(pag);
6bd73d16 2399
e0607266
DC
2400 /*
2401 * We don't bother checking the CRC here - we cannot guarantee that when
2402 * we are called here that the inode has not already been modified in
2403 * memory and hence invalidated the CRC.
2404 */
2660e653 2405 if (xfs_has_crc(mp)) {
e0607266
DC
2406 if (be64_to_cpu(dino->di_ino) != lino) {
2407 if (!uncertain)
2408 do_warn(
2409_("inode identifier %llu mismatch on inode %" PRIu64 "\n"),
51073f86
DW
2410 (unsigned long long)be64_to_cpu(dino->di_ino),
2411 lino);
e0607266
DC
2412 if (verify_mode)
2413 return 1;
2414 goto clear_bad_out;
2415 }
9c4e12fb
ES
2416 if (platform_uuid_compare(&dino->di_uuid,
2417 &mp->m_sb.sb_meta_uuid)) {
e0607266
DC
2418 if (!uncertain)
2419 do_warn(
2420 _("UUID mismatch on inode %" PRIu64 "\n"), lino);
2421 if (verify_mode)
2422 return 1;
2423 goto clear_bad_out;
2424 }
2425 }
2426
0459b626
BN
2427 /*
2428 * blow out of here if the inode size is < 0
2429 */
56b2de80 2430 if ((xfs_fsize_t)be64_to_cpu(dino->di_size) < 0) {
0459b626 2431 if (!uncertain)
5d1b7f0f
CH
2432 do_warn(
2433_("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
14f8b681 2434 (int64_t)be64_to_cpu(dino->di_size),
5d1b7f0f 2435 lino);
0459b626
BN
2436 if (verify_mode)
2437 return 1;
2438 goto clear_bad_out;
2439 }
2440
2441 /*
0724d0f4 2442 * if not in verify mode, check to see if the inode and imap
0459b626
BN
2443 * agree that the inode is free
2444 */
2445 if (!verify_mode && di_mode == 0) {
2446 /*
2447 * was_free value is not meaningful if we're in verify mode
2448 */
2449 if (was_free) {
2450 /*
2e1bf6c5 2451 * easy case, inode free -- inode and map agree, check
0459b626
BN
2452 * it just in case to ensure that format, etc. are
2453 * set correctly
2454 */
2e1bf6c5
ES
2455 if (libxfs_dinode_verify(mp, lino, dino) != NULL) {
2456 do_warn(
2457 _("free inode %" PRIu64 " contains errors, "), lino);
2458 if (!no_modify) {
0724d0f4 2459 clear_dinode(mp, dino, lino);
2e1bf6c5 2460 do_warn(_("corrected\n"));
0724d0f4 2461 *dirty += 1;
2e1bf6c5
ES
2462 } else {
2463 do_warn(_("would correct\n"));
2464 }
2465 }
0459b626
BN
2466 *used = is_free;
2467 return 0;
2468 }
2469 /*
2470 * the inode looks free but the map says it's in use.
2471 * clear the inode just to be safe and mark the inode
2472 * free.
2473 */
5d1b7f0f
CH
2474 do_warn(
2475 _("imap claims a free inode %" PRIu64 " is in use, "), lino);
0459b626
BN
2476 if (!no_modify) {
2477 do_warn(_("correcting imap and clearing inode\n"));
0724d0f4
ES
2478 clear_dinode(mp, dino, lino);
2479 *dirty += 1;
0459b626
BN
2480 retval = 1;
2481 } else
2482 do_warn(_("would correct imap and clear inode\n"));
2483 *used = is_free;
2484 return retval;
2485 }
2486
2487 /*
2488 * because of the lack of any write ordering guarantee, it's
2489 * possible that the core got updated but the forks didn't.
2490 * so rather than be ambitious (and probably incorrect),
2491 * if there's an inconsistency, we get conservative and
2492 * just pitch the file. blow off checking formats of
2493 * free inodes since technically any format is legal
2494 * as we reset the inode when we re-use it.
2495 */
56b2de80 2496 if (di_mode != 0 && check_dinode_mode_format(dino) != 0) {
0459b626 2497 if (!uncertain)
5d1b7f0f
CH
2498 do_warn(
2499 _("bad inode format in inode %" PRIu64 "\n"), lino);
0459b626
BN
2500 if (verify_mode)
2501 return 1;
2502 goto clear_bad_out;
2503 }
2504
bd5683fe
DC
2505 /*
2506 * check that we only have valid flags set, and those that are set make
2507 * sense.
2508 */
56b2de80
DC
2509 if (dino->di_flags) {
2510 uint16_t flags = be16_to_cpu(dino->di_flags);
bd5683fe
DC
2511
2512 if (flags & ~XFS_DIFLAG_ANY) {
c98f31a5
CH
2513 if (!uncertain) {
2514 do_warn(
2515 _("Bad flags set in inode %" PRIu64 "\n"),
2516 lino);
2517 }
5cd0710a 2518 flags &= XFS_DIFLAG_ANY;
bd5683fe
DC
2519 }
2520
e8e72c93
DW
2521 /* need an rt-dev for the realtime flag! */
2522 if ((flags & XFS_DIFLAG_REALTIME) && !rt_name) {
2523 if (!uncertain) {
2524 do_warn(
c98f31a5 2525 _("inode %" PRIu64 " has RT flag set but there is no RT device\n"),
e8e72c93 2526 lino);
bd5683fe 2527 }
e8e72c93 2528 flags &= ~XFS_DIFLAG_REALTIME;
bd5683fe 2529 }
fb380cb7 2530 if (flags & XFS_DIFLAG_NEWRTBM) {
bd5683fe
DC
2531 /* must be a rt bitmap inode */
2532 if (lino != mp->m_sb.sb_rbmino) {
c98f31a5
CH
2533 if (!uncertain) {
2534 do_warn(
2535 _("inode %" PRIu64 " not rt bitmap\n"),
2536 lino);
2537 }
fb380cb7 2538 flags &= ~XFS_DIFLAG_NEWRTBM;
bd5683fe
DC
2539 }
2540 }
2541 if (flags & (XFS_DIFLAG_RTINHERIT |
2542 XFS_DIFLAG_EXTSZINHERIT |
2543 XFS_DIFLAG_PROJINHERIT |
2544 XFS_DIFLAG_NOSYMLINKS)) {
2545 /* must be a directory */
2546 if (di_mode && !S_ISDIR(di_mode)) {
c98f31a5
CH
2547 if (!uncertain) {
2548 do_warn(
2549 _("directory flags set on non-directory inode %" PRIu64 "\n" ),
2550 lino);
2551 }
bd5683fe
DC
2552 flags &= ~(XFS_DIFLAG_RTINHERIT |
2553 XFS_DIFLAG_EXTSZINHERIT |
2554 XFS_DIFLAG_PROJINHERIT |
2555 XFS_DIFLAG_NOSYMLINKS);
2556 }
2557 }
83f4b5ac 2558 if (flags & (XFS_DIFLAG_REALTIME | FS_XFLAG_EXTSIZE)) {
bd5683fe
DC
2559 /* must be a file */
2560 if (di_mode && !S_ISREG(di_mode)) {
c98f31a5
CH
2561 if (!uncertain) {
2562 do_warn(
2563 _("file flags set on non-file inode %" PRIu64 "\n"),
2564 lino);
2565 }
bd5683fe 2566 flags &= ~(XFS_DIFLAG_REALTIME |
83f4b5ac 2567 FS_XFLAG_EXTSIZE);
bd5683fe
DC
2568 }
2569 }
56b2de80 2570 if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) {
bd5683fe 2571 if (!no_modify) {
5cd0710a 2572 do_warn(_("fixing bad flags.\n"));
56b2de80 2573 dino->di_flags = cpu_to_be16(flags);
bd5683fe
DC
2574 *dirty = 1;
2575 } else
5cd0710a 2576 do_warn(_("would fix bad flags.\n"));
bd5683fe
DC
2577 }
2578 }
2579
a406779b
DW
2580 /*
2581 * check that we only have valid flags2 set, and those that are set make
2582 * sense.
2583 */
2584 if (dino->di_version >= 3) {
2585 uint16_t flags = be16_to_cpu(dino->di_flags);
2586 uint64_t flags2 = be64_to_cpu(dino->di_flags2);
2587
2588 if (flags2 & ~XFS_DIFLAG2_ANY) {
2589 if (!uncertain) {
2590 do_warn(
2591 _("Bad flags2 set in inode %" PRIu64 "\n"),
2592 lino);
2593 }
2594 flags2 &= XFS_DIFLAG2_ANY;
2595 }
2596
c1604fa4
DW
2597 if (flags2 & XFS_DIFLAG2_DAX) {
2598 /* must be a file or dir */
2599 if (di_mode && !(S_ISREG(di_mode) || S_ISDIR(di_mode))) {
2600 if (!uncertain) {
2601 do_warn(
2602 _("DAX flag set on special inode %" PRIu64 "\n"),
2603 lino);
2604 }
2605 flags2 &= ~XFS_DIFLAG2_DAX;
2606 }
2607 }
2608
a406779b 2609 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2660e653 2610 !xfs_has_reflink(mp)) {
a406779b
DW
2611 if (!uncertain) {
2612 do_warn(
2613 _("inode %" PRIu64 " is marked reflinked but file system does not support reflink\n"),
2614 lino);
2615 }
2616 goto clear_bad_out;
2617 }
2618
2619 if (flags2 & XFS_DIFLAG2_REFLINK) {
2620 /* must be a file */
2621 if (di_mode && !S_ISREG(di_mode)) {
2622 if (!uncertain) {
2623 do_warn(
2624 _("reflink flag set on non-file inode %" PRIu64 "\n"),
2625 lino);
2626 }
2627 goto clear_bad_out;
2628 }
2629 }
2630
2631 if ((flags2 & XFS_DIFLAG2_REFLINK) &&
2632 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2633 if (!uncertain) {
2634 do_warn(
2635 _("Cannot have a reflinked realtime inode %" PRIu64 "\n"),
2636 lino);
2637 }
2638 goto clear_bad_out;
2639 }
2640
42627ba6 2641 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2660e653 2642 !xfs_has_reflink(mp)) {
42627ba6
DW
2643 if (!uncertain) {
2644 do_warn(
2645 _("inode %" PRIu64 " has CoW extent size hint but file system does not support reflink\n"),
2646 lino);
2647 }
2648 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2649 }
2650
2651 if (flags2 & XFS_DIFLAG2_COWEXTSIZE) {
2652 /* must be a directory or file */
2653 if (di_mode && !S_ISDIR(di_mode) && !S_ISREG(di_mode)) {
2654 if (!uncertain) {
2655 do_warn(
2656 _("CoW extent size flag set on non-file, non-directory inode %" PRIu64 "\n" ),
2657 lino);
2658 }
2659 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2660 }
2661 }
2662
2663 if ((flags2 & XFS_DIFLAG2_COWEXTSIZE) &&
2664 (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) {
2665 if (!uncertain) {
2666 do_warn(
2667 _("Cannot have CoW extent size hint on a realtime inode %" PRIu64 "\n"),
2668 lino);
2669 }
2670 flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
2671 }
2672
37c7dda1 2673 if (xfs_dinode_has_bigtime(dino) &&
2660e653 2674 !xfs_has_bigtime(mp)) {
37c7dda1
DW
2675 if (!uncertain) {
2676 do_warn(
2677 _("inode %" PRIu64 " is marked bigtime but file system does not support large timestamps\n"),
2678 lino);
2679 }
2680 flags2 &= ~XFS_DIFLAG2_BIGTIME;
2681
2682 if (no_modify) {
2683 do_warn(_("would zero timestamps.\n"));
2684 } else {
2685 do_warn(_("zeroing timestamps.\n"));
2686 dino->di_atime = 0;
2687 dino->di_mtime = 0;
2688 dino->di_ctime = 0;
2689 dino->di_crtime = 0;
2690 *dirty = 1;
2691 }
2692 }
2693
b83b2ec0
DW
2694 if (xfs_dinode_has_large_extent_counts(dino) &&
2695 !xfs_has_large_extent_counts(mp)) {
2696 if (!uncertain) {
2697 do_warn(
2698 _("inode %" PRIu64 " is marked large extent counts but file system does not support large extent counts\n"),
2699 lino);
2700 }
2701 flags2 &= ~XFS_DIFLAG2_NREXT64;
2702
2703 if (!no_modify)
2704 *dirty = 1;
2705 }
2706
0ec4cd64
DW
2707 if (xfs_dinode_has_large_extent_counts(dino)) {
2708 if (dino->di_nrext64_pad) {
2709 if (!no_modify) {
2710 do_warn(_("fixing bad nrext64_pad.\n"));
2711 dino->di_nrext64_pad = 0;
2712 *dirty = 1;
2713 } else
2714 do_warn(_("would fix bad nrext64_pad.\n"));
2715 }
2716 } else if (dino->di_version >= 3) {
2717 if (dino->di_v3_pad) {
2718 if (!no_modify) {
2719 do_warn(_("fixing bad v3_pad.\n"));
2720 dino->di_v3_pad = 0;
2721 *dirty = 1;
2722 } else
2723 do_warn(_("would fix bad v3_pad.\n"));
2724 }
2725 }
2726
a406779b
DW
2727 if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) {
2728 if (!no_modify) {
2729 do_warn(_("fixing bad flags2.\n"));
2730 dino->di_flags2 = cpu_to_be64(flags2);
2731 *dirty = 1;
2732 } else
2733 do_warn(_("would fix bad flags2.\n"));
2734 }
2735 }
2736
0459b626
BN
2737 if (verify_mode)
2738 return retval;
2739
2740 /*
2741 * clear the next unlinked field if necessary on a good
2742 * inode only during phase 4 -- when checking for inodes
2743 * referencing duplicate blocks. then it's safe because
2744 * we've done the inode discovery and have found all the inodes
2745 * we're going to find. check_dups is set to 1 only during
2746 * phase 4. Ugly.
2747 */
119383bf
DC
2748 if (check_dups && be32_to_cpu(dino->di_next_unlinked) != NULLAGINO) {
2749 if (no_modify) {
2750 do_warn(
2751 _("Would clear next_unlinked in inode %" PRIu64 "\n"), lino);
2752 } else {
2753 clear_dinode_unlinked(mp, dino);
2754 do_warn(
2755 _("Cleared next_unlinked in inode %" PRIu64 "\n"), lino);
2756 *dirty += 1;
2757 }
0724d0f4 2758 }
0459b626
BN
2759
2760 /* set type and map type info */
2761
2762 switch (di_mode & S_IFMT) {
2763 case S_IFDIR:
2764 type = XR_INO_DIR;
2765 *isa_dir = 1;
2766 break;
2767 case S_IFREG:
56b2de80 2768 if (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_REALTIME)
0459b626
BN
2769 type = XR_INO_RTDATA;
2770 else if (lino == mp->m_sb.sb_rbmino)
2771 type = XR_INO_RTBITMAP;
2772 else if (lino == mp->m_sb.sb_rsumino)
2773 type = XR_INO_RTSUM;
5857dce9
ES
2774 else if (lino == mp->m_sb.sb_uquotino)
2775 type = XR_INO_UQUOTA;
2776 else if (lino == mp->m_sb.sb_gquotino)
2777 type = XR_INO_GQUOTA;
2778 else if (lino == mp->m_sb.sb_pquotino)
2779 type = XR_INO_PQUOTA;
0459b626
BN
2780 else
2781 type = XR_INO_DATA;
2782 break;
2783 case S_IFLNK:
2784 type = XR_INO_SYMLINK;
2785 break;
2786 case S_IFCHR:
2787 type = XR_INO_CHRDEV;
2788 break;
2789 case S_IFBLK:
2790 type = XR_INO_BLKDEV;
2791 break;
2792 case S_IFSOCK:
2793 type = XR_INO_SOCK;
2794 break;
2795 case S_IFIFO:
2796 type = XR_INO_FIFO;
2797 break;
2798 default:
5d1b7f0f 2799 do_warn(_("bad inode type %#o inode %" PRIu64 "\n"),
0459b626
BN
2800 di_mode & S_IFMT, lino);
2801 goto clear_bad_out;
2802 }
2803
2804 /*
2805 * type checks for superblock inodes
2806 */
56b2de80 2807 if (process_check_sb_inodes(mp, dino, lino, &type, dirty) != 0)
0459b626
BN
2808 goto clear_bad_out;
2809
5f062427 2810 validate_extsize(mp, dino, lino, dirty);
0459b626 2811
42627ba6
DW
2812 /*
2813 * Only (regular files and directories) with COWEXTSIZE flags
2814 * set can have extsize set.
2815 */
2816 if (dino->di_version >= 3 &&
db3d080b
DW
2817 libxfs_inode_validate_cowextsize(mp,
2818 be32_to_cpu(dino->di_cowextsize),
2819 be16_to_cpu(dino->di_mode),
2820 be16_to_cpu(dino->di_flags),
2821 be64_to_cpu(dino->di_flags2)) != NULL) {
1c744e94 2822 do_warn(
db3d080b
DW
2823_("Bad CoW extent size %u on inode %" PRIu64 ", "),
2824 be32_to_cpu(dino->di_cowextsize), lino);
1c744e94 2825 if (!no_modify) {
db3d080b 2826 do_warn(_("resetting to zero\n"));
1c744e94 2827 dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_COWEXTSIZE);
db3d080b 2828 dino->di_cowextsize = 0;
1c744e94 2829 *dirty = 1;
db3d080b
DW
2830 } else
2831 do_warn(_("would reset to zero\n"));
1c744e94
DW
2832 }
2833
8fec4f7c 2834 /* nsec fields cannot be larger than 1 billion */
37c7dda1
DW
2835 check_nsec("atime", lino, dino, &dino->di_atime, dirty);
2836 check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);
2837 check_nsec("ctime", lino, dino, &dino->di_ctime, dirty);
8fec4f7c 2838 if (dino->di_version >= 3)
37c7dda1 2839 check_nsec("crtime", lino, dino, &dino->di_crtime, dirty);
8fec4f7c 2840
0459b626
BN
2841 /*
2842 * general size/consistency checks:
2843 */
2844 if (process_check_inode_sizes(mp, dino, lino, type) != 0)
2845 goto clear_bad_out;
2846
2847 /*
2848 * check for illegal values of forkoff
2849 */
56b2de80 2850 if (process_check_inode_forkoff(mp, dino, lino) != 0)
0459b626
BN
2851 goto clear_bad_out;
2852
7e174ec7
DW
2853 /*
2854 * record the state of the reflink flag
2855 */
2856 if (collect_rmaps)
2857 record_inode_reflink_flag(mp, dino, agno, ino, lino);
2858
0459b626
BN
2859 /*
2860 * check data fork -- if it's bad, clear the inode
2861 */
2862 if (process_inode_data_fork(mp, agno, ino, dino, type, dirty,
2863 &totblocks, &nextents, &dblkmap, check_dups) != 0)
2864 goto bad_out;
2865
2866 /*
2867 * check attribute fork if necessary. attributes are
2868 * always stored in the regular filesystem.
2869 */
2870 if (process_inode_attr_fork(mp, agno, ino, dino, type, dirty,
2871 &atotblocks, &anextents, check_dups, extra_attr_check,
2872 &retval))
2873 goto bad_out;
2874
2875 /*
2876 * enforce totblocks is 0 for misc types
2877 */
2878 if (process_misc_ino_types_blocks(totblocks, lino, type))
2879 goto clear_bad_out;
2880
2881 /*
2882 * correct space counters if required
2883 */
56b2de80 2884 if (process_inode_blocks_and_extents(dino, totblocks + atotblocks,
0459b626
BN
2885 nextents, anextents, lino, dirty) != 0)
2886 goto clear_bad_out;
2887
2888 /*
2889 * do any semantic type-based checking here
2890 */
2891 switch (type) {
2892 case XR_INO_DIR:
9a048535 2893 if (process_dir2(mp, lino, dino, ino_discovery,
0459b626 2894 dirty, "", parent, dblkmap)) {
5d1b7f0f
CH
2895 do_warn(
2896 _("problem with directory contents in inode %" PRIu64 "\n"),
2897 lino);
0459b626
BN
2898 goto clear_bad_out;
2899 }
2900 break;
2901 case XR_INO_SYMLINK:
2902 if (process_symlink(mp, lino, dino, dblkmap) != 0) {
5d1b7f0f
CH
2903 do_warn(
2904 _("problem with symbolic link in inode %" PRIu64 "\n"),
0459b626
BN
2905 lino);
2906 goto clear_bad_out;
2bd0ea18 2907 }
0459b626 2908 break;
5857dce9
ES
2909 case XR_INO_UQUOTA:
2910 case XR_INO_GQUOTA:
2911 case XR_INO_PQUOTA:
2912 if (process_quota_inode(mp, lino, dino, type, dblkmap) != 0) {
2913 do_warn(
2914 _("problem with quota inode %" PRIu64 "\n"), lino);
2915 goto clear_bad_out;
2916 }
2917 break;
0459b626
BN
2918 default:
2919 break;
2bd0ea18
NS
2920 }
2921
55d35a39 2922 blkmap_free(dblkmap);
0459b626
BN
2923
2924 /*
2925 * check nlinks feature, if it's a version 1 inode,
2926 * just leave nlinks alone. even if it's set wrong,
2927 * it'll be reset when read in.
2928 */
56b2de80 2929 *dirty += process_check_inode_nlink_version(dino, lino);
0459b626
BN
2930
2931 return retval;
2932
2933clear_bad_out:
2934 if (!no_modify) {
0724d0f4
ES
2935 clear_dinode(mp, dino, lino);
2936 *dirty += 1;
0459b626
BN
2937 }
2938bad_out:
2939 *used = is_free;
2940 *isa_dir = 0;
55d35a39 2941 blkmap_free(dblkmap);
0459b626 2942 return 1;
2bd0ea18
NS
2943}
2944
2945/*
2946 * returns 1 if inode is used, 0 if free.
2947 * performs any necessary salvaging actions.
2948 * note that we leave the generation count alone
2949 * because nothing we could set it to would be
2950 * guaranteed to be correct so the best guess for
2951 * the correct value is just to leave it alone.
2952 *
2953 * The trick is detecting empty files. For those,
2954 * the core and the forks should all be in the "empty"
2955 * or zero-length state -- a zero or possibly minimum length
2956 * (in the case of dirs) extent list -- although inline directories
2957 * and symlinks might be handled differently. So it should be
2958 * possible to sanity check them against each other.
2959 *
2960 * If the forks are an empty extent list though, then forget it.
2961 * The file is toast anyway since we can't recover its storage.
2962 *
2963 * Parameters:
2964 * Ins:
2965 * mp -- mount structure
2966 * dino -- pointer to on-disk inode structure
2967 * agno/ino -- inode numbers
2968 * free -- whether the map thinks the inode is free (1 == free)
2969 * ino_discovery -- whether we should examine directory
2970 * contents to discover new inodes
2971 * check_dups -- whether we should check to see if the
2972 * inode references duplicate blocks
2973 * if so, we compare the inode's claimed
2974 * blocks against the contents of the
2975 * duplicate extent list but we don't
2976 * set the bitmap. If not, we set the
2977 * bitmap and try and detect multiply
2978 * claimed blocks using the bitmap.
2979 * Outs:
2980 * dirty -- whether we changed the inode (1 == yes)
2bd0ea18
NS
2981 * used -- 1 if the inode is used, 0 if free. In no modify
2982 * mode, whether the inode should be used or free
2983 * isa_dir -- 1 if the inode is a directory, 0 if not. In
2984 * no modify mode, if the inode would be a dir or not.
2985 *
2986 * Return value -- 0 if the inode is good, 1 if it is/was corrupt
2987 */
2988
2989int
0459b626 2990process_dinode(
7328ea6e
CH
2991 xfs_mount_t *mp,
2992 struct xfs_dinode *dino,
2993 xfs_agnumber_t agno,
2994 xfs_agino_t ino,
2995 int was_free,
2996 int *dirty,
2997 int *used,
2998 int ino_discovery,
2999 int check_dups,
3000 int extra_attr_check,
3001 int *isa_dir,
3002 xfs_ino_t *parent)
2bd0ea18 3003{
7328ea6e
CH
3004 const int verify_mode = 0;
3005 const int uncertain = 0;
2bd0ea18
NS
3006
3007#ifdef XR_INODE_TRACE
9ee7055c 3008 fprintf(stderr, _("processing inode %d/%d\n"), agno, ino);
2bd0ea18 3009#endif
0459b626
BN
3010 return process_dinode_int(mp, dino, agno, ino, was_free, dirty, used,
3011 verify_mode, uncertain, ino_discovery,
3012 check_dups, extra_attr_check, isa_dir, parent);
2bd0ea18
NS
3013}
3014
3015/*
3016 * a more cursory check, check inode core, *DON'T* check forks
3017 * this basically just verifies whether the inode is an inode
3018 * and whether or not it has been totally trashed. returns 0
3019 * if the inode passes the cursory sanity check, 1 otherwise.
3020 */
3021int
0459b626 3022verify_dinode(
7328ea6e
CH
3023 xfs_mount_t *mp,
3024 struct xfs_dinode *dino,
3025 xfs_agnumber_t agno,
3026 xfs_agino_t ino)
2bd0ea18 3027{
7328ea6e
CH
3028 xfs_ino_t parent;
3029 int used = 0;
3030 int dirty = 0;
3031 int isa_dir = 0;
3032 const int verify_mode = 1;
3033 const int check_dups = 0;
3034 const int ino_discovery = 0;
3035 const int uncertain = 0;
0459b626
BN
3036
3037 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
3038 verify_mode, uncertain, ino_discovery,
3039 check_dups, 0, &isa_dir, &parent);
2bd0ea18
NS
3040}
3041
3042/*
3043 * like above only for inode on the uncertain list. it sets
3044 * the uncertain flag which makes process_dinode_int quieter.
3045 * returns 0 if the inode passes the cursory sanity check, 1 otherwise.
3046 */
3047int
0459b626 3048verify_uncertain_dinode(
7328ea6e
CH
3049 xfs_mount_t *mp,
3050 struct xfs_dinode *dino,
3051 xfs_agnumber_t agno,
3052 xfs_agino_t ino)
2bd0ea18 3053{
7328ea6e
CH
3054 xfs_ino_t parent;
3055 int used = 0;
3056 int dirty = 0;
3057 int isa_dir = 0;
3058 const int verify_mode = 1;
3059 const int check_dups = 0;
3060 const int ino_discovery = 0;
3061 const int uncertain = 1;
0459b626
BN
3062
3063 return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
3064 verify_mode, uncertain, ino_discovery,
3065 check_dups, 0, &isa_dir, &parent);
2bd0ea18 3066}