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
+= INT_GET(dinoc
->di_size
, ARCH_CONVERT
);
61 case XFS_DINODE_FMT_EXTENTS
:
62 offset
+= INT_GET(dinoc
->di_nextents
, ARCH_CONVERT
) * sizeof(xfs_bmbt_rec_32_t
);
64 case XFS_DINODE_FMT_BTREE
:
65 offset
+= INT_GET(dino
->di_u
.di_bmbt
.bb_numrecs
, ARCH_CONVERT
) * sizeof(xfs_bmbt_rec_32_t
);
68 do_error(_("Unknown inode format.\n"));
78 clear_dinode_attr(xfs_mount_t
*mp
, xfs_dinode_t
*dino
, xfs_ino_t ino_num
)
80 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
82 ASSERT(dinoc
->di_forkoff
!= 0);
85 fprintf(stderr
, _("clearing inode %llu attributes\n"),
86 (unsigned long long)ino_num
);
88 fprintf(stderr
, _("would have cleared inode %llu attributes\n"),
89 (unsigned long long)ino_num
);
91 if (INT_GET(dinoc
->di_anextents
, ARCH_CONVERT
) != 0) {
94 dinoc
->di_anextents
= 0;
97 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
100 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
103 /* get rid of the fork by clearing forkoff */
105 /* Originally, when the attr repair code was added, the fork was cleared
106 * by turning it into shortform status. This meant clearing the
107 * hdr.totsize/count fields and also changing aformat to LOCAL
108 * (vs EXTENTS). Over various fixes, the aformat and forkoff have
109 * been updated to not show an attribute fork at all, however.
110 * It could be possible that resetting totsize/count are not needed,
111 * but just to be safe, leave it in for now.
115 xfs_attr_shortform_t
*asf
= (xfs_attr_shortform_t
*)
116 XFS_DFORK_APTR(dino
);
117 INT_SET(asf
->hdr
.totsize
, ARCH_CONVERT
,
118 sizeof(xfs_attr_sf_hdr_t
));
119 INT_SET(asf
->hdr
.count
, ARCH_CONVERT
, 0);
120 dinoc
->di_forkoff
= 0; /* got to do this after asf is set */
124 * always returns 1 since the fork gets zapped
131 clear_dinode_core(xfs_dinode_core_t
*dinoc
, xfs_ino_t ino_num
)
135 if (INT_GET(dinoc
->di_magic
, ARCH_CONVERT
) != XFS_DINODE_MAGIC
) {
141 INT_SET(dinoc
->di_magic
, ARCH_CONVERT
, XFS_DINODE_MAGIC
);
144 if (!XFS_DINODE_GOOD_VERSION(dinoc
->di_version
) ||
145 (!fs_inode_nlink
&& dinoc
->di_version
> XFS_DINODE_VERSION_1
)) {
151 dinoc
->di_version
= (fs_inode_nlink
) ? XFS_DINODE_VERSION_2
152 : XFS_DINODE_VERSION_1
;
155 if (INT_GET(dinoc
->di_mode
, ARCH_CONVERT
) != 0) {
164 if (INT_GET(dinoc
->di_flags
, ARCH_CONVERT
) != 0) {
173 if (INT_GET(dinoc
->di_dmevmask
, ARCH_CONVERT
) != 0) {
179 dinoc
->di_dmevmask
= 0;
182 if (dinoc
->di_forkoff
!= 0) {
188 dinoc
->di_forkoff
= 0;
191 if (dinoc
->di_format
!= XFS_DINODE_FMT_EXTENTS
) {
197 dinoc
->di_format
= XFS_DINODE_FMT_EXTENTS
;
200 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
206 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
209 if (INT_GET(dinoc
->di_size
, ARCH_CONVERT
) != 0) {
218 if (INT_GET(dinoc
->di_nblocks
, ARCH_CONVERT
) != 0) {
224 dinoc
->di_nblocks
= 0;
227 if (INT_GET(dinoc
->di_onlink
, ARCH_CONVERT
) != 0) {
233 dinoc
->di_onlink
= 0;
236 if (INT_GET(dinoc
->di_nextents
, ARCH_CONVERT
) != 0) {
242 dinoc
->di_nextents
= 0;
245 if (INT_GET(dinoc
->di_anextents
, ARCH_CONVERT
) != 0) {
251 dinoc
->di_anextents
= 0;
254 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&&
255 INT_GET(dinoc
->di_nlink
, ARCH_CONVERT
) != 0) {
269 clear_dinode_unlinked(xfs_mount_t
*mp
, xfs_dinode_t
*dino
)
272 if (dino
->di_next_unlinked
!= NULLAGINO
) {
274 dino
->di_next_unlinked
= NULLAGINO
;
282 * this clears the unlinked list too so it should not be called
283 * until after the agi unlinked lists are walked in phase 3.
284 * returns > zero if the inode has been altered while being cleared
287 clear_dinode(xfs_mount_t
*mp
, xfs_dinode_t
*dino
, xfs_ino_t ino_num
)
291 dirty
= clear_dinode_core(&dino
->di_core
, ino_num
);
292 dirty
+= clear_dinode_unlinked(mp
, dino
);
294 /* and clear the forks */
296 if (dirty
&& !no_modify
)
297 memset(&dino
->di_u
, 0, XFS_LITINO(mp
));
304 * misc. inode-related utility routines
308 * verify_ag_bno is heavily used. In the common case, it
309 * performs just two number of compares
312 verify_ag_bno(xfs_sb_t
*sbp
,
316 if (agno
< (sbp
->sb_agcount
- 1)) {
317 if (agbno
>= sbp
->sb_agblocks
) {
322 if (agno
== (sbp
->sb_agcount
- 1)) {
325 (sbp
->sb_agcount
-1) *
335 * returns 0 if inode number is valid, 1 if bogus
338 verify_inum(xfs_mount_t
*mp
,
344 xfs_sb_t
*sbp
= &mp
->m_sb
;;
346 /* range check ag #, ag block. range-checking offset is pointless */
348 agno
= XFS_INO_TO_AGNO(mp
, ino
);
349 agino
= XFS_INO_TO_AGINO(mp
, ino
);
350 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
354 if (ino
== 0 || ino
== NULLFSINO
)
357 if (ino
!= XFS_AGINO_TO_INO(mp
, agno
, agino
))
360 return verify_ag_bno(sbp
, agno
, agbno
);
364 * have a separate routine to ensure that we don't accidentally
365 * lose illegally set bits in the agino by turning it into an FSINO
366 * to feed to the above routine
369 verify_aginum(xfs_mount_t
*mp
,
374 xfs_sb_t
*sbp
= &mp
->m_sb
;;
376 /* range check ag #, ag block. range-checking offset is pointless */
378 if (agino
== 0 || agino
== NULLAGINO
)
382 * agino's can't be too close to NULLAGINO because the min blocksize
383 * is 9 bits and at most 1 bit of that gets used for the inode offset
384 * so if the agino gets shifted by the # of offset bits and compared
385 * to the legal agbno values, a bogus agino will be too large. there
386 * will be extra bits set at the top that shouldn't be set.
388 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
392 return verify_ag_bno(sbp
, agno
, agbno
);
396 * return 1 if block number is good, 0 if out of range
399 verify_dfsbno(xfs_mount_t
*mp
,
404 xfs_sb_t
*sbp
= &mp
->m_sb
;;
406 /* range check ag #, ag block. range-checking offset is pointless */
408 agno
= XFS_FSB_TO_AGNO(mp
, fsbno
);
409 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
);
411 return verify_ag_bno(sbp
, agno
, agbno
) == 0;
414 #define XR_DFSBNORANGE_VALID 0
415 #define XR_DFSBNORANGE_BADSTART 1
416 #define XR_DFSBNORANGE_BADEND 2
417 #define XR_DFSBNORANGE_OVERFLOW 3
420 verify_dfsbno_range(xfs_mount_t
*mp
,
422 xfs_dfilblks_t count
)
426 xfs_sb_t
*sbp
= &mp
->m_sb
;;
428 /* the start and end blocks better be in the same allocation group */
429 agno
= XFS_FSB_TO_AGNO(mp
, fsbno
);
430 if (agno
!= XFS_FSB_TO_AGNO(mp
, fsbno
+ count
- 1)) {
431 return XR_DFSBNORANGE_OVERFLOW
;
434 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
);
435 if (verify_ag_bno(sbp
, agno
, agbno
)) {
436 return XR_DFSBNORANGE_BADSTART
;
439 agbno
= XFS_FSB_TO_AGBNO(mp
, fsbno
+ count
- 1);
440 if (verify_ag_bno(sbp
, agno
, agbno
)) {
441 return XR_DFSBNORANGE_BADEND
;
444 return (XR_DFSBNORANGE_VALID
);
448 verify_agbno(xfs_mount_t
*mp
,
452 xfs_sb_t
*sbp
= &mp
->m_sb
;;
454 /* range check ag #, ag block. range-checking offset is pointless */
455 return verify_ag_bno(sbp
, agno
, agbno
) == 0;
460 xfs_bmbt_rec_32_t
*rp
,
461 xfs_dfiloff_t
*op
, /* starting offset (blockno in file) */
462 xfs_dfsbno_t
*sp
, /* starting block (fs blockno) */
463 xfs_dfilblks_t
*cp
, /* blockcount */
464 int *fp
) /* extent flag */
466 xfs_bmbt_irec_t irec
, *s
= &irec
;
467 xfs_bmbt_rec_t rpcopy
, *p
= &rpcopy
;
469 memcpy(&rpcopy
, rp
, sizeof(rpcopy
));
470 /* Just use the extent parsing routine from the kernel */
471 libxfs_bmbt_disk_get_all(p
, s
);
473 if (fs_has_extflgbit
) {
474 if (s
->br_state
== XFS_EXT_UNWRITTEN
) {
482 *op
= s
->br_startoff
;
483 *sp
= s
->br_startblock
;
484 *cp
= s
->br_blockcount
;
488 * return address of block fblock if it's within the range described
489 * by the extent list. Otherwise, returns a null address.
495 xfs_bmbt_rec_32_t
*rp
,
497 xfs_dfiloff_t fblock
)
501 xfs_dfiloff_t off_bno
;
505 for (i
= 0; i
< numrecs
; i
++, rp
++) {
506 convert_extent(rp
, &off_bno
, &start
, &cnt
, &flag
);
507 if (off_bno
>= fblock
&& off_bno
+ cnt
< fblock
)
508 return(start
+ fblock
- off_bno
);
518 xfs_bmbt_rec_32_t
*rp
,
525 xfs_dfilblks_t c
; /* count */
526 xfs_dfsbno_t s
; /* start */
527 xfs_dfiloff_t o
; /* offset */
529 int flag
; /* extent flag */
530 int pwe
; /* partially-written extent */
532 convert_extent(rp
, &o
, &s
, &c
, &flag
);
535 * check numeric validity of the extent
537 if (s
>= mp
->m_sb
.sb_rblocks
) {
538 do_warn(_("inode %llu - bad rt extent start block number "
539 "%llu, offset %llu\n"), ino
, s
, o
);
542 if (s
+ c
- 1 >= mp
->m_sb
.sb_rblocks
) {
543 do_warn(_("inode %llu - bad rt extent last block number %llu, "
544 "offset %llu\n"), ino
, s
+ c
- 1, o
);
548 do_warn(_("inode %llu - bad rt extent overflows - start %llu, "
549 "end %llu, offset %llu\n"),
550 ino
, s
, s
+ c
- 1, o
);
555 * verify that the blocks listed in the record
556 * are multiples of an extent
558 if (XFS_SB_VERSION_HASEXTFLGBIT(&mp
->m_sb
) == 0 &&
559 (s
% mp
->m_sb
.sb_rextsize
!= 0 ||
560 c
% mp
->m_sb
.sb_rextsize
!= 0)) {
561 do_warn(_("malformed rt inode extent [%llu %llu] (fs rtext "
562 "size = %u)\n"), s
, c
, mp
->m_sb
.sb_rextsize
);
567 * set the appropriate number of extents
569 for (b
= s
; b
< s
+ c
; b
+= mp
->m_sb
.sb_rextsize
) {
570 ext
= (xfs_drtbno_t
) b
/ mp
->m_sb
.sb_rextsize
;
571 pwe
= XFS_SB_VERSION_HASEXTFLGBIT(&mp
->m_sb
) && flag
&&
572 (b
% mp
->m_sb
.sb_rextsize
!= 0);
574 if (check_dups
== 1) {
575 if (search_rt_dup_extent(mp
, ext
) && !pwe
) {
576 do_warn(_("data fork in rt ino %llu claims "
577 "dup rt extent, off - %llu, "
578 "start - %llu, count %llu\n"),
585 state
= get_rtbno_state(mp
, ext
);
590 set_rtbno_state(mp
, ext
, XR_E_INUSE
);
594 do_error(_("bad state in rt block map %llu\n"),
600 do_error(_("data fork in rt inode %llu found "
601 "metadata block %llu in rt bmap\n"),
609 set_rtbno_state(mp
, ext
, XR_E_MULT
);
610 do_warn(_("data fork in rt inode %llu claims "
611 "used rt block %llu\n"),
617 do_error(_("illegal state %d in rt block map "
618 "%llu\n"), state
, b
);
623 * bump up the block counter
631 * return 1 if inode should be cleared, 0 otherwise
632 * if check_dups should be set to 1, that implies that
633 * the primary purpose of this call is to see if the
634 * file overlaps with any duplicate extents (in the
635 * duplicate extent list).
639 process_bmbt_reclist_int(
641 xfs_bmbt_rec_32_t
*rp
,
647 xfs_dfiloff_t
*first_key
,
648 xfs_dfiloff_t
*last_key
,
653 xfs_dfilblks_t c
; /* count */
654 xfs_dfilblks_t cp
= 0; /* prev count */
655 xfs_dfsbno_t s
; /* start */
656 xfs_dfsbno_t sp
= 0; /* prev start */
657 xfs_dfiloff_t o
= 0; /* offset */
658 xfs_dfiloff_t op
= 0; /* prev offset */
663 int flag
; /* extent flag */
667 xfs_agnumber_t locked_agno
= -1;
670 if (whichfork
== XFS_DATA_FORK
)
671 forkname
= _("data");
673 forkname
= _("attr");
675 if (type
== XR_INO_RTDATA
)
676 ftype
= _("real-time");
678 ftype
= _("regular");
680 for (i
= 0; i
< numrecs
; i
++, rp
++) {
681 convert_extent(rp
, &o
, &s
, &c
, &flag
);
683 *last_key
= *first_key
= o
;
686 if (i
> 0 && op
+ cp
> o
) {
687 do_warn(_("bmap rec out of order, inode %llu entry %d "
688 "[o s c] [%llu %llu %llu], %d [%llu %llu %llu]\n"),
689 ino
, i
, o
, s
, c
, i
-1, op
, sp
, cp
);
697 * check numeric validity of the extent
700 do_warn(_("zero length extent (off = %llu, "
701 "fsbno = %llu) in ino %llu\n"), o
, s
, ino
);
705 if (type
== XR_INO_RTDATA
&& whichfork
== XFS_DATA_FORK
) {
707 * realtime bitmaps don't use AG locks, so returning
708 * immediately is fine for this code path.
710 if (process_rt_rec(mp
, rp
, ino
, tot
, check_dups
))
713 * skip rest of loop processing since that's
714 * all for regular file forks and attr forks
720 * regular file data fork or attribute fork
722 switch (verify_dfsbno_range(mp
, s
, c
)) {
723 case XR_DFSBNORANGE_VALID
:
726 case XR_DFSBNORANGE_BADSTART
:
727 do_warn(_("inode %llu - bad extent starting "
728 "block number %llu, offset %llu\n"),
732 case XR_DFSBNORANGE_BADEND
:
733 do_warn(_("inode %llu - bad extent last block "
734 "number %llu, offset %llu\n"),
738 case XR_DFSBNORANGE_OVERFLOW
:
739 do_warn(_("inode %llu - bad extent overflows - "
740 "start %llu, end %llu, offset %llu\n"),
741 ino
, s
, s
+ c
- 1, o
);
744 if (o
>= fs_max_file_offset
) {
745 do_warn(_("inode %llu - extent offset too large - "
746 "start %llu, count %llu, offset %llu\n"),
751 if (blkmapp
&& *blkmapp
)
752 blkmap_set_ext(blkmapp
, o
, s
, c
);
754 * Profiling shows that the following loop takes the
755 * most time in all of xfs_repair.
757 agno
= XFS_FSB_TO_AGNO(mp
, s
);
758 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
760 if (agno
!= locked_agno
) {
761 if (locked_agno
!= -1)
762 pthread_mutex_unlock(&ag_locks
[locked_agno
]);
763 pthread_mutex_lock(&ag_locks
[agno
]);
769 * if we're just checking the bmap for dups,
770 * return if we find one, otherwise, continue
771 * checking each entry without setting the
774 for (b
= s
; b
< e
; b
++, agbno
++) {
775 if (search_dup_extent(mp
, agno
, agbno
)) {
776 do_warn(_("%s fork in ino %llu claims "
777 "dup extent, off - %llu, "
778 "start - %llu, cnt %llu\n"),
779 forkname
, ino
, o
, s
, c
);
787 for (b
= s
; b
< e
; b
++, agbno
++) {
789 * Process in chunks of 16 (XR_BB_UNIT/XR_BB)
790 * for common XR_E_UNKNOWN to XR_E_INUSE transition
792 if (((agbno
& XR_BB_MASK
) == 0) && ((s
+ c
- b
) >= (XR_BB_UNIT
/XR_BB
))) {
793 if (ba_bmap
[agno
][agbno
>>XR_BB
] == XR_E_UNKNOWN_LL
) {
794 ba_bmap
[agno
][agbno
>>XR_BB
] = XR_E_INUSE_LL
;
795 agbno
+= (XR_BB_UNIT
/XR_BB
) - 1;
796 b
+= (XR_BB_UNIT
/XR_BB
) - 1;
802 state
= get_agbno_state(mp
, agno
, agbno
);
807 do_warn(_("%s fork in ino %llu claims free "
809 forkname
, ino
, (__uint64_t
) b
);
810 /* fall through ... */
812 set_agbno_state(mp
, agno
, agbno
, XR_E_INUSE
);
816 do_error(_("bad state in block map %llu\n"), b
);
821 do_warn(_("%s fork in inode %llu claims "
822 "metadata block %llu\n"),
823 forkname
, ino
, (__uint64_t
) b
);
828 set_agbno_state(mp
, agno
, agbno
, XR_E_MULT
);
829 do_warn(_("%s fork in %s inode %llu claims "
830 "used block %llu\n"),
831 forkname
, ftype
, ino
, (__uint64_t
) b
);
835 do_error(_("illegal state %d in block map %llu\n"),
843 if (locked_agno
!= -1)
844 pthread_mutex_unlock(&ag_locks
[locked_agno
]);
849 * return 1 if inode should be cleared, 0 otherwise, sets block bitmap
853 process_bmbt_reclist(
855 xfs_bmbt_rec_32_t
*rp
,
861 xfs_dfiloff_t
*first_key
,
862 xfs_dfiloff_t
*last_key
,
865 return(process_bmbt_reclist_int(mp
, rp
, numrecs
, type
, ino
, tot
,
866 blkmapp
, first_key
, last_key
, 0,
871 * return 1 if inode should be cleared, 0 otherwise, does not set
877 xfs_bmbt_rec_32_t
*rp
,
884 xfs_dfiloff_t first_key
= 0;
885 xfs_dfiloff_t last_key
= 0;
887 return(process_bmbt_reclist_int(mp
, rp
, numrecs
, type
, ino
, tot
,
888 NULL
, &first_key
, &last_key
, 1,
893 * these two are meant for routines that read and work with inodes
894 * one at a time where the inodes may be in any order (like walking
895 * the unlinked lists to look for inodes). the caller is responsible
896 * for writing/releasing the buffer.
899 get_agino_buf(xfs_mount_t
*mp
,
904 ino_tree_node_t
*irec
;
908 if ((irec
= find_inode_rec(agno
, agino
)) == NULL
)
911 size
= XFS_FSB_TO_BB(mp
, MAX(1, XFS_INODES_PER_CHUNK
/inodes_per_block
));
912 bp
= libxfs_readbuf(mp
->m_dev
, XFS_AGB_TO_DADDR(mp
, agno
,
913 XFS_AGINO_TO_AGBNO(mp
, irec
->ino_startnum
)), size
, 0);
915 do_warn(_("cannot read inode (%u/%u), disk block %lld\n"),
916 agno
, irec
->ino_startnum
,
917 XFS_AGB_TO_DADDR(mp
, agno
,
918 XFS_AGINO_TO_AGBNO(mp
, irec
->ino_startnum
)));
922 *dipp
= XFS_MAKE_IPTR(mp
, bp
, agino
-
923 XFS_OFFBNO_TO_AGINO(mp
, XFS_AGINO_TO_AGBNO(mp
,
931 * these next routines return the filesystem blockno of the
932 * block containing the block "bno" in the file whose bmap
933 * tree (or extent list) is rooted by "rootblock".
935 * the next routines are utility routines for the third
936 * routine, get_bmapi().
940 getfunc_extlist(xfs_mount_t
*mp
,
949 xfs_dfsbno_t final_fsbno
= NULLDFSBNO
;
950 xfs_bmbt_rec_32_t
*rootblock
= (xfs_bmbt_rec_32_t
*)
951 XFS_DFORK_PTR(dip
, whichfork
);
952 xfs_extnum_t nextents
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
956 for (i
= 0; i
< nextents
; i
++) {
957 convert_extent(rootblock
+ i
, &fbno
, &fsbno
, &bcnt
, &flag
);
959 if (fbno
<= bno
&& bno
< fbno
+ bcnt
) {
960 final_fsbno
= bno
- fbno
+ fsbno
;
969 getfunc_btree(xfs_mount_t
*mp
,
981 xfs_bmbt_rec_32_t
*rec
;
984 xfs_bmdr_key_t
*rkey
;
990 xfs_dfsbno_t final_fsbno
= NULLDFSBNO
;
991 xfs_bmbt_block_t
*block
;
992 xfs_bmdr_block_t
*rootblock
= (xfs_bmdr_block_t
*)
993 XFS_DFORK_PTR(dip
, whichfork
);
995 ASSERT(rootblock
->bb_level
!= 0);
997 * deal with root block, it's got a slightly different
998 * header structure than interior nodes. We know that
999 * a btree should have at least 2 levels otherwise it
1000 * would be an extent list.
1002 rkey
= XFS_BTREE_KEY_ADDR(
1003 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1004 xfs_bmdr
, rootblock
, 1,
1005 XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip
,
1008 rp
= XFS_BTREE_PTR_ADDR(
1009 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1010 xfs_bmdr
, rootblock
, 1,
1011 XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip
,
1014 for (found
= -1, i
= 0; i
< rootblock
->bb_numrecs
- 1; i
++) {
1015 if (rkey
[i
].br_startoff
<= bno
1016 && bno
< rkey
[i
+1].br_startoff
) {
1021 if (i
== rootblock
->bb_numrecs
- 1 && bno
>= rkey
[i
].br_startoff
)
1024 ASSERT(found
!= -1);
1026 fsbno
= INT_GET(rp
[found
], ARCH_CONVERT
);
1028 ASSERT(verify_dfsbno(mp
, fsbno
));
1030 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1031 XFS_FSB_TO_BB(mp
, 1), 0);
1033 do_error(_("cannot read bmap block %llu\n"), fsbno
);
1036 block
= XFS_BUF_TO_BMBT_BLOCK(bp
);
1039 * ok, now traverse any interior btree nodes
1042 prev_level
= INT_GET(block
->bb_level
, ARCH_CONVERT
);
1045 while (INT_GET(block
->bb_level
, ARCH_CONVERT
) > 0) {
1047 ASSERT(INT_GET(block
->bb_level
, ARCH_CONVERT
) < prev_level
);
1049 prev_level
= INT_GET(block
->bb_level
, ARCH_CONVERT
);
1052 if (INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) >
1053 mp
->m_bmap_dmxr
[1]) {
1054 do_warn(_("# of bmap records in inode %llu exceeds max "
1055 "(%u, max - %u)\n"),
1056 ino
, INT_GET(block
->bb_numrecs
, ARCH_CONVERT
),
1057 mp
->m_bmap_dmxr
[1]);
1061 if (verbose
&& INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) <
1062 mp
->m_bmap_dmnr
[1]) {
1063 do_warn(_("- # of bmap records in inode %llu less than "
1064 "minimum (%u, min - %u), proceeding ...\n"),
1065 ino
, INT_GET(block
->bb_numrecs
, ARCH_CONVERT
),
1066 mp
->m_bmap_dmnr
[1]);
1068 key
= XFS_BTREE_KEY_ADDR(mp
->m_sb
.sb_blocksize
,
1069 xfs_bmbt
, block
, 1, mp
->m_bmap_dmxr
[1]);
1070 pp
= XFS_BTREE_PTR_ADDR(mp
->m_sb
.sb_blocksize
,
1071 xfs_bmbt
, block
, 1, mp
->m_bmap_dmxr
[1]);
1072 for ( found
= -1, i
= 0;
1073 i
< INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) - 1;
1075 if (INT_GET(key
[i
].br_startoff
, ARCH_CONVERT
) <= bno
&&
1076 bno
< INT_GET(key
[i
+1].br_startoff
, ARCH_CONVERT
)) {
1081 if (i
== INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) - 1 &&
1082 bno
>= INT_GET(key
[i
].br_startoff
, ARCH_CONVERT
))
1085 ASSERT(found
!= -1);
1086 fsbno
= INT_GET(pp
[found
], ARCH_CONVERT
);
1088 ASSERT(verify_dfsbno(mp
, fsbno
));
1091 * release current btree block and read in the
1092 * next btree block to be traversed
1095 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, fsbno
),
1096 XFS_FSB_TO_BB(mp
, 1), 0);
1098 do_error(_("cannot read bmap block %llu\n"), fsbno
);
1101 block
= XFS_BUF_TO_BMBT_BLOCK(bp
);
1105 * current block must be a leaf block
1107 ASSERT(INT_GET(block
->bb_level
, ARCH_CONVERT
) == 0);
1108 if (INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) > mp
->m_bmap_dmxr
[0]) {
1109 do_warn(_("# of bmap records in inode %llu greater than "
1110 "maximum (%u, max - %u)\n"),
1111 ino
, INT_GET(block
->bb_numrecs
, ARCH_CONVERT
),
1112 mp
->m_bmap_dmxr
[0]);
1116 if (verbose
&& INT_GET(block
->bb_numrecs
, ARCH_CONVERT
) <
1118 do_warn(_("- # of bmap records in inode %llu less than minimum "
1119 "(%u, min - %u), continuing...\n"),
1120 ino
, INT_GET(block
->bb_numrecs
, ARCH_CONVERT
),
1121 mp
->m_bmap_dmnr
[0]);
1123 rec
= (xfs_bmbt_rec_32_t
*)XFS_BTREE_REC_ADDR(mp
->m_sb
.sb_blocksize
,
1124 xfs_bmbt
, block
, 1, mp
->m_bmap_dmxr
[0]);
1125 for (i
= 0; i
< INT_GET(block
->bb_numrecs
, ARCH_CONVERT
); i
++) {
1126 convert_extent(rec
+ i
, &fbno
, &fsbno
, &bcnt
, &flag
);
1128 if (fbno
<= bno
&& bno
< fbno
+ bcnt
) {
1129 final_fsbno
= bno
- fbno
+ fsbno
;
1135 if (final_fsbno
== NULLDFSBNO
)
1136 do_warn(_("could not map block %llu\n"), bno
);
1138 return(final_fsbno
);
1142 * this could be smarter. maybe we should have an open inode
1143 * routine that would get the inode buffer and return back
1144 * an inode handle. I'm betting for the moment that this
1145 * is used only by the directory and attribute checking code
1146 * and that the avl tree find and buffer cache search are
1147 * relatively cheap. If they're too expensive, we'll just
1148 * have to fix this and add an inode handle to the da btree
1151 * caller is responsible for checking doubly referenced blocks
1152 * and references to holes
1155 get_bmapi(xfs_mount_t
*mp
, xfs_dinode_t
*dino_p
,
1156 xfs_ino_t ino_num
, xfs_dfiloff_t bno
, int whichfork
)
1160 switch (XFS_DFORK_FORMAT(dino_p
, whichfork
)) {
1161 case XFS_DINODE_FMT_EXTENTS
:
1162 fsbno
= getfunc_extlist(mp
, ino_num
, dino_p
, bno
, whichfork
);
1164 case XFS_DINODE_FMT_BTREE
:
1165 fsbno
= getfunc_btree(mp
, ino_num
, dino_p
, bno
, whichfork
);
1167 case XFS_DINODE_FMT_LOCAL
:
1168 do_error(_("get_bmapi() called for local inode %llu\n"),
1176 do_error(_("bad inode format for inode %llu\n"), ino_num
);
1184 * higher level inode processing stuff starts here:
1185 * first, one utility routine for each type of inode
1189 * return 1 if inode should be cleared, 0 otherwise
1195 xfs_agnumber_t agno
,
1206 xfs_bmdr_block_t
*dib
;
1207 xfs_dfiloff_t last_key
;
1208 xfs_dfiloff_t first_key
= 0;
1211 xfs_bmbt_key_t
*pkey
;
1216 bmap_cursor_t cursor
;
1218 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
1219 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1223 if (whichfork
== XFS_DATA_FORK
)
1224 forkname
= _("data");
1226 forkname
= _("attr");
1228 level
= INT_GET(dib
->bb_level
, ARCH_CONVERT
);
1229 numrecs
= INT_GET(dib
->bb_numrecs
, ARCH_CONVERT
);
1231 if ((level
== 0) || (level
> XFS_BM_MAXLEVELS(mp
, whichfork
))) {
1233 * XXX - if we were going to fix up the inode,
1234 * we'd try to treat the fork as an interior
1235 * node and see if we could get an accurate
1236 * level value from one of the blocks pointed
1237 * to by the pointers in the fork. For now
1238 * though, we just bail (and blow out the inode).
1240 do_warn(_("bad level %d in inode %llu bmap btree root block\n"),
1241 level
, XFS_AGINO_TO_INO(mp
, agno
, ino
));
1245 do_warn(_("bad numrecs 0 in inode %llu bmap btree root block\n"),
1246 XFS_AGINO_TO_INO(mp
, agno
, ino
));
1250 * use bmdr/dfork_dsize since the root block is in the data fork
1252 if (XFS_BMDR_SPACE_CALC(numrecs
) > ((whichfork
== XFS_DATA_FORK
) ?
1253 XFS_DFORK_DSIZE(dip
, mp
) :
1254 XFS_DFORK_ASIZE(dip
, mp
))) {
1256 _("indicated size of %s btree root (%d bytes) greater than space in "
1257 "inode %llu %s fork\n"),
1258 forkname
, XFS_BMDR_SPACE_CALC(numrecs
), lino
, forkname
);
1262 init_bm_cursor(&cursor
, level
+ 1);
1264 pp
= XFS_BTREE_PTR_ADDR(
1265 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1267 XFS_BTREE_BLOCK_MAXRECS(
1268 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1270 pkey
= XFS_BTREE_KEY_ADDR(
1271 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1273 XFS_BTREE_BLOCK_MAXRECS(
1274 XFS_DFORK_SIZE(dip
, mp
, whichfork
),
1277 last_key
= NULLDFILOFF
;
1279 for (i
= 0; i
< numrecs
; i
++) {
1281 * XXX - if we were going to do more to fix up the inode
1282 * btree, we'd do it right here. For now, if there's a
1283 * problem, we'll bail out and presumably clear the inode.
1285 if (!verify_dfsbno(mp
, INT_GET(pp
[i
], ARCH_CONVERT
))) {
1286 do_warn(_("bad bmap btree ptr 0x%llx in ino %llu\n"),
1287 INT_GET(pp
[i
], ARCH_CONVERT
), lino
);
1291 if (scan_lbtree((xfs_dfsbno_t
)INT_GET(pp
[i
], ARCH_CONVERT
),
1292 level
, scanfunc_bmap
, type
, whichfork
,
1293 lino
, tot
, nex
, blkmapp
, &cursor
,
1297 * fix key (offset) mismatches between the keys in root
1298 * block records and the first key of each child block.
1299 * fixes cases where entries have been shifted between
1300 * blocks but the parent hasn't been updated
1302 if (check_dups
== 0 &&
1303 cursor
.level
[level
-1].first_key
!=
1304 INT_GET(pkey
[i
].br_startoff
, ARCH_CONVERT
)) {
1307 _("correcting key in bmbt root (was %llu, now %llu) in inode "
1309 INT_GET(pkey
[i
].br_startoff
,
1311 cursor
.level
[level
-1].first_key
,
1312 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1315 INT_SET(pkey
[i
].br_startoff
, ARCH_CONVERT
,
1316 cursor
.level
[level
-1].first_key
);
1319 _("bad key in bmbt root (is %llu, would reset to %llu) in inode "
1321 INT_GET(pkey
[i
].br_startoff
,
1323 cursor
.level
[level
-1].first_key
,
1324 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1329 * make sure that keys are in ascending order. blow out
1330 * inode if the ordering doesn't hold
1332 if (check_dups
== 0) {
1333 if (last_key
!= NULLDFILOFF
&& last_key
>=
1334 cursor
.level
[level
-1].first_key
) {
1336 _("out of order bmbt root key %llu in inode %llu %s fork\n"),
1338 XFS_AGINO_TO_INO(mp
, agno
, ino
),
1342 last_key
= cursor
.level
[level
-1].first_key
;
1346 * Check that the last child block's forward sibling pointer
1349 if (check_dups
== 0 &&
1350 cursor
.level
[0].right_fsbno
!= NULLDFSBNO
) {
1352 _("bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n"),
1353 cursor
.level
[0].right_fsbno
);
1355 _("\tin inode %u (%s fork) bmap btree block %llu\n"),
1356 XFS_AGINO_TO_INO(mp
, agno
, ino
), forkname
,
1357 cursor
.level
[0].fsbno
);
1365 * return 1 if inode should be cleared, 0 otherwise
1371 xfs_agnumber_t agno
,
1383 xfs_bmbt_rec_32_t
*rp
;
1384 xfs_dfiloff_t first_key
;
1385 xfs_dfiloff_t last_key
;
1387 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1388 rp
= (xfs_bmbt_rec_32_t
*)XFS_DFORK_PTR(dip
, whichfork
);
1390 *nex
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
1392 * XXX - if we were going to fix up the btree record,
1393 * we'd do it right here. For now, if there's a problem,
1394 * we'll bail out and presumably clear the inode.
1396 if (check_dups
== 0)
1397 return(process_bmbt_reclist(mp
, rp
, *nex
, type
, lino
,
1398 tot
, blkmapp
, &first_key
, &last_key
,
1401 return(scan_bmbt_reclist(mp
, rp
, *nex
, type
, lino
, tot
,
1406 * return 1 if inode should be cleared, 0 otherwise
1412 xfs_agnumber_t agno
,
1423 xfs_attr_shortform_t
*asf
;
1424 xfs_dinode_core_t
*dic
;
1428 *nex
= 0; /* local inodes have 0 extents */
1430 dic
= &dip
->di_core
;
1431 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1432 if (whichfork
== XFS_DATA_FORK
&&
1433 INT_GET(dic
->di_size
, ARCH_CONVERT
) >
1434 XFS_DFORK_DSIZE(dip
, mp
)) {
1436 _("local inode %llu data fork is too large (size = %lld, max = %d)\n"),
1437 lino
, INT_GET(dic
->di_size
, ARCH_CONVERT
),
1438 XFS_DFORK_DSIZE(dip
, mp
));
1440 } else if (whichfork
== XFS_ATTR_FORK
) {
1441 asf
= (xfs_attr_shortform_t
*)
1442 XFS_DFORK_APTR(dip
);
1443 if (INT_GET(asf
->hdr
.totsize
, ARCH_CONVERT
) >
1444 XFS_DFORK_ASIZE(dip
, mp
)) {
1446 _("local inode %llu attr fork too large (size %d, max = %d)\n"),
1447 lino
, INT_GET(asf
->hdr
.totsize
, ARCH_CONVERT
),
1448 XFS_DFORK_ASIZE(dip
, mp
));
1451 if (INT_GET(asf
->hdr
.totsize
, ARCH_CONVERT
) <
1452 sizeof(xfs_attr_sf_hdr_t
)) {
1454 _("local inode %llu attr too small (size = %d, min size = %d)\n"),
1455 lino
, INT_GET(asf
->hdr
.totsize
, ARCH_CONVERT
),
1456 sizeof(xfs_attr_sf_hdr_t
));
1465 process_symlink_extlist(xfs_mount_t
*mp
, xfs_ino_t lino
, xfs_dinode_t
*dino
)
1467 xfs_dfsbno_t start
; /* start */
1468 xfs_dfilblks_t cnt
; /* count */
1469 xfs_dfiloff_t offset
; /* offset */
1470 xfs_dfiloff_t expected_offset
;
1471 xfs_bmbt_rec_32_t
*rp
;
1475 int whichfork
= XFS_DATA_FORK
;
1478 if (INT_GET(dino
->di_core
.di_size
, ARCH_CONVERT
) <=
1479 XFS_DFORK_SIZE(dino
, mp
, whichfork
)) {
1480 if (dino
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
) {
1484 _("mismatch between format (%d) and size (%lld) in symlink ino %llu\n"),
1485 dino
->di_core
.di_format
,
1486 INT_GET(dino
->di_core
.di_size
, ARCH_CONVERT
),
1490 } else if (dino
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
) {
1492 _("mismatch between format (%d) and size (%lld) in symlink inode %llu\n"),
1493 dino
->di_core
.di_format
,
1494 INT_GET(dino
->di_core
.di_size
, ARCH_CONVERT
),
1499 rp
= (xfs_bmbt_rec_32_t
*)XFS_DFORK_PTR(dino
, whichfork
);
1500 numrecs
= XFS_DFORK_NEXTENTS(dino
, whichfork
);
1503 * the max # of extents in a symlink inode is equal to the
1504 * number of max # of blocks required to store the symlink
1506 if (numrecs
> max_symlink_blocks
) {
1508 _("bad number of extents (%d) in symlink %llu data fork\n"),
1513 max_blocks
= max_symlink_blocks
;
1514 expected_offset
= 0;
1516 for (i
= 0; numrecs
> 0; i
++, numrecs
--) {
1517 convert_extent(rp
, &offset
, &start
, &cnt
, &flag
);
1519 if (offset
!= expected_offset
) {
1521 _("bad extent #%d offset (%llu) in symlink %llu data fork\n"),
1525 if (cnt
== 0 || cnt
> max_blocks
) {
1527 _("bad extent #%d count (%llu) in symlink %llu data fork\n"),
1533 expected_offset
+= cnt
;
1540 * takes a name and length and returns 1 if the name contains
1541 * a \0, returns 0 otherwise
1544 null_check(char *name
, int length
)
1548 ASSERT(length
< MAXPATHLEN
);
1550 for (i
= 0; i
< length
; i
++, name
++) {
1559 * like usual, returns 0 if everything's ok and 1 if something's
1570 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
1571 xfs_buf_t
*bp
= NULL
;
1572 char *symlink
, *cptr
, *buf_data
;
1573 int i
, size
, amountdone
;
1574 char data
[MAXPATHLEN
];
1577 * check size against kernel symlink limits. we know
1578 * size is consistent with inode storage format -- e.g.
1579 * the inode is structurally ok so we don't have to check
1582 if (INT_GET(dinoc
->di_size
, ARCH_CONVERT
) >= MAXPATHLEN
) {
1583 do_warn(_("symlink in inode %llu too long (%lld chars)\n"),
1584 lino
, INT_GET(dinoc
->di_size
, ARCH_CONVERT
));
1589 * have to check symlink component by component.
1590 * get symlink contents into data area
1593 if (INT_GET(dinoc
->di_size
, ARCH_CONVERT
)
1594 <= XFS_DFORK_DSIZE(dino
, mp
)) {
1596 * local symlink, just copy the symlink out of the
1597 * inode into the data area
1599 memmove(symlink
, (char *)XFS_DFORK_DPTR(dino
),
1600 INT_GET(dinoc
->di_size
, ARCH_CONVERT
));
1603 * stored in a meta-data file, have to bmap one block
1604 * at a time and copy the symlink into the data area
1606 i
= size
= amountdone
= 0;
1609 while (amountdone
< INT_GET(dinoc
->di_size
, ARCH_CONVERT
)) {
1610 fsbno
= blkmap_get(blkmap
, i
);
1611 if (fsbno
!= NULLDFSBNO
)
1612 bp
= libxfs_readbuf(mp
->m_dev
,
1613 XFS_FSB_TO_DADDR(mp
, fsbno
),
1614 XFS_FSB_TO_BB(mp
, 1), 0);
1615 if (!bp
|| fsbno
== NULLDFSBNO
) {
1617 _("cannot read inode %llu, file block %d, disk block %llu\n"),
1622 buf_data
= (char *)XFS_BUF_PTR(bp
);
1623 size
= MIN(INT_GET(dinoc
->di_size
, ARCH_CONVERT
)
1624 - amountdone
, (int)XFS_FSB_TO_BB(mp
, 1)*BBSIZE
);
1625 memmove(cptr
, buf_data
, size
);
1632 data
[INT_GET(dinoc
->di_size
, ARCH_CONVERT
)] = '\0';
1637 if (null_check(symlink
, (int) INT_GET(dinoc
->di_size
, ARCH_CONVERT
))) {
1639 _("found illegal null character in symlink inode %llu\n"),
1645 * check for any component being too long
1647 if (INT_GET(dinoc
->di_size
, ARCH_CONVERT
) >= MAXNAMELEN
) {
1648 cptr
= strchr(symlink
, '/');
1650 while (cptr
!= NULL
) {
1651 if (cptr
- symlink
>= MAXNAMELEN
) {
1653 _("component of symlink in inode %llu too long\n"),
1658 cptr
= strchr(symlink
, '/');
1661 if (strlen(symlink
) >= MAXNAMELEN
) {
1663 _("component of symlink in inode %llu too long\n"),
1673 * called to process the set of misc inode special inode types
1674 * that have no associated data storage (fifos, pipes, devices, etc.).
1677 process_misc_ino_types(xfs_mount_t
*mp
,
1683 * disallow mountpoint inodes until such time as the
1684 * kernel actually allows them to be created (will
1685 * probably require a superblock version rev, sigh).
1687 if (type
== XR_INO_MOUNTPOINT
) {
1688 do_warn(_("inode %llu has bad inode type (IFMNT)\n"), lino
);
1693 * must also have a zero size
1695 if (be64_to_cpu(dino
->di_core
.di_size
) != 0) {
1698 do_warn(_("size of character device inode %llu != 0 "
1699 "(%lld bytes)\n"), lino
,
1700 be64_to_cpu(dino
->di_core
.di_size
));
1703 do_warn(_("size of block device inode %llu != 0 "
1704 "(%lld bytes)\n"), lino
,
1705 be64_to_cpu(dino
->di_core
.di_size
));
1708 do_warn(_("size of socket inode %llu != 0 "
1709 "(%lld bytes)\n"), lino
,
1710 be64_to_cpu(dino
->di_core
.di_size
));
1713 do_warn(_("size of fifo inode %llu != 0 "
1714 "(%lld bytes)\n"), lino
,
1715 be64_to_cpu(dino
->di_core
.di_size
));
1718 do_warn(_("Internal error - process_misc_ino_types, "
1719 "illegal type %d\n"), type
);
1730 process_misc_ino_types_blocks(xfs_drfsbno_t totblocks
, xfs_ino_t lino
, int type
)
1733 * you can not enforce all misc types have zero data fork blocks
1734 * by checking dino->di_core.di_nblocks because atotblocks (attribute
1735 * blocks) are part of nblocks. We must check this later when atotblocks
1736 * has been calculated or by doing a simple check that anExtents == 0.
1737 * We must also guarantee that totblocks is 0. Thus nblocks checking
1738 * will be done later in process_dinode_int for misc types.
1741 if (totblocks
!= 0) {
1745 _("size of character device inode %llu != 0 (%llu blocks)\n"),
1750 _("size of block device inode %llu != 0 (%llu blocks)\n"),
1755 _("size of socket inode %llu != 0 (%llu blocks)\n"),
1760 _("size of fifo inode %llu != 0 (%llu blocks)\n"),
1773 xfs_dinode_core_t
*dinoc
)
1775 return be16_to_cpu(dinoc
->di_mode
) & S_IFMT
;
1780 xfs_dinode_core_t
*dinoc
,
1783 int mode
= be16_to_cpu(dinoc
->di_mode
);
1785 ASSERT((new_fmt
& ~S_IFMT
) == 0);
1789 dinoc
->di_mode
= cpu_to_be16(mode
);
1793 check_dinode_mode_format(
1794 xfs_dinode_core_t
*dinoc
)
1796 if ((uchar_t
)dinoc
->di_format
>= XFS_DINODE_FMT_UUID
)
1797 return -1; /* FMT_UUID is not used */
1799 switch (dinode_fmt(dinoc
)) {
1804 return (dinoc
->di_format
!= XFS_DINODE_FMT_DEV
) ? -1 : 0;
1807 return (dinoc
->di_format
< XFS_DINODE_FMT_LOCAL
||
1808 dinoc
->di_format
> XFS_DINODE_FMT_BTREE
) ? -1 : 0;
1811 return (dinoc
->di_format
< XFS_DINODE_FMT_EXTENTS
||
1812 dinoc
->di_format
> XFS_DINODE_FMT_BTREE
) ? -1 : 0;
1815 return (dinoc
->di_format
< XFS_DINODE_FMT_LOCAL
||
1816 dinoc
->di_format
> XFS_DINODE_FMT_EXTENTS
) ? -1 : 0;
1820 return 0; /* invalid modes are checked elsewhere */
1824 * If inode is a superblock inode, does type check to make sure is it valid.
1825 * Returns 0 if it's valid, non-zero if it needs to be cleared.
1829 process_check_sb_inodes(
1831 xfs_dinode_core_t
*dinoc
,
1836 if (lino
== mp
->m_sb
.sb_rootino
) {
1837 if (*type
!= XR_INO_DIR
) {
1838 do_warn(_("root inode %llu has bad type 0x%x\n"),
1839 lino
, dinode_fmt(dinoc
));
1842 do_warn(_("resetting to directory\n"));
1843 change_dinode_fmt(dinoc
, S_IFDIR
);
1846 do_warn(_("would reset to directory\n"));
1850 if (lino
== mp
->m_sb
.sb_uquotino
) {
1851 if (*type
!= XR_INO_DATA
) {
1852 do_warn(_("user quota inode %llu has bad type 0x%x\n"),
1853 lino
, dinode_fmt(dinoc
));
1854 mp
->m_sb
.sb_uquotino
= NULLFSINO
;
1859 if (lino
== mp
->m_sb
.sb_gquotino
) {
1860 if (*type
!= XR_INO_DATA
) {
1861 do_warn(_("group quota inode %llu has bad type 0x%x\n"),
1862 lino
, dinode_fmt(dinoc
));
1863 mp
->m_sb
.sb_gquotino
= NULLFSINO
;
1868 if (lino
== mp
->m_sb
.sb_rsumino
) {
1869 if (*type
!= XR_INO_RTSUM
) {
1870 do_warn(_("realtime summary inode %llu has bad type 0x%x, "),
1871 lino
, dinode_fmt(dinoc
));
1873 do_warn(_("resetting to regular file\n"));
1874 change_dinode_fmt(dinoc
, S_IFREG
);
1877 do_warn(_("would reset to regular file\n"));
1880 if (mp
->m_sb
.sb_rblocks
== 0 && dinoc
->di_nextents
!= 0) {
1881 do_warn(_("bad # of extents (%u) for realtime summary inode %llu\n"),
1882 be32_to_cpu(dinoc
->di_nextents
), lino
);
1887 if (lino
== mp
->m_sb
.sb_rbmino
) {
1888 if (*type
!= XR_INO_RTBITMAP
) {
1889 do_warn(_("realtime bitmap inode %llu has bad type 0x%x, "),
1890 lino
, dinode_fmt(dinoc
));
1892 do_warn(_("resetting to regular file\n"));
1893 change_dinode_fmt(dinoc
, S_IFREG
);
1896 do_warn(_("would reset to regular file\n"));
1899 if (mp
->m_sb
.sb_rblocks
== 0 && dinoc
->di_nextents
!= 0) {
1900 do_warn(_("bad # of extents (%u) for realtime bitmap inode %llu\n"),
1901 be32_to_cpu(dinoc
->di_nextents
), lino
);
1910 * general size/consistency checks:
1912 * if the size <= size of the data fork, directories must be
1913 * local inodes unlike regular files which would be extent inodes.
1914 * all the other mentioned types have to have a zero size value.
1916 * if the size and format don't match, get out now rather than
1917 * risk trying to process a non-existent extents or btree
1921 process_check_inode_sizes(
1927 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
1928 xfs_fsize_t size
= be64_to_cpu(dinoc
->di_size
);
1933 if (size
<= XFS_DFORK_DSIZE(dino
, mp
) &&
1934 dinoc
->di_format
!= XFS_DINODE_FMT_LOCAL
) {
1935 do_warn(_("mismatch between format (%d) and size "
1936 "(%lld) in directory ino %llu\n"),
1937 dinoc
->di_format
, size
, lino
);
1942 case XR_INO_SYMLINK
:
1943 if (process_symlink_extlist(mp
, lino
, dino
)) {
1944 do_warn(_("bad data fork in symlink %llu\n"), lino
);
1949 case XR_INO_CHRDEV
: /* fall through to FIFO case ... */
1950 case XR_INO_BLKDEV
: /* fall through to FIFO case ... */
1951 case XR_INO_SOCK
: /* fall through to FIFO case ... */
1952 case XR_INO_MOUNTPOINT
: /* fall through to FIFO case ... */
1954 if (process_misc_ino_types(mp
, dino
, lino
, type
))
1960 * if we have no realtime blocks, any inode claiming
1961 * to be a real-time file is bogus
1963 if (mp
->m_sb
.sb_rblocks
== 0) {
1964 do_warn(_("found inode %llu claiming to be a "
1965 "real-time file\n"), lino
);
1970 case XR_INO_RTBITMAP
:
1971 if (size
!= (__int64_t
)mp
->m_sb
.sb_rbmblocks
*
1972 mp
->m_sb
.sb_blocksize
) {
1973 do_warn(_("realtime bitmap inode %llu has bad size "
1974 "%lld (should be %lld)\n"),
1975 lino
, size
, (__int64_t
) mp
->m_sb
.sb_rbmblocks
*
1976 mp
->m_sb
.sb_blocksize
);
1982 if (size
!= mp
->m_rsumsize
) {
1983 do_warn(_("realtime summary inode %llu has bad size "
1984 "%lld (should be %d)\n"),
1985 lino
, size
, mp
->m_rsumsize
);
1997 * check for illegal values of forkoff
2000 process_check_inode_forkoff(
2002 xfs_dinode_core_t
*dinoc
,
2005 if (dinoc
->di_forkoff
== 0)
2008 switch (dinoc
->di_format
) {
2009 case XFS_DINODE_FMT_DEV
:
2010 if (dinoc
->di_forkoff
!= (roundup(sizeof(xfs_dev_t
), 8) >> 3)) {
2011 do_warn(_("bad attr fork offset %d in dev inode %llu, "
2012 "should be %d\n"), dinoc
->di_forkoff
, lino
,
2013 (int)(roundup(sizeof(xfs_dev_t
), 8) >> 3));
2017 case XFS_DINODE_FMT_LOCAL
: /* fall through ... */
2018 case XFS_DINODE_FMT_EXTENTS
: /* fall through ... */
2019 case XFS_DINODE_FMT_BTREE
:
2020 if (dinoc
->di_forkoff
>= (XFS_LITINO(mp
) >> 3)) {
2021 do_warn(_("bad attr fork offset %d in inode %llu, "
2022 "max=%d\n"), dinoc
->di_forkoff
, lino
,
2023 XFS_LITINO(mp
) >> 3);
2028 do_error(_("unexpected inode format %d\n"), dinoc
->di_format
);
2035 * Updates the inodes block and extent counts if they are wrong
2038 process_inode_blocks_and_extents(
2039 xfs_dinode_core_t
*dinoc
,
2040 xfs_drfsbno_t nblocks
,
2041 __uint64_t nextents
,
2042 __uint64_t anextents
,
2046 if (nblocks
!= be64_to_cpu(dinoc
->di_nblocks
)) {
2048 do_warn(_("correcting nblocks for inode %llu, "
2049 "was %llu - counted %llu\n"), lino
,
2050 be64_to_cpu(dinoc
->di_nblocks
), nblocks
);
2051 dinoc
->di_nblocks
= cpu_to_be64(nblocks
);
2054 do_warn(_("bad nblocks %llu for inode %llu, "
2055 "would reset to %llu\n"),
2056 be64_to_cpu(dinoc
->di_nblocks
), lino
, nblocks
);
2060 if (nextents
> MAXEXTNUM
) {
2061 do_warn(_("too many data fork extents (%llu) in inode %llu\n"),
2065 if (nextents
!= be32_to_cpu(dinoc
->di_nextents
)) {
2067 do_warn(_("correcting nextents for inode %llu, "
2068 "was %d - counted %llu\n"), lino
,
2069 be32_to_cpu(dinoc
->di_nextents
), nextents
);
2070 dinoc
->di_nextents
= cpu_to_be32(nextents
);
2073 do_warn(_("bad nextents %d for inode %llu, would reset "
2074 "to %llu\n"), be32_to_cpu(dinoc
->di_nextents
),
2079 if (anextents
> MAXAEXTNUM
) {
2080 do_warn(_("too many attr fork extents (%llu) in inode %llu\n"),
2084 if (anextents
!= be16_to_cpu(dinoc
->di_anextents
)) {
2086 do_warn(_("correcting anextents for inode %llu, "
2087 "was %d - counted %llu\n"), lino
,
2088 be16_to_cpu(dinoc
->di_anextents
), anextents
);
2089 dinoc
->di_anextents
= cpu_to_be16(anextents
);
2092 do_warn(_("bad anextents %d for inode %llu, would reset"
2093 " to %llu\n"), be16_to_cpu(dinoc
->di_anextents
),
2101 * check data fork -- if it's bad, clear the inode
2104 process_inode_data_fork(
2106 xfs_agnumber_t agno
,
2111 xfs_drfsbno_t
*totblocks
,
2112 __uint64_t
*nextents
,
2116 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
2117 xfs_ino_t lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2120 *nextents
= be32_to_cpu(dinoc
->di_nextents
);
2121 if (*nextents
> be64_to_cpu(dinoc
->di_nblocks
) ||
2122 *nextents
> XFS_MAX_INCORE_EXTENTS
)
2125 if (dinoc
->di_format
!= XFS_DINODE_FMT_LOCAL
&& type
!= XR_INO_RTDATA
)
2126 *dblkmap
= blkmap_alloc(*nextents
);
2129 switch (dinoc
->di_format
) {
2130 case XFS_DINODE_FMT_LOCAL
:
2131 err
= process_lclinode(mp
, agno
, ino
, dino
, type
, dirty
,
2132 totblocks
, nextents
, dblkmap
, XFS_DATA_FORK
,
2135 case XFS_DINODE_FMT_EXTENTS
:
2136 err
= process_exinode(mp
, agno
, ino
, dino
, type
, dirty
,
2137 totblocks
, nextents
, dblkmap
, XFS_DATA_FORK
,
2140 case XFS_DINODE_FMT_BTREE
:
2141 err
= process_btinode(mp
, agno
, ino
, dino
, type
, dirty
,
2142 totblocks
, nextents
, dblkmap
, XFS_DATA_FORK
,
2145 case XFS_DINODE_FMT_DEV
: /* fall through */
2149 do_error(_("unknown format %d, ino %llu (mode = %d)\n"),
2150 dinoc
->di_format
, lino
, be16_to_cpu(dinoc
->di_mode
));
2154 do_warn(_("bad data fork in inode %llu\n"), lino
);
2156 *dirty
+= clear_dinode(mp
, dino
, lino
);
2164 * if check_dups was non-zero, we have to
2165 * re-process data fork to set bitmap since the
2166 * bitmap wasn't set the first time through
2168 switch (dinoc
->di_format
) {
2169 case XFS_DINODE_FMT_LOCAL
:
2170 err
= process_lclinode(mp
, agno
, ino
, dino
, type
,
2171 dirty
, totblocks
, nextents
, dblkmap
,
2174 case XFS_DINODE_FMT_EXTENTS
:
2175 err
= process_exinode(mp
, agno
, ino
, dino
, type
,
2176 dirty
, totblocks
, nextents
, dblkmap
,
2179 case XFS_DINODE_FMT_BTREE
:
2180 err
= process_btinode(mp
, agno
, ino
, dino
, type
,
2181 dirty
, totblocks
, nextents
, dblkmap
,
2184 case XFS_DINODE_FMT_DEV
: /* fall through */
2188 do_error(_("unknown format %d, ino %llu (mode = %d)\n"),
2189 dinoc
->di_format
, lino
,
2190 be16_to_cpu(dinoc
->di_mode
));
2193 if (no_modify
&& err
!= 0)
2202 * Process extended attribute fork in inode
2205 process_inode_attr_fork(
2207 xfs_agnumber_t agno
,
2212 xfs_drfsbno_t
*atotblocks
,
2213 __uint64_t
*anextents
,
2215 int extra_attr_check
,
2218 xfs_dinode_core_t
*dinoc
= &dino
->di_core
;
2219 xfs_ino_t lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2220 blkmap_t
*ablkmap
= NULL
;
2224 if (!XFS_DFORK_Q(dino
)) {
2226 if (dinoc
->di_aformat
!= XFS_DINODE_FMT_EXTENTS
) {
2227 do_warn(_("bad attribute format %d in inode %llu, "),
2228 dinoc
->di_aformat
, lino
);
2230 do_warn(_("resetting value\n"));
2231 dinoc
->di_aformat
= XFS_DINODE_FMT_EXTENTS
;
2234 do_warn(_("would reset value\n"));
2239 *anextents
= be16_to_cpu(dinoc
->di_anextents
);
2240 if (*anextents
> be64_to_cpu(dinoc
->di_nblocks
) ||
2241 *anextents
> XFS_MAX_INCORE_EXTENTS
)
2244 switch (dinoc
->di_aformat
) {
2245 case XFS_DINODE_FMT_LOCAL
:
2247 err
= process_lclinode(mp
, agno
, ino
, dino
, type
, dirty
,
2248 atotblocks
, anextents
, &ablkmap
,
2249 XFS_ATTR_FORK
, check_dups
);
2251 case XFS_DINODE_FMT_EXTENTS
:
2252 ablkmap
= blkmap_alloc(*anextents
);
2254 err
= process_exinode(mp
, agno
, ino
, dino
, type
, dirty
,
2255 atotblocks
, anextents
, &ablkmap
,
2256 XFS_ATTR_FORK
, check_dups
);
2258 case XFS_DINODE_FMT_BTREE
:
2259 ablkmap
= blkmap_alloc(*anextents
);
2261 err
= process_btinode(mp
, agno
, ino
, dino
, type
, dirty
,
2262 atotblocks
, anextents
, &ablkmap
,
2263 XFS_ATTR_FORK
, check_dups
);
2266 do_warn(_("illegal attribute format %d, ino %llu\n"),
2267 dinoc
->di_aformat
, lino
);
2274 * clear the attribute fork if necessary. we can't
2275 * clear the inode because we've already put the
2276 * inode space info into the blockmap.
2278 * XXX - put the inode onto the "move it" list and
2279 * log the the attribute scrubbing
2281 do_warn(_("bad attribute fork in inode %llu"), lino
);
2284 if (delete_attr_ok
) {
2285 do_warn(_(", clearing attr fork\n"));
2286 *dirty
+= clear_dinode_attr(mp
, dino
, lino
);
2287 dinoc
->di_aformat
= XFS_DINODE_FMT_LOCAL
;
2290 *dirty
+= clear_dinode(mp
, dino
, lino
);
2294 do_warn(_(", would clear attr fork\n"));
2299 blkmap_free(ablkmap
);
2302 return delete_attr_ok
? 0 : 1;
2306 switch (dinoc
->di_aformat
) {
2307 case XFS_DINODE_FMT_LOCAL
:
2308 err
= process_lclinode(mp
, agno
, ino
, dino
,
2309 type
, dirty
, atotblocks
, anextents
,
2310 &ablkmap
, XFS_ATTR_FORK
, 0);
2312 case XFS_DINODE_FMT_EXTENTS
:
2313 err
= process_exinode(mp
, agno
, ino
, dino
,
2314 type
, dirty
, atotblocks
, anextents
,
2315 &ablkmap
, XFS_ATTR_FORK
, 0);
2317 case XFS_DINODE_FMT_BTREE
:
2318 err
= process_btinode(mp
, agno
, ino
, dino
,
2319 type
, dirty
, atotblocks
, anextents
,
2320 &ablkmap
, XFS_ATTR_FORK
, 0);
2323 do_error(_("illegal attribute fmt %d, ino %llu\n"),
2324 dinoc
->di_aformat
, lino
);
2327 if (no_modify
&& err
!= 0) {
2328 blkmap_free(ablkmap
);
2336 * do attribute semantic-based consistency checks now
2339 /* get this only in phase 3, not in both phase 3 and 4 */
2340 if (extra_attr_check
&&
2341 process_attributes(mp
, lino
, dino
, ablkmap
, &repair
)) {
2342 do_warn(_("problem with attribute contents in inode %llu\n"),
2345 /* clear attributes if not done already */
2347 *dirty
+= clear_dinode_attr(mp
, dino
, lino
);
2348 dinoc
->di_aformat
= XFS_DINODE_FMT_LOCAL
;
2350 do_warn(_("would clear attr fork\n"));
2356 *dirty
= 1; /* it's been repaired */
2359 blkmap_free(ablkmap
);
2364 * check nlinks feature, if it's a version 1 inode,
2365 * just leave nlinks alone. even if it's set wrong,
2366 * it'll be reset when read in.
2370 process_check_inode_nlink_version(
2371 xfs_dinode_core_t
*dinoc
,
2376 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&& !fs_inode_nlink
) {
2378 * do we have a fs/inode version mismatch with a valid
2379 * version 2 inode here that has to stay version 2 or
2382 if (be32_to_cpu(dinoc
->di_nlink
) > XFS_MAXLINK_1
) {
2384 * yes. are nlink inodes allowed?
2386 if (fs_inode_nlink_allowed
) {
2388 * yes, update status variable which will
2389 * cause sb to be updated later.
2392 do_warn(_("version 2 inode %llu claims > %u links, "),
2393 lino
, XFS_MAXLINK_1
);
2395 do_warn(_("updating superblock "
2396 "version number\n"));
2398 do_warn(_("would update superblock "
2399 "version number\n"));
2403 * no, have to convert back to onlinks
2404 * even if we lose some links
2406 do_warn(_("WARNING: version 2 inode %llu "
2407 "claims > %u links, "),
2408 lino
, XFS_MAXLINK_1
);
2410 do_warn(_("converting back to version 1,\n"
2411 "this may destroy %d links\n"),
2412 be32_to_cpu(dinoc
->di_nlink
) -
2415 dinoc
->di_version
= XFS_DINODE_VERSION_1
;
2416 dinoc
->di_nlink
= cpu_to_be32(XFS_MAXLINK_1
);
2417 dinoc
->di_onlink
= cpu_to_be16(XFS_MAXLINK_1
);
2420 do_warn(_("would convert back to version 1,\n"
2421 "\tthis might destroy %d links\n"),
2422 be32_to_cpu(dinoc
->di_nlink
) -
2428 * do we have a v2 inode that we could convert back
2429 * to v1 without losing any links? if we do and
2430 * we have a mismatch between superblock bits and the
2431 * version bit, alter the version bit in this case.
2433 * the case where we lost links was handled above.
2435 do_warn(_("found version 2 inode %llu, "), lino
);
2437 do_warn(_("converting back to version 1\n"));
2438 dinoc
->di_version
= XFS_DINODE_VERSION_1
;
2439 dinoc
->di_onlink
= cpu_to_be16(
2440 be32_to_cpu(dinoc
->di_nlink
));
2443 do_warn(_("would convert back to version 1\n"));
2449 * ok, if it's still a version 2 inode, it's going
2450 * to stay a version 2 inode. it should have a zero
2451 * onlink field, so clear it.
2453 if (dinoc
->di_version
> XFS_DINODE_VERSION_1
&&
2454 dinoc
->di_onlink
!= 0 && fs_inode_nlink
> 0) {
2456 do_warn(_("clearing obsolete nlink field in "
2457 "version 2 inode %llu, was %d, now 0\n"),
2458 lino
, be16_to_cpu(dinoc
->di_onlink
));
2459 dinoc
->di_onlink
= 0;
2462 do_warn(_("would clear obsolete nlink field in "
2463 "version 2 inode %llu, currently %d\n"),
2464 lino
, be16_to_cpu(dinoc
->di_onlink
));
2471 * returns 0 if the inode is ok, 1 if the inode is corrupt
2472 * check_dups can be set to 1 *only* when called by the
2473 * first pass of the duplicate block checking of phase 4.
2474 * *dirty is set > 0 if the dinode has been altered and
2475 * needs to be written out.
2477 * for detailed, info, look at process_dinode() comments.
2481 process_dinode_int(xfs_mount_t
*mp
,
2483 xfs_agnumber_t agno
,
2485 int was_free
, /* 1 if inode is currently free */
2486 int *dirty
, /* out == > 0 if inode is now dirty */
2487 int *used
, /* out == 1 if inode is in use */
2488 int verify_mode
, /* 1 == verify but don't modify inode */
2489 int uncertain
, /* 1 == inode is uncertain */
2490 int ino_discovery
, /* 1 == check dirs for unknown inodes */
2491 int check_dups
, /* 1 == check if inode claims
2492 * duplicate blocks */
2493 int extra_attr_check
, /* 1 == do attribute format and value checks */
2494 int *isa_dir
, /* out == 1 if inode is a directory */
2495 xfs_ino_t
*parent
) /* out -- parent if ino is a dir */
2497 xfs_drfsbno_t totblocks
= 0;
2498 xfs_drfsbno_t atotblocks
= 0;
2499 xfs_dinode_core_t
*dinoc
;
2503 __uint64_t nextents
;
2504 __uint64_t anextents
;
2506 const int is_free
= 0;
2507 const int is_used
= 1;
2508 blkmap_t
*dblkmap
= NULL
;
2510 *dirty
= *isa_dir
= 0;
2512 type
= XR_INO_UNKNOWN
;
2514 dinoc
= &dino
->di_core
;
2515 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
2516 di_mode
= be16_to_cpu(dinoc
->di_mode
);
2519 * if in verify mode, don't modify the inode.
2521 * if correcting, reset stuff that has known values
2523 * if in uncertain mode, be silent on errors since we're
2524 * trying to find out if these are inodes as opposed
2525 * to assuming that they are. Just return the appropriate
2526 * return code in that case.
2528 * If uncertain is set, verify_mode MUST be set.
2530 ASSERT(uncertain
== 0 || verify_mode
!= 0);
2532 if (be16_to_cpu(dinoc
->di_magic
) != XFS_DINODE_MAGIC
) {
2535 do_warn(_("bad magic number 0x%x on inode %llu%c"),
2536 be16_to_cpu(dinoc
->di_magic
), lino
,
2537 verify_mode
? '\n' : ',');
2540 do_warn(_(" resetting magic number\n"));
2541 dinoc
->di_magic
= cpu_to_be16(XFS_DINODE_MAGIC
);
2544 do_warn(_(" would reset magic number\n"));
2548 if (!XFS_DINODE_GOOD_VERSION(dinoc
->di_version
) ||
2549 (!fs_inode_nlink
&& dinoc
->di_version
> XFS_DINODE_VERSION_1
)) {
2552 do_warn(_("bad version number 0x%x on inode %llu%c"),
2553 dinoc
->di_version
, lino
,
2554 verify_mode
? '\n' : ',');
2557 do_warn(_(" resetting version number\n"));
2558 dinoc
->di_version
= (fs_inode_nlink
) ?
2559 XFS_DINODE_VERSION_2
:
2560 XFS_DINODE_VERSION_1
;
2563 do_warn(_(" would reset version number\n"));
2568 * blow out of here if the inode size is < 0
2570 if ((xfs_fsize_t
)be64_to_cpu(dinoc
->di_size
) < 0) {
2572 do_warn(_("bad (negative) size %lld on inode %llu\n"),
2573 be64_to_cpu(dinoc
->di_size
), lino
);
2580 * if not in verify mode, check to sii if the inode and imap
2581 * agree that the inode is free
2583 if (!verify_mode
&& di_mode
== 0) {
2585 * was_free value is not meaningful if we're in verify mode
2589 * easy case, inode free -- inode and map agree, clear
2590 * it just in case to ensure that format, etc. are
2594 *dirty
+= clear_dinode(mp
, dino
, lino
);
2599 * the inode looks free but the map says it's in use.
2600 * clear the inode just to be safe and mark the inode
2603 do_warn(_("imap claims a free inode %llu is in use, "), lino
);
2605 do_warn(_("correcting imap and clearing inode\n"));
2606 *dirty
+= clear_dinode(mp
, dino
, lino
);
2609 do_warn(_("would correct imap and clear inode\n"));
2615 * because of the lack of any write ordering guarantee, it's
2616 * possible that the core got updated but the forks didn't.
2617 * so rather than be ambitious (and probably incorrect),
2618 * if there's an inconsistency, we get conservative and
2619 * just pitch the file. blow off checking formats of
2620 * free inodes since technically any format is legal
2621 * as we reset the inode when we re-use it.
2623 if (di_mode
!= 0 && check_dinode_mode_format(dinoc
) != 0) {
2625 do_warn(_("bad inode format in inode %llu\n"), lino
);
2635 * clear the next unlinked field if necessary on a good
2636 * inode only during phase 4 -- when checking for inodes
2637 * referencing duplicate blocks. then it's safe because
2638 * we've done the inode discovery and have found all the inodes
2639 * we're going to find. check_dups is set to 1 only during
2642 if (check_dups
&& !no_modify
)
2643 *dirty
+= clear_dinode_unlinked(mp
, dino
);
2645 /* set type and map type info */
2647 switch (di_mode
& S_IFMT
) {
2653 if (be16_to_cpu(dinoc
->di_flags
) & XFS_DIFLAG_REALTIME
)
2654 type
= XR_INO_RTDATA
;
2655 else if (lino
== mp
->m_sb
.sb_rbmino
)
2656 type
= XR_INO_RTBITMAP
;
2657 else if (lino
== mp
->m_sb
.sb_rsumino
)
2658 type
= XR_INO_RTSUM
;
2663 type
= XR_INO_SYMLINK
;
2666 type
= XR_INO_CHRDEV
;
2669 type
= XR_INO_BLKDEV
;
2678 do_warn(_("bad inode type %#o inode %llu\n"),
2679 di_mode
& S_IFMT
, lino
);
2684 * type checks for superblock inodes
2686 if (process_check_sb_inodes(mp
, dinoc
, lino
, &type
, dirty
) != 0)
2690 * only regular files with REALTIME or EXTSIZE flags set can have
2691 * extsize set, or directories with EXTSZINHERIT.
2693 if (be32_to_cpu(dinoc
->di_extsize
) != 0) {
2694 if ((type
== XR_INO_RTDATA
) ||
2695 (type
== XR_INO_DIR
&& (be16_to_cpu(dinoc
->di_flags
) &
2696 XFS_DIFLAG_EXTSZINHERIT
)) ||
2697 (type
== XR_INO_DATA
&& (be16_to_cpu(dinoc
->di_flags
) &
2698 XFS_DIFLAG_EXTSIZE
))) {
2701 do_warn(_("bad non-zero extent size %u for "
2702 "non-realtime/extsize inode %llu, "),
2703 be32_to_cpu(dinoc
->di_extsize
), lino
);
2705 do_warn(_("resetting to zero\n"));
2706 dinoc
->di_extsize
= 0;
2709 do_warn(_("would reset to zero\n"));
2714 * general size/consistency checks:
2716 if (process_check_inode_sizes(mp
, dino
, lino
, type
) != 0)
2720 * check for illegal values of forkoff
2722 if (process_check_inode_forkoff(mp
, dinoc
, lino
) != 0)
2726 * check data fork -- if it's bad, clear the inode
2728 if (process_inode_data_fork(mp
, agno
, ino
, dino
, type
, dirty
,
2729 &totblocks
, &nextents
, &dblkmap
, check_dups
) != 0)
2733 * check attribute fork if necessary. attributes are
2734 * always stored in the regular filesystem.
2736 if (process_inode_attr_fork(mp
, agno
, ino
, dino
, type
, dirty
,
2737 &atotblocks
, &anextents
, check_dups
, extra_attr_check
,
2742 * enforce totblocks is 0 for misc types
2744 if (process_misc_ino_types_blocks(totblocks
, lino
, type
))
2748 * correct space counters if required
2750 if (process_inode_blocks_and_extents(dinoc
, totblocks
+ atotblocks
,
2751 nextents
, anextents
, lino
, dirty
) != 0)
2755 * do any semantic type-based checking here
2759 if (xfs_sb_version_hasdirv2(&mp
->m_sb
) ?
2760 process_dir2(mp
, lino
, dino
, ino_discovery
,
2761 dirty
, "", parent
, dblkmap
) :
2762 process_dir(mp
, lino
, dino
, ino_discovery
,
2763 dirty
, "", parent
, dblkmap
)) {
2764 do_warn(_("problem with directory contents in "
2765 "inode %llu\n"), lino
);
2769 case XR_INO_SYMLINK
:
2770 if (process_symlink(mp
, lino
, dino
, dblkmap
) != 0) {
2771 do_warn(_("problem with symbolic link in inode %llu\n"),
2781 blkmap_free(dblkmap
);
2784 * check nlinks feature, if it's a version 1 inode,
2785 * just leave nlinks alone. even if it's set wrong,
2786 * it'll be reset when read in.
2788 *dirty
= process_check_inode_nlink_version(dinoc
, lino
);
2794 *dirty
+= clear_dinode(mp
, dino
, lino
);
2801 blkmap_free(dblkmap
);
2806 * returns 1 if inode is used, 0 if free.
2807 * performs any necessary salvaging actions.
2808 * note that we leave the generation count alone
2809 * because nothing we could set it to would be
2810 * guaranteed to be correct so the best guess for
2811 * the correct value is just to leave it alone.
2813 * The trick is detecting empty files. For those,
2814 * the core and the forks should all be in the "empty"
2815 * or zero-length state -- a zero or possibly minimum length
2816 * (in the case of dirs) extent list -- although inline directories
2817 * and symlinks might be handled differently. So it should be
2818 * possible to sanity check them against each other.
2820 * If the forks are an empty extent list though, then forget it.
2821 * The file is toast anyway since we can't recover its storage.
2825 * mp -- mount structure
2826 * dino -- pointer to on-disk inode structure
2827 * agno/ino -- inode numbers
2828 * free -- whether the map thinks the inode is free (1 == free)
2829 * ino_discovery -- whether we should examine directory
2830 * contents to discover new inodes
2831 * check_dups -- whether we should check to see if the
2832 * inode references duplicate blocks
2833 * if so, we compare the inode's claimed
2834 * blocks against the contents of the
2835 * duplicate extent list but we don't
2836 * set the bitmap. If not, we set the
2837 * bitmap and try and detect multiply
2838 * claimed blocks using the bitmap.
2840 * dirty -- whether we changed the inode (1 == yes)
2841 * used -- 1 if the inode is used, 0 if free. In no modify
2842 * mode, whether the inode should be used or free
2843 * isa_dir -- 1 if the inode is a directory, 0 if not. In
2844 * no modify mode, if the inode would be a dir or not.
2846 * Return value -- 0 if the inode is good, 1 if it is/was corrupt
2853 xfs_agnumber_t agno
,
2860 int extra_attr_check
,
2864 const int verify_mode
= 0;
2865 const int uncertain
= 0;
2867 #ifdef XR_INODE_TRACE
2868 fprintf(stderr
, "processing inode %d/%d\n", agno
, ino
);
2870 return process_dinode_int(mp
, dino
, agno
, ino
, was_free
, dirty
, used
,
2871 verify_mode
, uncertain
, ino_discovery
,
2872 check_dups
, extra_attr_check
, isa_dir
, parent
);
2876 * a more cursory check, check inode core, *DON'T* check forks
2877 * this basically just verifies whether the inode is an inode
2878 * and whether or not it has been totally trashed. returns 0
2879 * if the inode passes the cursory sanity check, 1 otherwise.
2885 xfs_agnumber_t agno
,
2892 const int verify_mode
= 1;
2893 const int check_dups
= 0;
2894 const int ino_discovery
= 0;
2895 const int uncertain
= 0;
2897 return process_dinode_int(mp
, dino
, agno
, ino
, 0, &dirty
, &used
,
2898 verify_mode
, uncertain
, ino_discovery
,
2899 check_dups
, 0, &isa_dir
, &parent
);
2903 * like above only for inode on the uncertain list. it sets
2904 * the uncertain flag which makes process_dinode_int quieter.
2905 * returns 0 if the inode passes the cursory sanity check, 1 otherwise.
2908 verify_uncertain_dinode(
2911 xfs_agnumber_t agno
,
2918 const int verify_mode
= 1;
2919 const int check_dups
= 0;
2920 const int ino_discovery
= 0;
2921 const int uncertain
= 1;
2923 return process_dinode_int(mp
, dino
, agno
, ino
, 0, &dirty
, &used
,
2924 verify_mode
, uncertain
, ino_discovery
,
2925 check_dups
, 0, &isa_dir
, &parent
);