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