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