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