2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
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
7 * published by the Free Software Foundation.
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.
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
25 #include "err_protos.h"
31 #include "attr_repair.h"
36 * inode clearing routines
40 * return the offset into the inode where the attribute fork starts
44 calc_attr_offset(xfs_mount_t
*mp
, xfs_dinode_t
*dino
)
46 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
47 int offset
= ((__psint_t
) &dino
->di_u
)
51 * don't worry about alignment when calculating offset
52 * because the data fork is already 8-byte aligned
54 switch (dinoc
->di_format
) {
55 case XFS_DINODE_FMT_DEV
:
56 offset
+= sizeof(xfs_dev_t
);
58 case XFS_DINODE_FMT_LOCAL
:
59 offset
+= be64_to_cpu(dinoc
->di_size
);
61 case XFS_DINODE_FMT_EXTENTS
:
62 offset
+= be32_to_cpu(dinoc
->di_nextents
) *
63 sizeof(xfs_bmbt_rec_t
);
65 case XFS_DINODE_FMT_BTREE
:
66 offset
+= be16_to_cpu(dino
->di_u
.di_bmbt
.bb_numrecs
) *
67 sizeof(xfs_bmbt_rec_t
);
70 do_error(_("Unknown inode format.\n"));
80 clear_dinode_attr(xfs_mount_t
*mp
, xfs_dinode_t
*dino
, xfs_ino_t ino_num
)
82 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
84 ASSERT(dinoc
->di_forkoff
!= 0);
87 fprintf(stderr
, _("clearing inode %llu attributes\n"),
88 (unsigned long long)ino_num
);
90 fprintf(stderr
, _("would have cleared inode %llu attributes\n"),
91 (unsigned long long)ino_num
);
93 if (be16_to_cpu(dinoc
->di_anextents
) != 0) {
96 dinoc
->di_anextents
= cpu_to_be16(0);
99 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
102 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
105 /* get rid of the fork by clearing forkoff */
107 /* Originally, when the attr repair code was added, the fork was cleared
108 * by turning it into shortform status. This meant clearing the
109 * hdr.totsize/count fields and also changing aformat to LOCAL
110 * (vs EXTENTS). Over various fixes, the aformat and forkoff have
111 * been updated to not show an attribute fork at all, however.
112 * It could be possible that resetting totsize/count are not needed,
113 * but just to be safe, leave it in for now.
117 xfs_attr_shortform_t
*asf
= (xfs_attr_shortform_t
*)
118 XFS_DFORK_APTR(dino
);
119 asf
->hdr
.totsize
= cpu_to_be16(sizeof(xfs_attr_sf_hdr_t
));
121 dinoc
->di_forkoff
= 0; /* got to do this after asf is set */
125 * always returns 1 since the fork gets zapped
132 clear_dinode_core(xfs_dinode_core_t
*dinoc
, xfs_ino_t ino_num
)
136 if (be16_to_cpu(dinoc
->di_magic
) != XFS_DINODE_MAGIC
) {
142 dinoc
->di_magic
= cpu_to_be16(XFS_DINODE_MAGIC
);
145 if (!XFS_DINODE_GOOD_VERSION(dinoc
->di_version
) ||
146 (!fs_inode_nlink
&& dinoc
->di_version
> XFS_DINODE_VERSION_1
)) {
152 dinoc
->di_version
= (fs_inode_nlink
) ? XFS_DINODE_VERSION_2
153 : XFS_DINODE_VERSION_1
;
156 if (be16_to_cpu(dinoc
->di_mode
) != 0) {
165 if (be16_to_cpu(dinoc
->di_flags
) != 0) {
174 if (be32_to_cpu(dinoc
->di_dmevmask
) != 0) {
180 dinoc
->di_dmevmask
= 0;
183 if (dinoc
->di_forkoff
!= 0) {
189 dinoc
->di_forkoff
= 0;
192 if (dinoc
->di_format
!= XFS_DINODE_FMT_EXTENTS
) {
198 dinoc
->di_format
= XFS_DINODE_FMT_EXTENTS
;
201 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
207 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
210 if (be64_to_cpu(dinoc
->di_size
) != 0) {
219 if (be64_to_cpu(dinoc
->di_nblocks
) != 0) {
225 dinoc
->di_nblocks
= 0;
228 if (be16_to_cpu(dinoc
->di_onlink
) != 0) {
234 dinoc
->di_onlink
= 0;
237 if (be32_to_cpu(dinoc
->di_nextents
) != 0) {
243 dinoc
->di_nextents
= 0;
246 if (be16_to_cpu(dinoc
->di_anextents
) != 0) {
252 dinoc
->di_anextents
= 0;
255 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&&
256 be32_to_cpu(dinoc
->di_nlink
) != 0) {
270 clear_dinode_unlinked(xfs_mount_t
*mp
, xfs_dinode_t
*dino
)
273 if (be32_to_cpu(dino
->di_next_unlinked
) != NULLAGINO
) {
275 dino
->di_next_unlinked
= cpu_to_be32(NULLAGINO
);
283 * this clears the unlinked list too so it should not be called
284 * until after the agi unlinked lists are walked in phase 3.
285 * returns > zero if the inode has been altered while being cleared
288 clear_dinode(xfs_mount_t
*mp
, xfs_dinode_t
*dino
, xfs_ino_t ino_num
)
292 dirty
= clear_dinode_core(&dino
->di_core
, ino_num
);
293 dirty
+= clear_dinode_unlinked(mp
, dino
);
295 /* and clear the forks */
297 if (dirty
&& !no_modify
)
298 memset(&dino
->di_u
, 0, XFS_LITINO(mp
));
305 * misc. inode-related utility routines
309 * verify_ag_bno is heavily used. In the common case, it
310 * performs just two number of compares
311 * Returns 1 for bad ag/bno pair or 0 if it's valid.
314 verify_ag_bno(xfs_sb_t
*sbp
,
318 if (agno
< (sbp
->sb_agcount
- 1))
319 return (agbno
>= sbp
->sb_agblocks
);
320 if (agno
== (sbp
->sb_agcount
- 1))
321 return (agbno
>= (sbp
->sb_dblocks
-
322 ((sbp
->sb_agcount
- 1) * sbp
->sb_agblocks
)));
327 * returns 0 if inode number is valid, 1 if bogus
330 verify_inum(xfs_mount_t
*mp
,
336 xfs_sb_t
*sbp
= &mp
->m_sb
;;
338 /* range check ag #, ag block. range-checking offset is pointless */
340 agno
= XFS_INO_TO_AGNO(mp
, ino
);
341 agino
= XFS_INO_TO_AGINO(mp
, ino
);
342 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
346 if (ino
== 0 || ino
== NULLFSINO
)
349 if (ino
!= XFS_AGINO_TO_INO(mp
, agno
, agino
))
352 return verify_ag_bno(sbp
, agno
, agbno
);
356 * have a separate routine to ensure that we don't accidentally
357 * lose illegally set bits in the agino by turning it into an FSINO
358 * to feed to the above routine
361 verify_aginum(xfs_mount_t
*mp
,
366 xfs_sb_t
*sbp
= &mp
->m_sb
;;
368 /* range check ag #, ag block. range-checking offset is pointless */
370 if (agino
== 0 || agino
== NULLAGINO
)
374 * agino's can't be too close to NULLAGINO because the min blocksize
375 * is 9 bits and at most 1 bit of that gets used for the inode offset
376 * so if the agino gets shifted by the # of offset bits and compared
377 * to the legal agbno values, a bogus agino will be too large. there
378 * will be extra bits set at the top that shouldn't be set.
380 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
384 return verify_ag_bno(sbp
, agno
, agbno
);
388 * return 1 if block number is good, 0 if out of range
391 verify_dfsbno(xfs_mount_t
*mp
,
396 xfs_sb_t
*sbp
= &mp
->m_sb
;;
398 /* range check ag #, ag block. range-checking offset is pointless */
400 agno
= XFS_FSB_TO_AGNO(mp
, fsbno
);
401 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
);
403 return verify_ag_bno(sbp
, agno
, agbno
) == 0;
406 #define XR_DFSBNORANGE_VALID 0
407 #define XR_DFSBNORANGE_BADSTART 1
408 #define XR_DFSBNORANGE_BADEND 2
409 #define XR_DFSBNORANGE_OVERFLOW 3
412 verify_dfsbno_range(xfs_mount_t
*mp
,
414 xfs_dfilblks_t count
)
418 xfs_sb_t
*sbp
= &mp
->m_sb
;;
420 /* the start and end blocks better be in the same allocation group */
421 agno
= XFS_FSB_TO_AGNO(mp
, fsbno
);
422 if (agno
!= XFS_FSB_TO_AGNO(mp
, fsbno
+ count
- 1)) {
423 return XR_DFSBNORANGE_OVERFLOW
;
426 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
);
427 if (verify_ag_bno(sbp
, agno
, agbno
)) {
428 return XR_DFSBNORANGE_BADSTART
;
431 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
+ count
- 1);
432 if (verify_ag_bno(sbp
, agno
, agbno
)) {
433 return XR_DFSBNORANGE_BADEND
;
436 return (XR_DFSBNORANGE_VALID
);
440 verify_agbno(xfs_mount_t
*mp
,
444 xfs_sb_t
*sbp
= &mp
->m_sb
;;
446 /* range check ag #, ag block. range-checking offset is pointless */
447 return verify_ag_bno(sbp
, agno
, agbno
) == 0;
451 * return address of block fblock if it's within the range described
452 * by the extent list. Otherwise, returns a null address.
460 xfs_dfiloff_t fblock
)
463 xfs_bmbt_irec_t irec
;
465 for (i
= 0; i
< numrecs
; i
++) {
466 libxfs_bmbt_disk_get_all(rp
+ i
, &irec
);
467 if (irec
.br_startoff
>= fblock
&&
468 irec
.br_startoff
+ irec
.br_blockcount
< fblock
)
469 return (irec
.br_startblock
+ fblock
- irec
.br_startoff
);
478 xfs_bmbt_irec_t
*irec
,
486 int pwe
; /* partially-written extent */
489 * check numeric validity of the extent
491 if (irec
->br_startblock
>= mp
->m_sb
.sb_rblocks
) {
492 do_warn(_("inode %llu - bad rt extent start block number "
493 "%llu, offset %llu\n"), ino
,
494 irec
->br_startblock
, irec
->br_startoff
);
497 if (irec
->br_startblock
+ irec
->br_blockcount
- 1 >= mp
->m_sb
.sb_rblocks
) {
498 do_warn(_("inode %llu - bad rt extent last block number %llu, "
499 "offset %llu\n"), ino
, irec
->br_startblock
+
500 irec
->br_blockcount
- 1, irec
->br_startoff
);
503 if (irec
->br_startblock
+ irec
->br_blockcount
- 1 < irec
->br_startblock
) {
504 do_warn(_("inode %llu - bad rt extent overflows - start %llu, "
505 "end %llu, offset %llu\n"), ino
,
506 irec
->br_startblock
, irec
->br_startblock
+
507 irec
->br_blockcount
- 1, irec
->br_startoff
);
512 * verify that the blocks listed in the record
513 * are multiples of an extent
515 if (xfs_sb_version_hasextflgbit(&mp
->m_sb
) == 0 &&
516 (irec
->br_startblock
% mp
->m_sb
.sb_rextsize
!= 0 ||
517 irec
->br_blockcount
% mp
->m_sb
.sb_rextsize
!= 0)) {
518 do_warn(_("malformed rt inode extent [%llu %llu] (fs rtext "
519 "size = %u)\n"), irec
->br_startblock
,
520 irec
->br_blockcount
, mp
->m_sb
.sb_rextsize
);
525 * set the appropriate number of extents
527 for (b
= irec
->br_startblock
; b
< irec
->br_startblock
+
528 irec
->br_blockcount
; b
+= mp
->m_sb
.sb_rextsize
) {
529 ext
= (xfs_drtbno_t
) b
/ mp
->m_sb
.sb_rextsize
;
530 pwe
= xfs_sb_version_hasextflgbit(&mp
->m_sb
) &&
531 irec
->br_state
== XFS_EXT_UNWRITTEN
&&
532 (b
% mp
->m_sb
.sb_rextsize
!= 0);
534 if (check_dups
== 1) {
535 if (search_rt_dup_extent(mp
, ext
) && !pwe
) {
536 do_warn(_("data fork in rt ino %llu claims "
537 "dup rt extent, off - %llu, "
538 "start - %llu, count %llu\n"),
539 ino
, irec
->br_startoff
,
541 irec
->br_blockcount
);
547 state
= get_rtbno_state(mp
, ext
);
552 set_rtbno_state(mp
, ext
, XR_E_INUSE
);
556 do_error(_("bad state in rt block map %llu\n"),
562 do_error(_("data fork in rt inode %llu found "
563 "metadata block %llu in rt bmap\n"),
571 set_rtbno_state(mp
, ext
, XR_E_MULT
);
572 do_warn(_("data fork in rt inode %llu claims "
573 "used rt block %llu\n"),
579 do_error(_("illegal state %d in rt block map "
580 "%llu\n"), state
, b
);
585 * bump up the block counter
587 *tot
+= irec
->br_blockcount
;
593 * return 1 if inode should be cleared, 0 otherwise
594 * if check_dups should be set to 1, that implies that
595 * the primary purpose of this call is to see if the
596 * file overlaps with any duplicate extents (in the
597 * duplicate extent list).
601 process_bmbt_reclist_int(
609 xfs_dfiloff_t
*first_key
,
610 xfs_dfiloff_t
*last_key
,
614 xfs_bmbt_irec_t irec
;
615 xfs_dfilblks_t cp
= 0; /* prev count */
616 xfs_dfsbno_t sp
= 0; /* prev start */
617 xfs_dfiloff_t op
= 0; /* prev offset */
626 xfs_agnumber_t locked_agno
= -1;
629 if (whichfork
== XFS_DATA_FORK
)
630 forkname
= _("data");
632 forkname
= _("attr");
634 if (type
== XR_INO_RTDATA
)
635 ftype
= _("real-time");
637 ftype
= _("regular");
639 for (i
= 0; i
< numrecs
; i
++) {
640 libxfs_bmbt_disk_get_all(rp
+ i
, &irec
);
642 *last_key
= *first_key
= irec
.br_startoff
;
644 *last_key
= irec
.br_startoff
;
645 if (i
> 0 && op
+ cp
> irec
.br_startoff
) {
646 do_warn(_("bmap rec out of order, inode %llu entry %d "
647 "[o s c] [%llu %llu %llu], %d [%llu %llu %llu]\n"),
648 ino
, i
, irec
.br_startoff
, irec
.br_startblock
,
649 irec
.br_blockcount
, i
- 1, op
, sp
, cp
);
652 op
= irec
.br_startoff
;
653 cp
= irec
.br_blockcount
;
654 sp
= irec
.br_startblock
;
657 * check numeric validity of the extent
659 if (irec
.br_blockcount
== 0) {
660 do_warn(_("zero length extent (off = %llu, fsbno = "
661 "%llu) in ino %llu\n"), irec
.br_startoff
,
662 irec
.br_startblock
, ino
);
666 if (type
== XR_INO_RTDATA
&& whichfork
== XFS_DATA_FORK
) {
668 * realtime bitmaps don't use AG locks, so returning
669 * immediately is fine for this code path.
671 if (process_rt_rec(mp
, &irec
, ino
, tot
, check_dups
))
674 * skip rest of loop processing since that'irec.br_startblock
675 * all for regular file forks and attr forks
681 * regular file data fork or attribute fork
683 switch (verify_dfsbno_range(mp
, irec
.br_startblock
,
684 irec
.br_blockcount
)) {
685 case XR_DFSBNORANGE_VALID
:
688 case XR_DFSBNORANGE_BADSTART
:
689 do_warn(_("inode %llu - bad extent starting "
690 "block number %llu, offset %llu\n"),
691 ino
, irec
.br_startblock
,
695 case XR_DFSBNORANGE_BADEND
:
696 do_warn(_("inode %llu - bad extent last block "
697 "number %llu, offset %llu\n"), ino
,
698 irec
.br_startblock
+ irec
.br_blockcount
699 - 1, irec
.br_startoff
);
702 case XR_DFSBNORANGE_OVERFLOW
:
703 do_warn(_("inode %llu - bad extent overflows - "
704 "start %llu, end %llu, offset %llu\n"),
705 ino
, irec
.br_startblock
,
706 irec
.br_startblock
+ irec
.br_blockcount
707 - 1, irec
.br_startoff
);
710 if (irec
.br_startoff
>= fs_max_file_offset
) {
711 do_warn(_("inode %llu - extent offset too large - "
712 "start %llu, count %llu, offset %llu\n"),
713 ino
, irec
.br_startblock
, irec
.br_blockcount
,
718 if (blkmapp
&& *blkmapp
)
719 blkmap_set_ext(blkmapp
, irec
.br_startoff
,
720 irec
.br_startblock
, irec
.br_blockcount
);
722 * Profiling shows that the following loop takes the
723 * most time in all of xfs_repair.
725 agno
= XFS_FSB_TO_AGNO(mp
, irec
.br_startblock
);
726 agbno
= XFS_FSB_TO_AGBNO(mp
, irec
.br_startblock
);
727 e
= irec
.br_startblock
+ irec
.br_blockcount
;
728 if (agno
!= locked_agno
) {
729 if (locked_agno
!= -1)
730 pthread_mutex_unlock(&ag_locks
[locked_agno
]);
731 pthread_mutex_lock(&ag_locks
[agno
]);
737 * if we're just checking the bmap for dups,
738 * return if we find one, otherwise, continue
739 * checking each entry without setting the
742 for (b
= irec
.br_startblock
; b
< e
; b
++, agbno
++) {
743 if (search_dup_extent(mp
, agno
, agbno
)) {
744 do_warn(_("%s fork in ino %llu claims "
745 "dup extent, off - %llu, "
746 "start - %llu, cnt %llu\n"),
747 forkname
, ino
, irec
.br_startoff
,
753 *tot
+= irec
.br_blockcount
;
757 for (b
= irec
.br_startblock
; b
< e
; b
++, agbno
++) {
759 * Process in chunks of 16 (XR_BB_UNIT/XR_BB)
760 * for common XR_E_UNKNOWN to XR_E_INUSE transition
762 if (((agbno
& XR_BB_MASK
) == 0) && ((irec
.br_startblock
+ irec
.br_blockcount
- b
) >= (XR_BB_UNIT
/XR_BB
))) {
763 if (ba_bmap
[agno
][agbno
>>XR_BB
] == XR_E_UNKNOWN_LL
) {
764 ba_bmap
[agno
][agbno
>>XR_BB
] = XR_E_INUSE_LL
;
765 agbno
+= (XR_BB_UNIT
/XR_BB
) - 1;
766 b
+= (XR_BB_UNIT
/XR_BB
) - 1;
772 state
= get_agbno_state(mp
, agno
, agbno
);
777 do_warn(_("%s fork in ino %llu claims free "
779 forkname
, ino
, (__uint64_t
) b
);
780 /* fall through ... */
782 set_agbno_state(mp
, agno
, agbno
, XR_E_INUSE
);
786 do_error(_("bad state in block map %llu\n"), b
);
791 do_warn(_("%s fork in inode %llu claims "
792 "metadata block %llu\n"),
793 forkname
, ino
, (__uint64_t
) b
);
798 set_agbno_state(mp
, agno
, agbno
, XR_E_MULT
);
799 do_warn(_("%s fork in %s inode %llu claims "
800 "used block %llu\n"),
801 forkname
, ftype
, ino
, (__uint64_t
) b
);
805 do_error(_("illegal state %d in block map %llu\n"),
809 *tot
+= irec
.br_blockcount
;
813 if (locked_agno
!= -1)
814 pthread_mutex_unlock(&ag_locks
[locked_agno
]);
819 * return 1 if inode should be cleared, 0 otherwise, sets block bitmap
823 process_bmbt_reclist(
831 xfs_dfiloff_t
*first_key
,
832 xfs_dfiloff_t
*last_key
,
835 return process_bmbt_reclist_int(mp
, rp
, numrecs
, type
, ino
, tot
,
836 blkmapp
, first_key
, last_key
, 0, whichfork
);
840 * return 1 if inode should be cleared, 0 otherwise, does not set
853 xfs_dfiloff_t first_key
= 0;
854 xfs_dfiloff_t last_key
= 0;
856 return process_bmbt_reclist_int(mp
, rp
, numrecs
, type
, ino
, tot
,
857 NULL
, &first_key
, &last_key
, 1, whichfork
);
861 * these two are meant for routines that read and work with inodes
862 * one at a time where the inodes may be in any order (like walking
863 * the unlinked lists to look for inodes). the caller is responsible
864 * for writing/releasing the buffer.
867 get_agino_buf(xfs_mount_t
*mp
,
872 ino_tree_node_t
*irec
;
876 if ((irec
= find_inode_rec(agno
, agino
)) == NULL
)
879 size
= XFS_FSB_TO_BB(mp
, MAX(1, XFS_INODES_PER_CHUNK
/inodes_per_block
));
880 bp
= libxfs_readbuf(mp
->m_dev
, XFS_AGB_TO_DADDR(mp
, agno
,
881 XFS_AGINO_TO_AGBNO(mp
, irec
->ino_startnum
)), size
, 0);
883 do_warn(_("cannot read inode (%u/%u), disk block %lld\n"),
884 agno
, irec
->ino_startnum
,
885 XFS_AGB_TO_DADDR(mp
, agno
,
886 XFS_AGINO_TO_AGBNO(mp
, irec
->ino_startnum
)));
890 *dipp
= XFS_MAKE_IPTR(mp
, bp
, agino
-
891 XFS_OFFBNO_TO_AGINO(mp
, XFS_AGINO_TO_AGBNO(mp
,
899 * these next routines return the filesystem blockno of the
900 * block containing the block "bno" in the file whose bmap
901 * tree (or extent list) is rooted by "rootblock".
903 * the next routines are utility routines for the third
904 * routine, get_bmapi().
906 * NOTE: getfunc_extlist only used by dirv1 checking code
909 getfunc_extlist(xfs_mount_t
*mp
,
915 xfs_bmbt_irec_t irec
;
916 xfs_dfsbno_t final_fsbno
= NULLDFSBNO
;
917 xfs_bmbt_rec_t
*rootblock
= (xfs_bmbt_rec_t
*)
918 XFS_DFORK_PTR(dip
, whichfork
);
919 xfs_extnum_t nextents
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
922 for (i
= 0; i
< nextents
; i
++) {
923 libxfs_bmbt_disk_get_all(rootblock
+ i
, &irec
);
924 if (irec
.br_startoff
<= bno
&&
925 bno
< irec
.br_startoff
+ irec
.br_blockcount
) {
926 final_fsbno
= bno
- irec
.br_startoff
+ irec
.br_startblock
;
935 * NOTE: getfunc_btree only used by dirv1 checking code...
938 getfunc_btree(xfs_mount_t
*mp
,
951 xfs_bmbt_irec_t irec
;
954 xfs_bmdr_key_t
*rkey
;
958 xfs_dfsbno_t final_fsbno
= NULLDFSBNO
;
959 struct xfs_btree_block
*block
;
960 xfs_bmdr_block_t
*rootblock
= (xfs_bmdr_block_t
*)
961 XFS_DFORK_PTR(dip
, whichfork
);
963 ASSERT(rootblock
->bb_level
!= 0);
965 * deal with root block, it's got a slightly different
966 * header structure than interior nodes. We know that
967 * a btree should have at least 2 levels otherwise it
968 * would be an extent list.
970 rkey
= XFS_BMDR_KEY_ADDR(rootblock
, 1);
971 rp
= XFS_BMDR_PTR_ADDR(rootblock
, 1,
972 xfs_bmdr_maxrecs(mp
, XFS_DFORK_SIZE(dip
, mp
, whichfork
), 1));
974 for (i
= 0; i
< be16_to_cpu(rootblock
->bb_numrecs
) - 1; i
++) {
975 if (be64_to_cpu(rkey
[i
].br_startoff
) <= bno
&&
976 bno
< be64_to_cpu(rkey
[i
+ 1].br_startoff
)) {
981 if (i
== be16_to_cpu(rootblock
->bb_numrecs
) - 1 &&
982 bno
>= be64_to_cpu(rkey
[i
].br_startoff
))
987 fsbno
= be64_to_cpu(rp
[found
]);
989 ASSERT(verify_dfsbno(mp
, fsbno
));
991 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
992 XFS_FSB_TO_BB(mp
, 1), 0);
994 do_error(_("cannot read bmap block %llu\n"), fsbno
);
997 block
= XFS_BUF_TO_BLOCK(bp
);
998 numrecs
= be16_to_cpu(block
->bb_numrecs
);
1001 * ok, now traverse any interior btree nodes
1004 prev_level
= be16_to_cpu(block
->bb_level
);
1007 while (be16_to_cpu(block
->bb_level
) > 0) {
1009 ASSERT(be16_to_cpu(block
->bb_level
) < prev_level
);
1011 prev_level
= be16_to_cpu(block
->bb_level
);
1013 if (numrecs
> mp
->m_bmap_dmxr
[1]) {
1014 do_warn(_("# of bmap records in inode %llu exceeds max "
1015 "(%u, max - %u)\n"),
1017 mp
->m_bmap_dmxr
[1]);
1021 if (verbose
&& numrecs
< mp
->m_bmap_dmnr
[1]) {
1022 do_warn(_("- # of bmap records in inode %llu less than "
1023 "minimum (%u, min - %u), proceeding ...\n"),
1024 ino
, numrecs
, mp
->m_bmap_dmnr
[1]);
1026 key
= XFS_BMBT_KEY_ADDR(mp
, block
, 1);
1027 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[1]);
1028 for (found
= -1, i
= 0; i
< numrecs
- 1; i
++) {
1029 if (be64_to_cpu(key
[i
].br_startoff
) <= bno
&& bno
<
1030 be64_to_cpu(key
[i
+ 1].br_startoff
)) {
1035 if (i
== numrecs
- 1 && bno
>= be64_to_cpu(key
[i
].br_startoff
))
1038 ASSERT(found
!= -1);
1039 fsbno
= be64_to_cpu(pp
[found
]);
1041 ASSERT(verify_dfsbno(mp
, fsbno
));
1044 * release current btree block and read in the
1045 * next btree block to be traversed
1048 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1049 XFS_FSB_TO_BB(mp
, 1), 0);
1051 do_error(_("cannot read bmap block %llu\n"), fsbno
);
1054 block
= XFS_BUF_TO_BLOCK(bp
);
1055 numrecs
= be16_to_cpu(block
->bb_numrecs
);
1059 * current block must be a leaf block
1061 ASSERT(be16_to_cpu(block
->bb_level
) == 0);
1062 if (numrecs
> mp
->m_bmap_dmxr
[0]) {
1063 do_warn(_("# of bmap records in inode %llu greater than "
1064 "maximum (%u, max - %u)\n"),
1065 ino
, numrecs
, mp
->m_bmap_dmxr
[0]);
1069 if (verbose
&& numrecs
< mp
->m_bmap_dmnr
[0])
1070 do_warn(_("- # of bmap records in inode %llu less than minimum "
1071 "(%u, min - %u), continuing...\n"),
1072 ino
, numrecs
, mp
->m_bmap_dmnr
[0]);
1074 rec
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
1075 for (i
= 0; i
< numrecs
; i
++) {
1076 libxfs_bmbt_disk_get_all(rec
+ i
, &irec
);
1077 if (irec
.br_startoff
<= bno
&&
1078 bno
< irec
.br_startoff
+ irec
.br_blockcount
) {
1079 final_fsbno
= bno
- irec
.br_startoff
+
1086 if (final_fsbno
== NULLDFSBNO
)
1087 do_warn(_("could not map block %llu\n"), bno
);
1089 return(final_fsbno
);
1093 * this could be smarter. maybe we should have an open inode
1094 * routine that would get the inode buffer and return back
1095 * an inode handle. I'm betting for the moment that this
1096 * is used only by the directory and attribute checking code
1097 * and that the avl tree find and buffer cache search are
1098 * relatively cheap. If they're too expensive, we'll just
1099 * have to fix this and add an inode handle to the da btree
1102 * caller is responsible for checking doubly referenced blocks
1103 * and references to holes
1105 * NOTE: get_bmapi only used by dirv1 checking code
1108 get_bmapi(xfs_mount_t
*mp
, xfs_dinode_t
*dino_p
,
1109 xfs_ino_t ino_num
, xfs_dfiloff_t bno
, int whichfork
)
1113 switch (XFS_DFORK_FORMAT(dino_p
, whichfork
)) {
1114 case XFS_DINODE_FMT_EXTENTS
:
1115 fsbno
= getfunc_extlist(mp
, ino_num
, dino_p
, bno
, whichfork
);
1117 case XFS_DINODE_FMT_BTREE
:
1118 fsbno
= getfunc_btree(mp
, ino_num
, dino_p
, bno
, whichfork
);
1120 case XFS_DINODE_FMT_LOCAL
:
1121 do_error(_("get_bmapi() called for local inode %llu\n"),
1129 do_error(_("bad inode format for inode %llu\n"), ino_num
);
1137 * higher level inode processing stuff starts here:
1138 * first, one utility routine for each type of inode
1142 * return 1 if inode should be cleared, 0 otherwise
1148 xfs_agnumber_t agno
,
1159 xfs_bmdr_block_t
*dib
;
1160 xfs_dfiloff_t last_key
;
1161 xfs_dfiloff_t first_key
= 0;
1164 xfs_bmbt_key_t
*pkey
;
1169 bmap_cursor_t cursor
;
1171 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
1172 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1176 if (whichfork
== XFS_DATA_FORK
)
1177 forkname
= _("data");
1179 forkname
= _("attr");
1181 level
= be16_to_cpu(dib
->bb_level
);
1182 numrecs
= be16_to_cpu(dib
->bb_numrecs
);
1184 if ((level
== 0) || (level
> XFS_BM_MAXLEVELS(mp
, whichfork
))) {
1186 * XXX - if we were going to fix up the inode,
1187 * we'd try to treat the fork as an interior
1188 * node and see if we could get an accurate
1189 * level value from one of the blocks pointed
1190 * to by the pointers in the fork. For now
1191 * though, we just bail (and blow out the inode).
1193 do_warn(_("bad level %d in inode %llu bmap btree root block\n"),
1194 level
, XFS_AGINO_TO_INO(mp
, agno
, ino
));
1198 do_warn(_("bad numrecs 0 in inode %llu bmap btree root block\n"),
1199 XFS_AGINO_TO_INO(mp
, agno
, ino
));
1203 * use bmdr/dfork_dsize since the root block is in the data fork
1205 if (XFS_BMDR_SPACE_CALC(numrecs
) > XFS_DFORK_SIZE(dip
, mp
, whichfork
)) {
1207 _("indicated size of %s btree root (%d bytes) greater than space in "
1208 "inode %llu %s fork\n"),
1209 forkname
, XFS_BMDR_SPACE_CALC(numrecs
), lino
, forkname
);
1213 init_bm_cursor(&cursor
, level
+ 1);
1215 pp
= XFS_BMDR_PTR_ADDR(dib
, 1,
1216 xfs_bmdr_maxrecs(mp
, XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
1217 pkey
= XFS_BMDR_KEY_ADDR(dib
, 1);
1218 last_key
= NULLDFILOFF
;
1220 for (i
= 0; i
< numrecs
; i
++) {
1222 * XXX - if we were going to do more to fix up the inode
1223 * btree, we'd do it right here. For now, if there's a
1224 * problem, we'll bail out and presumably clear the inode.
1226 if (!verify_dfsbno(mp
, be64_to_cpu(pp
[i
]))) {
1227 do_warn(_("bad bmap btree ptr 0x%llx in ino %llu\n"),
1228 be64_to_cpu(pp
[i
]), lino
);
1232 if (scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
,
1233 whichfork
, lino
, tot
, nex
, blkmapp
, &cursor
,
1237 * fix key (offset) mismatches between the keys in root
1238 * block records and the first key of each child block.
1239 * fixes cases where entries have been shifted between
1240 * blocks but the parent hasn't been updated
1242 if (!check_dups
&& cursor
.level
[level
-1].first_key
!=
1243 be64_to_cpu(pkey
[i
].br_startoff
)) {
1246 _("correcting key in bmbt root (was %llu, now %llu) in inode "
1248 be64_to_cpu(pkey
[i
].br_startoff
),
1249 cursor
.level
[level
-1].first_key
,
1250 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1253 pkey
[i
].br_startoff
= cpu_to_be64(
1254 cursor
.level
[level
-1].first_key
);
1257 _("bad key in bmbt root (is %llu, would reset to %llu) in inode "
1259 be64_to_cpu(pkey
[i
].br_startoff
),
1260 cursor
.level
[level
-1].first_key
,
1261 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1266 * make sure that keys are in ascending order. blow out
1267 * inode if the ordering doesn't hold
1269 if (check_dups
== 0) {
1270 if (last_key
!= NULLDFILOFF
&& last_key
>=
1271 cursor
.level
[level
-1].first_key
) {
1273 _("out of order bmbt root key %llu in inode %llu %s fork\n"),
1275 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1279 last_key
= cursor
.level
[level
-1].first_key
;
1283 * Check that the last child block's forward sibling pointer
1286 if (check_dups
== 0 &&
1287 cursor
.level
[0].right_fsbno
!= NULLDFSBNO
) {
1289 _("bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n"),
1290 cursor
.level
[0].right_fsbno
);
1292 _("\tin inode %u (%s fork) bmap btree block %llu\n"),
1293 XFS_AGINO_TO_INO(mp
, agno
, ino
), forkname
,
1294 cursor
.level
[0].fsbno
);
1302 * return 1 if inode should be cleared, 0 otherwise
1308 xfs_agnumber_t agno
,
1321 xfs_dfiloff_t first_key
;
1322 xfs_dfiloff_t last_key
;
1324 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1325 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
1327 *nex
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
1329 * XXX - if we were going to fix up the btree record,
1330 * we'd do it right here. For now, if there's a problem,
1331 * we'll bail out and presumably clear the inode.
1333 if (check_dups
== 0)
1334 return(process_bmbt_reclist(mp
, rp
, *nex
, type
, lino
,
1335 tot
, blkmapp
, &first_key
, &last_key
,
1338 return(scan_bmbt_reclist(mp
, rp
, *nex
, type
, lino
, tot
,
1343 * return 1 if inode should be cleared, 0 otherwise
1348 xfs_agnumber_t agno
,
1353 xfs_attr_shortform_t
*asf
;
1356 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1357 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_core
.di_size
) >
1358 XFS_DFORK_DSIZE(dip
, mp
)) {
1360 _("local inode %llu data fork is too large (size = %lld, max = %d)\n"),
1361 lino
, be64_to_cpu(dip
->di_core
.di_size
),
1362 XFS_DFORK_DSIZE(dip
, mp
));
1364 } else if (whichfork
== XFS_ATTR_FORK
) {
1365 asf
= (xfs_attr_shortform_t
*)XFS_DFORK_APTR(dip
);
1366 if (be16_to_cpu(asf
->hdr
.totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
1368 _("local inode %llu attr fork too large (size %d, max = %d)\n"),
1369 lino
, be16_to_cpu(asf
->hdr
.totsize
),
1370 XFS_DFORK_ASIZE(dip
, mp
));
1373 if (be16_to_cpu(asf
->hdr
.totsize
) < sizeof(xfs_attr_sf_hdr_t
)) {
1375 _("local inode %llu attr too small (size = %d, min size = %d)\n"),
1376 lino
, be16_to_cpu(asf
->hdr
.totsize
),
1377 sizeof(xfs_attr_sf_hdr_t
));
1386 process_symlink_extlist(xfs_mount_t
*mp
, xfs_ino_t lino
, xfs_dinode_t
*dino
)
1388 xfs_dfiloff_t expected_offset
;
1390 xfs_bmbt_irec_t irec
;
1395 if (be64_to_cpu(dino
->di_core
.di_size
) <= XFS_DFORK_DSIZE(dino
, mp
)) {
1396 if (dino
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
)
1398 do_warn(_("mismatch between format (%d) and size (%lld) in "
1399 "symlink ino %llu\n"), dino
->di_core
.di_format
,
1400 be64_to_cpu(dino
->di_core
.di_size
), lino
);
1403 if (dino
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
) {
1404 do_warn(_("mismatch between format (%d) and size (%lld) in "
1405 "symlink inode %llu\n"), dino
->di_core
.di_format
,
1406 be64_to_cpu(dino
->di_core
.di_size
), lino
);
1410 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_DPTR(dino
);
1411 numrecs
= be32_to_cpu(dino
->di_core
.di_nextents
);
1414 * the max # of extents in a symlink inode is equal to the
1415 * number of max # of blocks required to store the symlink
1417 if (numrecs
> max_symlink_blocks
) {
1419 _("bad number of extents (%d) in symlink %llu data fork\n"),
1424 max_blocks
= max_symlink_blocks
;
1425 expected_offset
= 0;
1427 for (i
= 0; i
< numrecs
; i
++) {
1428 libxfs_bmbt_disk_get_all(rp
+ i
, &irec
);
1430 if (irec
.br_startoff
!= expected_offset
) {
1432 _("bad extent #%d offset (%llu) in symlink %llu data fork\n"),
1433 i
, irec
.br_startoff
, lino
);
1436 if (irec
.br_blockcount
== 0 || irec
.br_blockcount
> max_blocks
) {
1438 _("bad extent #%d count (%llu) in symlink %llu data fork\n"),
1439 i
, irec
.br_blockcount
, lino
);
1443 max_blocks
-= irec
.br_blockcount
;
1444 expected_offset
+= irec
.br_blockcount
;
1451 * takes a name and length and returns 1 if the name contains
1452 * a \0, returns 0 otherwise
1455 null_check(char *name
, int length
)
1459 ASSERT(length
< MAXPATHLEN
);
1461 for (i
= 0; i
< length
; i
++, name
++) {
1470 * like usual, returns 0 if everything's ok and 1 if something's
1481 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
1482 xfs_buf_t
*bp
= NULL
;
1483 char *symlink
, *cptr
, *buf_data
;
1484 int i
, size
, amountdone
;
1485 char data
[MAXPATHLEN
];
1488 * check size against kernel symlink limits. we know
1489 * size is consistent with inode storage format -- e.g.
1490 * the inode is structurally ok so we don't have to check
1493 if (be64_to_cpu(dinoc
->di_size
) >= MAXPATHLEN
) {
1494 do_warn(_("symlink in inode %llu too long (%lld chars)\n"),
1495 lino
, be64_to_cpu(dinoc
->di_size
));
1500 * have to check symlink component by component.
1501 * get symlink contents into data area
1504 if (be64_to_cpu(dinoc
->di_size
) <= XFS_DFORK_DSIZE(dino
, mp
)) {
1506 * local symlink, just copy the symlink out of the
1507 * inode into the data area
1509 memmove(symlink
, XFS_DFORK_DPTR(dino
),
1510 be64_to_cpu(dinoc
->di_size
));
1513 * stored in a meta-data file, have to bmap one block
1514 * at a time and copy the symlink into the data area
1516 i
= size
= amountdone
= 0;
1519 while (amountdone
< be64_to_cpu(dinoc
->di_size
)) {
1520 fsbno
= blkmap_get(blkmap
, i
);
1521 if (fsbno
!= NULLDFSBNO
)
1522 bp
= libxfs_readbuf(mp
->m_dev
,
1523 XFS_FSB_TO_DADDR(mp
, fsbno
),
1524 XFS_FSB_TO_BB(mp
, 1), 0);
1525 if (!bp
|| fsbno
== NULLDFSBNO
) {
1527 _("cannot read inode %llu, file block %d, disk block %llu\n"),
1532 buf_data
= (char *)XFS_BUF_PTR(bp
);
1533 size
= MIN(be64_to_cpu(dinoc
->di_size
) - amountdone
,
1534 XFS_FSB_TO_BB(mp
, 1) * BBSIZE
);
1535 memmove(cptr
, buf_data
, size
);
1542 data
[be64_to_cpu(dinoc
->di_size
)] = '\0';
1547 if (null_check(symlink
, be64_to_cpu(dinoc
->di_size
))) {
1549 _("found illegal null character in symlink inode %llu\n"),
1555 * check for any component being too long
1557 if (be64_to_cpu(dinoc
->di_size
) >= MAXNAMELEN
) {
1558 cptr
= strchr(symlink
, '/');
1560 while (cptr
!= NULL
) {
1561 if (cptr
- symlink
>= MAXNAMELEN
) {
1563 _("component of symlink in inode %llu too long\n"),
1568 cptr
= strchr(symlink
, '/');
1571 if (strlen(symlink
) >= MAXNAMELEN
) {
1573 _("component of symlink in inode %llu too long\n"),
1583 * called to process the set of misc inode special inode types
1584 * that have no associated data storage (fifos, pipes, devices, etc.).
1587 process_misc_ino_types(xfs_mount_t
*mp
,
1593 * disallow mountpoint inodes until such time as the
1594 * kernel actually allows them to be created (will
1595 * probably require a superblock version rev, sigh).
1597 if (type
== XR_INO_MOUNTPOINT
) {
1598 do_warn(_("inode %llu has bad inode type (IFMNT)\n"), lino
);
1603 * must also have a zero size
1605 if (be64_to_cpu(dino
->di_core
.di_size
) != 0) {
1608 do_warn(_("size of character device inode %llu != 0 "
1609 "(%lld bytes)\n"), lino
,
1610 be64_to_cpu(dino
->di_core
.di_size
));
1613 do_warn(_("size of block device inode %llu != 0 "
1614 "(%lld bytes)\n"), lino
,
1615 be64_to_cpu(dino
->di_core
.di_size
));
1618 do_warn(_("size of socket inode %llu != 0 "
1619 "(%lld bytes)\n"), lino
,
1620 be64_to_cpu(dino
->di_core
.di_size
));
1623 do_warn(_("size of fifo inode %llu != 0 "
1624 "(%lld bytes)\n"), lino
,
1625 be64_to_cpu(dino
->di_core
.di_size
));
1628 do_warn(_("Internal error - process_misc_ino_types, "
1629 "illegal type %d\n"), type
);
1640 process_misc_ino_types_blocks(xfs_drfsbno_t totblocks
, xfs_ino_t lino
, int type
)
1643 * you can not enforce all misc types have zero data fork blocks
1644 * by checking dino->di_core.di_nblocks because atotblocks (attribute
1645 * blocks) are part of nblocks. We must check this later when atotblocks
1646 * has been calculated or by doing a simple check that anExtents == 0.
1647 * We must also guarantee that totblocks is 0. Thus nblocks checking
1648 * will be done later in process_dinode_int for misc types.
1651 if (totblocks
!= 0) {
1655 _("size of character device inode %llu != 0 (%llu blocks)\n"),
1660 _("size of block device inode %llu != 0 (%llu blocks)\n"),
1665 _("size of socket inode %llu != 0 (%llu blocks)\n"),
1670 _("size of fifo inode %llu != 0 (%llu blocks)\n"),
1683 xfs_dinode_core_t
*dinoc
)
1685 return be16_to_cpu(dinoc
->di_mode
) & S_IFMT
;
1690 xfs_dinode_core_t
*dinoc
,
1693 int mode
= be16_to_cpu(dinoc
->di_mode
);
1695 ASSERT((new_fmt
& ~S_IFMT
) == 0);
1699 dinoc
->di_mode
= cpu_to_be16(mode
);
1703 check_dinode_mode_format(
1704 xfs_dinode_core_t
*dinoc
)
1706 if (dinoc
->di_format
>= XFS_DINODE_FMT_UUID
)
1707 return -1; /* FMT_UUID is not used */
1709 switch (dinode_fmt(dinoc
)) {
1714 return (dinoc
->di_format
!= XFS_DINODE_FMT_DEV
) ? -1 : 0;
1717 return (dinoc
->di_format
< XFS_DINODE_FMT_LOCAL
||
1718 dinoc
->di_format
> XFS_DINODE_FMT_BTREE
) ? -1 : 0;
1721 return (dinoc
->di_format
< XFS_DINODE_FMT_EXTENTS
||
1722 dinoc
->di_format
> XFS_DINODE_FMT_BTREE
) ? -1 : 0;
1725 return (dinoc
->di_format
< XFS_DINODE_FMT_LOCAL
||
1726 dinoc
->di_format
> XFS_DINODE_FMT_EXTENTS
) ? -1 : 0;
1730 return 0; /* invalid modes are checked elsewhere */
1734 * If inode is a superblock inode, does type check to make sure is it valid.
1735 * Returns 0 if it's valid, non-zero if it needs to be cleared.
1739 process_check_sb_inodes(
1741 xfs_dinode_core_t
*dinoc
,
1746 if (lino
== mp
->m_sb
.sb_rootino
) {
1747 if (*type
!= XR_INO_DIR
) {
1748 do_warn(_("root inode %llu has bad type 0x%x\n"),
1749 lino
, dinode_fmt(dinoc
));
1752 do_warn(_("resetting to directory\n"));
1753 change_dinode_fmt(dinoc
, S_IFDIR
);
1756 do_warn(_("would reset to directory\n"));
1760 if (lino
== mp
->m_sb
.sb_uquotino
) {
1761 if (*type
!= XR_INO_DATA
) {
1762 do_warn(_("user quota inode %llu has bad type 0x%x\n"),
1763 lino
, dinode_fmt(dinoc
));
1764 mp
->m_sb
.sb_uquotino
= NULLFSINO
;
1769 if (lino
== mp
->m_sb
.sb_gquotino
) {
1770 if (*type
!= XR_INO_DATA
) {
1771 do_warn(_("group quota inode %llu has bad type 0x%x\n"),
1772 lino
, dinode_fmt(dinoc
));
1773 mp
->m_sb
.sb_gquotino
= NULLFSINO
;
1778 if (lino
== mp
->m_sb
.sb_rsumino
) {
1779 if (*type
!= XR_INO_RTSUM
) {
1780 do_warn(_("realtime summary inode %llu has bad type 0x%x, "),
1781 lino
, dinode_fmt(dinoc
));
1783 do_warn(_("resetting to regular file\n"));
1784 change_dinode_fmt(dinoc
, S_IFREG
);
1787 do_warn(_("would reset to regular file\n"));
1790 if (mp
->m_sb
.sb_rblocks
== 0 && dinoc
->di_nextents
!= 0) {
1791 do_warn(_("bad # of extents (%u) for realtime summary inode %llu\n"),
1792 be32_to_cpu(dinoc
->di_nextents
), lino
);
1797 if (lino
== mp
->m_sb
.sb_rbmino
) {
1798 if (*type
!= XR_INO_RTBITMAP
) {
1799 do_warn(_("realtime bitmap inode %llu has bad type 0x%x, "),
1800 lino
, dinode_fmt(dinoc
));
1802 do_warn(_("resetting to regular file\n"));
1803 change_dinode_fmt(dinoc
, S_IFREG
);
1806 do_warn(_("would reset to regular file\n"));
1809 if (mp
->m_sb
.sb_rblocks
== 0 && dinoc
->di_nextents
!= 0) {
1810 do_warn(_("bad # of extents (%u) for realtime bitmap inode %llu\n"),
1811 be32_to_cpu(dinoc
->di_nextents
), lino
);
1820 * general size/consistency checks:
1822 * if the size <= size of the data fork, directories must be
1823 * local inodes unlike regular files which would be extent inodes.
1824 * all the other mentioned types have to have a zero size value.
1826 * if the size and format don't match, get out now rather than
1827 * risk trying to process a non-existent extents or btree
1831 process_check_inode_sizes(
1837 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
1838 xfs_fsize_t size
= be64_to_cpu(dinoc
->di_size
);
1843 if (size
<= XFS_DFORK_DSIZE(dino
, mp
) &&
1844 dinoc
->di_format
!= XFS_DINODE_FMT_LOCAL
) {
1845 do_warn(_("mismatch between format (%d) and size "
1846 "(%lld) in directory ino %llu\n"),
1847 dinoc
->di_format
, size
, lino
);
1850 if (size
> XFS_DIR2_LEAF_OFFSET
) {
1851 do_warn(_("directory inode %llu has bad size %lld\n"),
1857 case XR_INO_SYMLINK
:
1858 if (process_symlink_extlist(mp
, lino
, dino
)) {
1859 do_warn(_("bad data fork in symlink %llu\n"), lino
);
1864 case XR_INO_CHRDEV
: /* fall through to FIFO case ... */
1865 case XR_INO_BLKDEV
: /* fall through to FIFO case ... */
1866 case XR_INO_SOCK
: /* fall through to FIFO case ... */
1867 case XR_INO_MOUNTPOINT
: /* fall through to FIFO case ... */
1869 if (process_misc_ino_types(mp
, dino
, lino
, type
))
1875 * if we have no realtime blocks, any inode claiming
1876 * to be a real-time file is bogus
1878 if (mp
->m_sb
.sb_rblocks
== 0) {
1879 do_warn(_("found inode %llu claiming to be a "
1880 "real-time file\n"), lino
);
1885 case XR_INO_RTBITMAP
:
1886 if (size
!= (__int64_t
)mp
->m_sb
.sb_rbmblocks
*
1887 mp
->m_sb
.sb_blocksize
) {
1888 do_warn(_("realtime bitmap inode %llu has bad size "
1889 "%lld (should be %lld)\n"),
1890 lino
, size
, (__int64_t
) mp
->m_sb
.sb_rbmblocks
*
1891 mp
->m_sb
.sb_blocksize
);
1897 if (size
!= mp
->m_rsumsize
) {
1898 do_warn(_("realtime summary inode %llu has bad size "
1899 "%lld (should be %d)\n"),
1900 lino
, size
, mp
->m_rsumsize
);
1912 * check for illegal values of forkoff
1915 process_check_inode_forkoff(
1917 xfs_dinode_core_t
*dinoc
,
1920 if (dinoc
->di_forkoff
== 0)
1923 switch (dinoc
->di_format
) {
1924 case XFS_DINODE_FMT_DEV
:
1925 if (dinoc
->di_forkoff
!= (roundup(sizeof(xfs_dev_t
), 8) >> 3)) {
1926 do_warn(_("bad attr fork offset %d in dev inode %llu, "
1927 "should be %d\n"), dinoc
->di_forkoff
, lino
,
1928 (int)(roundup(sizeof(xfs_dev_t
), 8) >> 3));
1932 case XFS_DINODE_FMT_LOCAL
: /* fall through ... */
1933 case XFS_DINODE_FMT_EXTENTS
: /* fall through ... */
1934 case XFS_DINODE_FMT_BTREE
:
1935 if (dinoc
->di_forkoff
>= (XFS_LITINO(mp
) >> 3)) {
1936 do_warn(_("bad attr fork offset %d in inode %llu, "
1937 "max=%d\n"), dinoc
->di_forkoff
, lino
,
1938 XFS_LITINO(mp
) >> 3);
1943 do_error(_("unexpected inode format %d\n"), dinoc
->di_format
);
1950 * Updates the inodes block and extent counts if they are wrong
1953 process_inode_blocks_and_extents(
1954 xfs_dinode_core_t
*dinoc
,
1955 xfs_drfsbno_t nblocks
,
1956 __uint64_t nextents
,
1957 __uint64_t anextents
,
1961 if (nblocks
!= be64_to_cpu(dinoc
->di_nblocks
)) {
1963 do_warn(_("correcting nblocks for inode %llu, "
1964 "was %llu - counted %llu\n"), lino
,
1965 be64_to_cpu(dinoc
->di_nblocks
), nblocks
);
1966 dinoc
->di_nblocks
= cpu_to_be64(nblocks
);
1969 do_warn(_("bad nblocks %llu for inode %llu, "
1970 "would reset to %llu\n"),
1971 be64_to_cpu(dinoc
->di_nblocks
), lino
, nblocks
);
1975 if (nextents
> MAXEXTNUM
) {
1976 do_warn(_("too many data fork extents (%llu) in inode %llu\n"),
1980 if (nextents
!= be32_to_cpu(dinoc
->di_nextents
)) {
1982 do_warn(_("correcting nextents for inode %llu, "
1983 "was %d - counted %llu\n"), lino
,
1984 be32_to_cpu(dinoc
->di_nextents
), nextents
);
1985 dinoc
->di_nextents
= cpu_to_be32(nextents
);
1988 do_warn(_("bad nextents %d for inode %llu, would reset "
1989 "to %llu\n"), be32_to_cpu(dinoc
->di_nextents
),
1994 if (anextents
> MAXAEXTNUM
) {
1995 do_warn(_("too many attr fork extents (%llu) in inode %llu\n"),
1999 if (anextents
!= be16_to_cpu(dinoc
->di_anextents
)) {
2001 do_warn(_("correcting anextents for inode %llu, "
2002 "was %d - counted %llu\n"), lino
,
2003 be16_to_cpu(dinoc
->di_anextents
), anextents
);
2004 dinoc
->di_anextents
= cpu_to_be16(anextents
);
2007 do_warn(_("bad anextents %d for inode %llu, would reset"
2008 " to %llu\n"), be16_to_cpu(dinoc
->di_anextents
),
2016 * check data fork -- if it's bad, clear the inode
2019 process_inode_data_fork(
2021 xfs_agnumber_t agno
,
2026 xfs_drfsbno_t
*totblocks
,
2027 __uint64_t
*nextents
,
2031 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
2032 xfs_ino_t lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2035 *nextents
= be32_to_cpu(dinoc
->di_nextents
);
2036 if (*nextents
> be64_to_cpu(dinoc
->di_nblocks
))
2039 if (dinoc
->di_format
!= XFS_DINODE_FMT_LOCAL
&& type
!= XR_INO_RTDATA
)
2040 *dblkmap
= blkmap_alloc(*nextents
);
2043 switch (dinoc
->di_format
) {
2044 case XFS_DINODE_FMT_LOCAL
:
2045 err
= process_lclinode(mp
, agno
, ino
, dino
, XFS_DATA_FORK
);
2048 case XFS_DINODE_FMT_EXTENTS
:
2049 err
= process_exinode(mp
, agno
, ino
, dino
, type
, dirty
,
2050 totblocks
, nextents
, dblkmap
, XFS_DATA_FORK
,
2053 case XFS_DINODE_FMT_BTREE
:
2054 err
= process_btinode(mp
, agno
, ino
, dino
, type
, dirty
,
2055 totblocks
, nextents
, dblkmap
, XFS_DATA_FORK
,
2058 case XFS_DINODE_FMT_DEV
: /* fall through */
2062 do_error(_("unknown format %d, ino %llu (mode = %d)\n"),
2063 dinoc
->di_format
, lino
, be16_to_cpu(dinoc
->di_mode
));
2067 do_warn(_("bad data fork in inode %llu\n"), lino
);
2069 *dirty
+= clear_dinode(mp
, dino
, lino
);
2077 * if check_dups was non-zero, we have to
2078 * re-process data fork to set bitmap since the
2079 * bitmap wasn't set the first time through
2081 switch (dinoc
->di_format
) {
2082 case XFS_DINODE_FMT_LOCAL
:
2083 err
= process_lclinode(mp
, agno
, ino
, dino
,
2086 case XFS_DINODE_FMT_EXTENTS
:
2087 err
= process_exinode(mp
, agno
, ino
, dino
, type
,
2088 dirty
, totblocks
, nextents
, dblkmap
,
2091 case XFS_DINODE_FMT_BTREE
:
2092 err
= process_btinode(mp
, agno
, ino
, dino
, type
,
2093 dirty
, totblocks
, nextents
, dblkmap
,
2096 case XFS_DINODE_FMT_DEV
: /* fall through */
2100 do_error(_("unknown format %d, ino %llu (mode = %d)\n"),
2101 dinoc
->di_format
, lino
,
2102 be16_to_cpu(dinoc
->di_mode
));
2105 if (no_modify
&& err
!= 0)
2114 * Process extended attribute fork in inode
2117 process_inode_attr_fork(
2119 xfs_agnumber_t agno
,
2124 xfs_drfsbno_t
*atotblocks
,
2125 __uint64_t
*anextents
,
2127 int extra_attr_check
,
2130 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
2131 xfs_ino_t lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2132 blkmap_t
*ablkmap
= NULL
;
2136 if (!XFS_DFORK_Q(dino
)) {
2138 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
2139 do_warn(_("bad attribute format %d in inode %llu, "),
2140 dinoc
->di_aformat
, lino
);
2142 do_warn(_("resetting value\n"));
2143 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
2146 do_warn(_("would reset value\n"));
2151 *anextents
= be16_to_cpu(dinoc
->di_anextents
);
2152 if (*anextents
> be64_to_cpu(dinoc
->di_nblocks
))
2155 switch (dinoc
->di_aformat
) {
2156 case XFS_DINODE_FMT_LOCAL
:
2159 err
= process_lclinode(mp
, agno
, ino
, dino
, XFS_ATTR_FORK
);
2161 case XFS_DINODE_FMT_EXTENTS
:
2162 ablkmap
= blkmap_alloc(*anextents
);
2164 err
= process_exinode(mp
, agno
, ino
, dino
, type
, dirty
,
2165 atotblocks
, anextents
, &ablkmap
,
2166 XFS_ATTR_FORK
, check_dups
);
2168 case XFS_DINODE_FMT_BTREE
:
2169 ablkmap
= blkmap_alloc(*anextents
);
2171 err
= process_btinode(mp
, agno
, ino
, dino
, type
, dirty
,
2172 atotblocks
, anextents
, &ablkmap
,
2173 XFS_ATTR_FORK
, check_dups
);
2176 do_warn(_("illegal attribute format %d, ino %llu\n"),
2177 dinoc
->di_aformat
, lino
);
2184 * clear the attribute fork if necessary. we can't
2185 * clear the inode because we've already put the
2186 * inode space info into the blockmap.
2188 * XXX - put the inode onto the "move it" list and
2189 * log the the attribute scrubbing
2191 do_warn(_("bad attribute fork in inode %llu"), lino
);
2194 if (delete_attr_ok
) {
2195 do_warn(_(", clearing attr fork\n"));
2196 *dirty
+= clear_dinode_attr(mp
, dino
, lino
);
2197 dinoc
->di_aformat
= XFS_DINODE_FMT_LOCAL
;
2200 *dirty
+= clear_dinode(mp
, dino
, lino
);
2204 do_warn(_(", would clear attr fork\n"));
2209 blkmap_free(ablkmap
);
2212 return delete_attr_ok
? 0 : 1;
2216 switch (dinoc
->di_aformat
) {
2217 case XFS_DINODE_FMT_LOCAL
:
2218 err
= process_lclinode(mp
, agno
, ino
, dino
,
2221 case XFS_DINODE_FMT_EXTENTS
:
2222 err
= process_exinode(mp
, agno
, ino
, dino
,
2223 type
, dirty
, atotblocks
, anextents
,
2224 &ablkmap
, XFS_ATTR_FORK
, 0);
2226 case XFS_DINODE_FMT_BTREE
:
2227 err
= process_btinode(mp
, agno
, ino
, dino
,
2228 type
, dirty
, atotblocks
, anextents
,
2229 &ablkmap
, XFS_ATTR_FORK
, 0);
2232 do_error(_("illegal attribute fmt %d, ino %llu\n"),
2233 dinoc
->di_aformat
, lino
);
2236 if (no_modify
&& err
!= 0) {
2237 blkmap_free(ablkmap
);
2245 * do attribute semantic-based consistency checks now
2248 /* get this only in phase 3, not in both phase 3 and 4 */
2249 if (extra_attr_check
&&
2250 process_attributes(mp
, lino
, dino
, ablkmap
, &repair
)) {
2251 do_warn(_("problem with attribute contents in inode %llu\n"),
2254 /* clear attributes if not done already */
2256 *dirty
+= clear_dinode_attr(mp
, dino
, lino
);
2257 dinoc
->di_aformat
= XFS_DINODE_FMT_LOCAL
;
2259 do_warn(_("would clear attr fork\n"));
2265 *dirty
= 1; /* it's been repaired */
2268 blkmap_free(ablkmap
);
2273 * check nlinks feature, if it's a version 1 inode,
2274 * just leave nlinks alone. even if it's set wrong,
2275 * it'll be reset when read in.
2279 process_check_inode_nlink_version(
2280 xfs_dinode_core_t
*dinoc
,
2285 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&& !fs_inode_nlink
) {
2287 * do we have a fs/inode version mismatch with a valid
2288 * version 2 inode here that has to stay version 2 or
2291 if (be32_to_cpu(dinoc
->di_nlink
) > XFS_MAXLINK_1
) {
2293 * yes. are nlink inodes allowed?
2295 if (fs_inode_nlink_allowed
) {
2297 * yes, update status variable which will
2298 * cause sb to be updated later.
2301 do_warn(_("version 2 inode %llu claims > %u links, "),
2302 lino
, XFS_MAXLINK_1
);
2304 do_warn(_("updating superblock "
2305 "version number\n"));
2307 do_warn(_("would update superblock "
2308 "version number\n"));
2312 * no, have to convert back to onlinks
2313 * even if we lose some links
2315 do_warn(_("WARNING: version 2 inode %llu "
2316 "claims > %u links, "),
2317 lino
, XFS_MAXLINK_1
);
2319 do_warn(_("converting back to version 1,\n"
2320 "this may destroy %d links\n"),
2321 be32_to_cpu(dinoc
->di_nlink
) -
2324 dinoc
->di_version
= XFS_DINODE_VERSION_1
;
2325 dinoc
->di_nlink
= cpu_to_be32(XFS_MAXLINK_1
);
2326 dinoc
->di_onlink
= cpu_to_be16(XFS_MAXLINK_1
);
2329 do_warn(_("would convert back to version 1,\n"
2330 "\tthis might destroy %d links\n"),
2331 be32_to_cpu(dinoc
->di_nlink
) -
2337 * do we have a v2 inode that we could convert back
2338 * to v1 without losing any links? if we do and
2339 * we have a mismatch between superblock bits and the
2340 * version bit, alter the version bit in this case.
2342 * the case where we lost links was handled above.
2344 do_warn(_("found version 2 inode %llu, "), lino
);
2346 do_warn(_("converting back to version 1\n"));
2347 dinoc
->di_version
= XFS_DINODE_VERSION_1
;
2348 dinoc
->di_onlink
= cpu_to_be16(
2349 be32_to_cpu(dinoc
->di_nlink
));
2352 do_warn(_("would convert back to version 1\n"));
2358 * ok, if it's still a version 2 inode, it's going
2359 * to stay a version 2 inode. it should have a zero
2360 * onlink field, so clear it.
2362 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&&
2363 dinoc
->di_onlink
!= 0 && fs_inode_nlink
> 0) {
2365 do_warn(_("clearing obsolete nlink field in "
2366 "version 2 inode %llu, was %d, now 0\n"),
2367 lino
, be16_to_cpu(dinoc
->di_onlink
));
2368 dinoc
->di_onlink
= 0;
2371 do_warn(_("would clear obsolete nlink field in "
2372 "version 2 inode %llu, currently %d\n"),
2373 lino
, be16_to_cpu(dinoc
->di_onlink
));
2380 * returns 0 if the inode is ok, 1 if the inode is corrupt
2381 * check_dups can be set to 1 *only* when called by the
2382 * first pass of the duplicate block checking of phase 4.
2383 * *dirty is set > 0 if the dinode has been altered and
2384 * needs to be written out.
2386 * for detailed, info, look at process_dinode() comments.
2390 process_dinode_int(xfs_mount_t
*mp
,
2392 xfs_agnumber_t agno
,
2394 int was_free
, /* 1 if inode is currently free */
2395 int *dirty
, /* out == > 0 if inode is now dirty */
2396 int *used
, /* out == 1 if inode is in use */
2397 int verify_mode
, /* 1 == verify but don't modify inode */
2398 int uncertain
, /* 1 == inode is uncertain */
2399 int ino_discovery
, /* 1 == check dirs for unknown inodes */
2400 int check_dups
, /* 1 == check if inode claims
2401 * duplicate blocks */
2402 int extra_attr_check
, /* 1 == do attribute format and value checks */
2403 int *isa_dir
, /* out == 1 if inode is a directory */
2404 xfs_ino_t
*parent
) /* out -- parent if ino is a dir */
2406 xfs_drfsbno_t totblocks
= 0;
2407 xfs_drfsbno_t atotblocks
= 0;
2408 xfs_dinode_core_t
*dinoc
;
2412 __uint64_t nextents
;
2413 __uint64_t anextents
;
2415 const int is_free
= 0;
2416 const int is_used
= 1;
2417 blkmap_t
*dblkmap
= NULL
;
2419 *dirty
= *isa_dir
= 0;
2421 type
= XR_INO_UNKNOWN
;
2423 dinoc
= &dino
->di_core
;
2424 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2425 di_mode
= be16_to_cpu(dinoc
->di_mode
);
2428 * if in verify mode, don't modify the inode.
2430 * if correcting, reset stuff that has known values
2432 * if in uncertain mode, be silent on errors since we're
2433 * trying to find out if these are inodes as opposed
2434 * to assuming that they are. Just return the appropriate
2435 * return code in that case.
2437 * If uncertain is set, verify_mode MUST be set.
2439 ASSERT(uncertain
== 0 || verify_mode
!= 0);
2441 if (be16_to_cpu(dinoc
->di_magic
) != XFS_DINODE_MAGIC
) {
2444 do_warn(_("bad magic number 0x%x on inode %llu%c"),
2445 be16_to_cpu(dinoc
->di_magic
), lino
,
2446 verify_mode
? '\n' : ',');
2449 do_warn(_(" resetting magic number\n"));
2450 dinoc
->di_magic
= cpu_to_be16(XFS_DINODE_MAGIC
);
2453 do_warn(_(" would reset magic number\n"));
2457 if (!XFS_DINODE_GOOD_VERSION(dinoc
->di_version
) ||
2458 (!fs_inode_nlink
&& dinoc
->di_version
> XFS_DINODE_VERSION_1
)) {
2461 do_warn(_("bad version number 0x%x on inode %llu%c"),
2462 (__s8
)dinoc
->di_version
, lino
,
2463 verify_mode
? '\n' : ',');
2466 do_warn(_(" resetting version number\n"));
2467 dinoc
->di_version
= (fs_inode_nlink
) ?
2468 XFS_DINODE_VERSION_2
:
2469 XFS_DINODE_VERSION_1
;
2472 do_warn(_(" would reset version number\n"));
2477 * blow out of here if the inode size is < 0
2479 if ((xfs_fsize_t
)be64_to_cpu(dinoc
->di_size
) < 0) {
2481 do_warn(_("bad (negative) size %lld on inode %llu\n"),
2482 be64_to_cpu(dinoc
->di_size
), lino
);
2489 * if not in verify mode, check to sii if the inode and imap
2490 * agree that the inode is free
2492 if (!verify_mode
&& di_mode
== 0) {
2494 * was_free value is not meaningful if we're in verify mode
2498 * easy case, inode free -- inode and map agree, clear
2499 * it just in case to ensure that format, etc. are
2503 *dirty
+= clear_dinode(mp
, dino
, lino
);
2508 * the inode looks free but the map says it's in use.
2509 * clear the inode just to be safe and mark the inode
2512 do_warn(_("imap claims a free inode %llu is in use, "), lino
);
2514 do_warn(_("correcting imap and clearing inode\n"));
2515 *dirty
+= clear_dinode(mp
, dino
, lino
);
2518 do_warn(_("would correct imap and clear inode\n"));
2524 * because of the lack of any write ordering guarantee, it's
2525 * possible that the core got updated but the forks didn't.
2526 * so rather than be ambitious (and probably incorrect),
2527 * if there's an inconsistency, we get conservative and
2528 * just pitch the file. blow off checking formats of
2529 * free inodes since technically any format is legal
2530 * as we reset the inode when we re-use it.
2532 if (di_mode
!= 0 && check_dinode_mode_format(dinoc
) != 0) {
2534 do_warn(_("bad inode format in inode %llu\n"), lino
);
2544 * clear the next unlinked field if necessary on a good
2545 * inode only during phase 4 -- when checking for inodes
2546 * referencing duplicate blocks. then it's safe because
2547 * we've done the inode discovery and have found all the inodes
2548 * we're going to find. check_dups is set to 1 only during
2551 if (check_dups
&& !no_modify
)
2552 *dirty
+= clear_dinode_unlinked(mp
, dino
);
2554 /* set type and map type info */
2556 switch (di_mode
& S_IFMT
) {
2562 if (be16_to_cpu(dinoc
->di_flags
) & XFS_DIFLAG_REALTIME
)
2563 type
= XR_INO_RTDATA
;
2564 else if (lino
== mp
->m_sb
.sb_rbmino
)
2565 type
= XR_INO_RTBITMAP
;
2566 else if (lino
== mp
->m_sb
.sb_rsumino
)
2567 type
= XR_INO_RTSUM
;
2572 type
= XR_INO_SYMLINK
;
2575 type
= XR_INO_CHRDEV
;
2578 type
= XR_INO_BLKDEV
;
2587 do_warn(_("bad inode type %#o inode %llu\n"),
2588 di_mode
& S_IFMT
, lino
);
2593 * type checks for superblock inodes
2595 if (process_check_sb_inodes(mp
, dinoc
, lino
, &type
, dirty
) != 0)
2599 * only regular files with REALTIME or EXTSIZE flags set can have
2600 * extsize set, or directories with EXTSZINHERIT.
2602 if (be32_to_cpu(dinoc
->di_extsize
) != 0) {
2603 if ((type
== XR_INO_RTDATA
) ||
2604 (type
== XR_INO_DIR
&& (be16_to_cpu(dinoc
->di_flags
) &
2605 XFS_DIFLAG_EXTSZINHERIT
)) ||
2606 (type
== XR_INO_DATA
&& (be16_to_cpu(dinoc
->di_flags
) &
2607 XFS_DIFLAG_EXTSIZE
))) {
2610 do_warn(_("bad non-zero extent size %u for "
2611 "non-realtime/extsize inode %llu, "),
2612 be32_to_cpu(dinoc
->di_extsize
), lino
);
2614 do_warn(_("resetting to zero\n"));
2615 dinoc
->di_extsize
= 0;
2618 do_warn(_("would reset to zero\n"));
2623 * general size/consistency checks:
2625 if (process_check_inode_sizes(mp
, dino
, lino
, type
) != 0)
2629 * check for illegal values of forkoff
2631 if (process_check_inode_forkoff(mp
, dinoc
, lino
) != 0)
2635 * check data fork -- if it's bad, clear the inode
2637 if (process_inode_data_fork(mp
, agno
, ino
, dino
, type
, dirty
,
2638 &totblocks
, &nextents
, &dblkmap
, check_dups
) != 0)
2642 * check attribute fork if necessary. attributes are
2643 * always stored in the regular filesystem.
2645 if (process_inode_attr_fork(mp
, agno
, ino
, dino
, type
, dirty
,
2646 &atotblocks
, &anextents
, check_dups
, extra_attr_check
,
2651 * enforce totblocks is 0 for misc types
2653 if (process_misc_ino_types_blocks(totblocks
, lino
, type
))
2657 * correct space counters if required
2659 if (process_inode_blocks_and_extents(dinoc
, totblocks
+ atotblocks
,
2660 nextents
, anextents
, lino
, dirty
) != 0)
2664 * do any semantic type-based checking here
2668 if (xfs_sb_version_hasdirv2(&mp
->m_sb
) ?
2669 process_dir2(mp
, lino
, dino
, ino_discovery
,
2670 dirty
, "", parent
, dblkmap
) :
2671 process_dir(mp
, lino
, dino
, ino_discovery
,
2672 dirty
, "", parent
, dblkmap
)) {
2673 do_warn(_("problem with directory contents in "
2674 "inode %llu\n"), lino
);
2678 case XR_INO_SYMLINK
:
2679 if (process_symlink(mp
, lino
, dino
, dblkmap
) != 0) {
2680 do_warn(_("problem with symbolic link in inode %llu\n"),
2690 blkmap_free(dblkmap
);
2693 * check nlinks feature, if it's a version 1 inode,
2694 * just leave nlinks alone. even if it's set wrong,
2695 * it'll be reset when read in.
2697 *dirty
+= process_check_inode_nlink_version(dinoc
, lino
);
2703 *dirty
+= clear_dinode(mp
, dino
, lino
);
2710 blkmap_free(dblkmap
);
2715 * returns 1 if inode is used, 0 if free.
2716 * performs any necessary salvaging actions.
2717 * note that we leave the generation count alone
2718 * because nothing we could set it to would be
2719 * guaranteed to be correct so the best guess for
2720 * the correct value is just to leave it alone.
2722 * The trick is detecting empty files. For those,
2723 * the core and the forks should all be in the "empty"
2724 * or zero-length state -- a zero or possibly minimum length
2725 * (in the case of dirs) extent list -- although inline directories
2726 * and symlinks might be handled differently. So it should be
2727 * possible to sanity check them against each other.
2729 * If the forks are an empty extent list though, then forget it.
2730 * The file is toast anyway since we can't recover its storage.
2734 * mp -- mount structure
2735 * dino -- pointer to on-disk inode structure
2736 * agno/ino -- inode numbers
2737 * free -- whether the map thinks the inode is free (1 == free)
2738 * ino_discovery -- whether we should examine directory
2739 * contents to discover new inodes
2740 * check_dups -- whether we should check to see if the
2741 * inode references duplicate blocks
2742 * if so, we compare the inode's claimed
2743 * blocks against the contents of the
2744 * duplicate extent list but we don't
2745 * set the bitmap. If not, we set the
2746 * bitmap and try and detect multiply
2747 * claimed blocks using the bitmap.
2749 * dirty -- whether we changed the inode (1 == yes)
2750 * used -- 1 if the inode is used, 0 if free. In no modify
2751 * mode, whether the inode should be used or free
2752 * isa_dir -- 1 if the inode is a directory, 0 if not. In
2753 * no modify mode, if the inode would be a dir or not.
2755 * Return value -- 0 if the inode is good, 1 if it is/was corrupt
2762 xfs_agnumber_t agno
,
2769 int extra_attr_check
,
2773 const int verify_mode
= 0;
2774 const int uncertain
= 0;
2776 #ifdef XR_INODE_TRACE
2777 fprintf(stderr
, _("processing inode %d/%d\n"), agno
, ino
);
2779 return process_dinode_int(mp
, dino
, agno
, ino
, was_free
, dirty
, used
,
2780 verify_mode
, uncertain
, ino_discovery
,
2781 check_dups
, extra_attr_check
, isa_dir
, parent
);
2785 * a more cursory check, check inode core, *DON'T* check forks
2786 * this basically just verifies whether the inode is an inode
2787 * and whether or not it has been totally trashed. returns 0
2788 * if the inode passes the cursory sanity check, 1 otherwise.
2794 xfs_agnumber_t agno
,
2801 const int verify_mode
= 1;
2802 const int check_dups
= 0;
2803 const int ino_discovery
= 0;
2804 const int uncertain
= 0;
2806 return process_dinode_int(mp
, dino
, agno
, ino
, 0, &dirty
, &used
,
2807 verify_mode
, uncertain
, ino_discovery
,
2808 check_dups
, 0, &isa_dir
, &parent
);
2812 * like above only for inode on the uncertain list. it sets
2813 * the uncertain flag which makes process_dinode_int quieter.
2814 * returns 0 if the inode passes the cursory sanity check, 1 otherwise.
2817 verify_uncertain_dinode(
2820 xfs_agnumber_t agno
,
2827 const int verify_mode
= 1;
2828 const int check_dups
= 0;
2829 const int ino_discovery
= 0;
2830 const int uncertain
= 1;
2832 return process_dinode_int(mp
, dino
, agno
, ino
, 0, &dirty
, &used
,
2833 verify_mode
, uncertain
, ino_discovery
,
2834 check_dups
, 0, &isa_dir
, &parent
);