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