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