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