2 * Copyright (c) 2000-2002,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
23 #include "err_protos.h"
30 * Tag bad directory entries with this.
31 * We can't tag them with -1 since that will look like a
32 * data_unused_t instead of a data_entry_t.
34 #define BADFSINO ((xfs_ino_t)0xfeffffffffffffffULL)
37 * Known bad inode list. These are seen when the leaf and node
38 * block linkages are incorrect.
40 typedef struct dir2_bad
{
42 struct dir2_bad
*next
;
44 dir2_bad_t
*dir2_bad_list
;
52 if ((l
= malloc(sizeof(dir2_bad_t
))) == NULL
) {
54 _("malloc failed (%u bytes) dir2_add_badlist:ino %llu\n"),
55 sizeof(dir2_bad_t
), ino
);
58 l
->next
= dir2_bad_list
;
69 for (l
= dir2_bad_list
; l
; l
= l
->next
)
76 * Multibuffer handling.
77 * V2 directory blocks can be noncontiguous, needing multiple buffers.
91 bplist
= calloc(nex
, sizeof(*bplist
));
93 do_error(_("couldn't malloc dir2 buffer list\n"));
96 for (i
= 0; i
< nex
; i
++) {
97 bplist
[i
] = libxfs_readbuf(mp
->m_dev
,
98 XFS_FSB_TO_DADDR(mp
, bmp
[i
].startblock
),
99 XFS_FSB_TO_BB(mp
, bmp
[i
].blockcount
), 0);
103 dabuf
= malloc(XFS_DA_BUF_SIZE(nex
));
105 do_error(_("couldn't malloc dir2 buffer header\n"));
112 dabuf
->bbcount
= (short)BTOBB(XFS_BUF_COUNT(bp
));
113 dabuf
->data
= XFS_BUF_PTR(bp
);
116 for (i
= 0, dabuf
->bbcount
= 0; i
< nex
; i
++) {
117 dabuf
->bps
[i
] = bp
= bplist
[i
];
118 dabuf
->bbcount
+= BTOBB(XFS_BUF_COUNT(bp
));
120 dabuf
->data
= malloc(BBTOB(dabuf
->bbcount
));
121 if (dabuf
->data
== NULL
) {
122 do_error(_("couldn't malloc dir2 buffer data\n"));
125 for (i
= off
= 0; i
< nex
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
127 bcopy(XFS_BUF_PTR(bp
), (char *)dabuf
->data
+ off
,
134 for (i
= 0; i
< nex
; i
++)
135 libxfs_putbuf(bplist
[i
]);
150 for (i
=off
=0; i
< dabuf
->nbuf
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
152 bcopy((char *)dabuf
->data
+ off
, XFS_BUF_PTR(bp
),
181 if ((nbuf
= dabuf
->nbuf
) == 1) {
185 bplist
= malloc(nbuf
* sizeof(*bplist
));
186 if (bplist
== NULL
) {
187 do_error(_("couldn't malloc dir2 buffer list\n"));
190 bcopy(dabuf
->bps
, bplist
, nbuf
* sizeof(*bplist
));
191 for (i
= off
= 0; i
< nbuf
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
193 bcopy((char *)dabuf
->data
+ off
, XFS_BUF_PTR(bp
),
198 for (i
= error
= 0; i
< nbuf
; i
++) {
199 e
= libxfs_writebuf(bplist
[i
], 0);
217 if ((nbuf
= dabuf
->nbuf
) == 1) {
221 bplist
= malloc(nbuf
* sizeof(*bplist
));
222 if (bplist
== NULL
) {
223 do_error(_("couldn't malloc dir2 buffer list\n"));
226 bcopy(dabuf
->bps
, bplist
, nbuf
* sizeof(*bplist
));
229 for (i
= 0; i
< nbuf
; i
++)
230 libxfs_putbuf(bplist
[i
]);
236 * walk tree from root to the left-most leaf block reading in
237 * blocks and setting up cursor. passes back file block number of the
238 * left-most leaf block if successful (bno). returns 1 if successful,
242 traverse_int_dir2block(xfs_mount_t
*mp
,
243 dir2_bt_cursor_t
*da_cursor
,
251 xfs_da_intnode_t
*node
;
254 * traverse down left-side of tree until we hit the
255 * left-most leaf block setting up the btree cursor along
258 bno
= mp
->m_dirleafblk
;
261 da_cursor
->active
= 0;
265 * read in each block along the way and set up cursor
267 nex
= blkmap_getn(da_cursor
->blkmap
, bno
, mp
->m_dirblkfsbs
,
273 bp
= da_read_buf(mp
, nex
, bmp
);
276 do_warn(_("can't read block %u for directory inode "
278 bno
, da_cursor
->ino
);
284 if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) ==
285 XFS_DIR2_LEAFN_MAGIC
) {
287 do_warn(_("found non-root LEAFN node in inode "
289 da_cursor
->ino
, bno
);
291 if (INT_GET(node
->hdr
.level
, ARCH_CONVERT
) >= 1) {
292 do_warn(_("LEAFN node level is %d inode %llu "
294 INT_GET(node
->hdr
.level
, ARCH_CONVERT
),
295 da_cursor
->ino
, bno
);
300 } else if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) !=
303 do_warn(_("bad dir magic number 0x%x in inode %llu "
305 INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
),
306 da_cursor
->ino
, bno
);
309 if (INT_GET(node
->hdr
.count
, ARCH_CONVERT
) >
310 mp
->m_dir_node_ents
) {
312 do_warn(_("bad record count in inode %llu, count = %d, "
313 "max = %d\n"), da_cursor
->ino
,
314 INT_GET(node
->hdr
.count
, ARCH_CONVERT
),
315 mp
->m_dir_node_ents
);
320 * maintain level counter
323 i
= da_cursor
->active
=
324 INT_GET(node
->hdr
.level
, ARCH_CONVERT
);
326 if (INT_GET(node
->hdr
.level
, ARCH_CONVERT
) == i
- 1) {
329 do_warn(_("bad directory btree for directory "
337 da_cursor
->level
[i
].hashval
=
338 INT_GET(node
->btree
[0].hashval
, ARCH_CONVERT
);
339 da_cursor
->level
[i
].bp
= bp
;
340 da_cursor
->level
[i
].bno
= bno
;
341 da_cursor
->level
[i
].index
= 0;
344 * set up new bno for next level down
346 bno
= INT_GET(node
->btree
[0].before
, ARCH_CONVERT
);
347 } while (node
!= NULL
&& i
> 1);
350 * now return block number and get out
352 *rbno
= da_cursor
->level
[0].bno
= bno
;
356 while (i
> 1 && i
<= da_cursor
->active
) {
357 da_brelse(da_cursor
->level
[i
].bp
);
365 * blow out buffer for this level and all the rest above as well
366 * if error == 0, we are not expecting to encounter any unreleased
367 * buffers (e.g. if we do, it's a mistake). if error == 1, we're
368 * in an error-handling case so unreleased buffers may exist.
371 release_dir2_cursor_int(xfs_mount_t
*mp
,
372 dir2_bt_cursor_t
*cursor
,
376 int level
= prev_level
+ 1;
378 if (cursor
->level
[level
].bp
!= NULL
) {
380 do_warn(_("release_dir2_cursor_int got unexpected "
381 "non-null bp, dabno = %u\n"),
382 cursor
->level
[level
].bno
);
386 da_brelse(cursor
->level
[level
].bp
);
387 cursor
->level
[level
].bp
= NULL
;
390 if (level
< cursor
->active
)
391 release_dir2_cursor_int(mp
, cursor
, level
, error
);
397 release_dir2_cursor(xfs_mount_t
*mp
,
398 dir2_bt_cursor_t
*cursor
,
401 release_dir2_cursor_int(mp
, cursor
, prev_level
, 0);
405 err_release_dir2_cursor(xfs_mount_t
*mp
,
406 dir2_bt_cursor_t
*cursor
,
409 release_dir2_cursor_int(mp
, cursor
, prev_level
, 1);
413 * make sure that all entries in all blocks along the right side of
414 * of the tree are used and hashval's are consistent. level is the
415 * level of the descendent block. returns 0 if good (even if it had
416 * to be fixed up), and 1 if bad. The right edge of the tree is
417 * technically a block boundary. This routine should be used then
418 * instead of verify_dir2_path().
421 verify_final_dir2_path(xfs_mount_t
*mp
,
422 dir2_bt_cursor_t
*cursor
,
425 xfs_da_intnode_t
*node
;
428 int this_level
= p_level
+ 1;
431 * the index should point to the next "unprocessed" entry
432 * in the block which should be the final (rightmost) entry
434 entry
= cursor
->level
[this_level
].index
;
435 node
= (xfs_da_intnode_t
*)(cursor
->level
[this_level
].bp
->data
);
437 * check internal block consistency on this level -- ensure
438 * that all entries are used, encountered and expected hashvals
441 if (entry
!= INT_GET(node
->hdr
.count
, ARCH_CONVERT
) - 1) {
443 _("directory block used/count inconsistency - %d / %hu\n"),
444 entry
, INT_GET(node
->hdr
.count
, ARCH_CONVERT
));
448 * hash values monotonically increasing ???
450 if (cursor
->level
[this_level
].hashval
>=
451 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
452 do_warn(_("directory/attribute block hashvalue inconsistency, "
453 "expected > %u / saw %u\n"),
454 cursor
->level
[this_level
].hashval
,
455 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
));
458 if (INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
) != 0) {
459 do_warn(_("bad directory/attribute forward block pointer, "
460 "expected 0, saw %u\n"),
461 INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
));
465 do_warn(_("bad directory block in inode %llu\n"), cursor
->ino
);
469 * keep track of greatest block # -- that gets
470 * us the length of the directory
472 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
473 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
476 * ok, now check descendant block number against this level
478 if (cursor
->level
[p_level
].bno
!=
479 INT_GET(node
->btree
[entry
].before
, ARCH_CONVERT
)) {
483 if (cursor
->level
[p_level
].hashval
!=
484 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
486 do_warn(_("correcting bad hashval in non-leaf dir "
487 "block\n\tin (level %d) in inode %llu.\n"),
488 this_level
, cursor
->ino
);
489 INT_SET(node
->btree
[entry
].hashval
, ARCH_CONVERT
,
490 cursor
->level
[p_level
].hashval
);
491 cursor
->level
[this_level
].dirty
++;
493 do_warn(_("would correct bad hashval in non-leaf dir "
494 "block\n\tin (level %d) in inode %llu.\n"),
495 this_level
, cursor
->ino
);
500 * release/write buffer
502 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
503 (cursor
->level
[this_level
].dirty
&& !no_modify
));
505 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
506 da_bwrite(mp
, cursor
->level
[this_level
].bp
);
508 da_brelse(cursor
->level
[this_level
].bp
);
510 cursor
->level
[this_level
].bp
= NULL
;
513 * bail out if this is the root block (top of tree)
515 if (this_level
>= cursor
->active
) {
519 * set hashvalue to correctl reflect the now-validated
520 * last entry in this block and continue upwards validation
522 cursor
->level
[this_level
].hashval
=
523 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
);
525 return(verify_final_dir2_path(mp
, cursor
, this_level
));
529 * Verifies the path from a descendant block up to the root.
530 * Should be called when the descendant level traversal hits
531 * a block boundary before crossing the boundary (reading in a new
534 * the directory/attr btrees work differently to the other fs btrees.
535 * each interior block contains records that are <hashval, bno>
536 * pairs. The bno is a file bno, not a filesystem bno. The last
537 * hashvalue in the block <bno> will be <hashval>. BUT unlike
538 * the freespace btrees, the *last* value in each block gets
539 * propagated up the tree instead of the first value in each block.
540 * that is, the interior records point to child blocks and the *greatest*
541 * hash value contained by the child block is the one the block above
542 * uses as the key for the child block.
544 * level is the level of the descendent block. returns 0 if good,
545 * and 1 if bad. The descendant block may be a leaf block.
547 * the invariant here is that the values in the cursor for the
548 * levels beneath this level (this_level) and the cursor index
549 * for this level *must* be valid.
551 * that is, the hashval/bno info is accurate for all
552 * DESCENDANTS and match what the node[index] information
553 * for the current index in the cursor for this level.
555 * the index values in the cursor for the descendant level
556 * are allowed to be off by one as they will reflect the
557 * next entry at those levels to be processed.
559 * the hashvalue for the current level can't be set until
560 * we hit the last entry in the block so, it's garbage
561 * until set by this routine.
563 * bno and bp for the current block/level are always valid
564 * since they have to be set so we can get a buffer for the
568 verify_dir2_path(xfs_mount_t
*mp
,
569 dir2_bt_cursor_t
*cursor
,
572 xfs_da_intnode_t
*node
;
573 xfs_da_intnode_t
*newnode
;
578 int this_level
= p_level
+ 1;
583 * index is currently set to point to the entry that
584 * should be processed now in this level.
586 entry
= cursor
->level
[this_level
].index
;
587 node
= cursor
->level
[this_level
].bp
->data
;
590 * if this block is out of entries, validate this
591 * block and move on to the next block.
592 * and update cursor value for said level
594 if (entry
>= INT_GET(node
->hdr
.count
, ARCH_CONVERT
)) {
596 * update the hash value for this level before
597 * validating it. bno value should be ok since
598 * it was set when the block was first read in.
600 cursor
->level
[this_level
].hashval
=
601 INT_GET(node
->btree
[entry
- 1].hashval
, ARCH_CONVERT
);
604 * keep track of greatest block # -- that gets
605 * us the length of the directory
607 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
608 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
611 * validate the path for the current used-up block
614 if (verify_dir2_path(mp
, cursor
, this_level
))
617 * ok, now get the next buffer and check sibling pointers
619 dabno
= INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
);
621 nex
= blkmap_getn(cursor
->blkmap
, dabno
, mp
->m_dirblkfsbs
,
624 do_warn(_("can't get map info for block %u of "
625 "directory inode %llu\n"),
630 bp
= da_read_buf(mp
, nex
, bmp
);
633 do_warn(_("can't read block %u for directory inode "
641 * verify magic number and back pointer, sanity-check
642 * entry count, verify level
645 if (XFS_DA_NODE_MAGIC
!=
646 INT_GET(newnode
->hdr
.info
.magic
, ARCH_CONVERT
)) {
647 do_warn(_("bad magic number %x in block %u for "
648 "directory inode %llu\n"),
649 INT_GET(newnode
->hdr
.info
.magic
, ARCH_CONVERT
),
653 if (INT_GET(newnode
->hdr
.info
.back
, ARCH_CONVERT
) !=
654 cursor
->level
[this_level
].bno
) {
655 do_warn(_("bad back pointer in block %u for directory "
660 if (INT_GET(newnode
->hdr
.count
, ARCH_CONVERT
) >
661 mp
->m_dir_node_ents
) {
662 do_warn(_("entry count %d too large in block %u for "
663 "directory inode %llu\n"),
664 INT_GET(newnode
->hdr
.count
, ARCH_CONVERT
),
668 if (INT_GET(newnode
->hdr
.level
, ARCH_CONVERT
) != this_level
) {
669 do_warn(_("bad level %d in block %u for directory "
671 INT_GET(newnode
->hdr
.level
, ARCH_CONVERT
),
680 * update cursor, write out the *current* level if
681 * required. don't write out the descendant level
683 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
684 (cursor
->level
[this_level
].dirty
&& !no_modify
));
686 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
687 da_bwrite(mp
, cursor
->level
[this_level
].bp
);
689 da_brelse(cursor
->level
[this_level
].bp
);
690 cursor
->level
[this_level
].bp
= bp
;
691 cursor
->level
[this_level
].dirty
= 0;
692 cursor
->level
[this_level
].bno
= dabno
;
693 cursor
->level
[this_level
].hashval
=
694 INT_GET(newnode
->btree
[0].hashval
, ARCH_CONVERT
);
697 entry
= cursor
->level
[this_level
].index
= 0;
700 * ditto for block numbers
702 if (cursor
->level
[p_level
].bno
!=
703 INT_GET(node
->btree
[entry
].before
, ARCH_CONVERT
)) {
707 * ok, now validate last hashvalue in the descendant
708 * block against the hashval in the current entry
710 if (cursor
->level
[p_level
].hashval
!=
711 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
713 do_warn(_("correcting bad hashval in interior dir "
714 "block\n\tin (level %d) in inode %llu.\n"),
715 this_level
, cursor
->ino
);
716 INT_SET(node
->btree
[entry
].hashval
, ARCH_CONVERT
,
717 cursor
->level
[p_level
].hashval
);
718 cursor
->level
[this_level
].dirty
++;
720 do_warn(_("would correct bad hashval in interior dir "
721 "block\n\tin (level %d) in inode %llu.\n"),
722 this_level
, cursor
->ino
);
726 * increment index for this level to point to next entry
727 * (which should point to the next descendant block)
729 cursor
->level
[this_level
].index
++;
734 * Fix up a shortform directory which was in long form (i8count set)
735 * and is now in short form (i8count clear).
736 * Return pointer to the end of the data when done.
739 process_sf_dir2_fixi8(
741 xfs_dir2_sf_entry_t
**next_sfep
)
744 xfs_dir2_sf_t
*newsfp
;
745 xfs_dir2_sf_entry_t
*newsfep
;
746 xfs_dir2_sf_t
*oldsfp
;
747 xfs_dir2_sf_entry_t
*oldsfep
;
751 oldsize
= (__psint_t
)*next_sfep
- (__psint_t
)sfp
;
752 oldsfp
= malloc(oldsize
);
753 if (oldsfp
== NULL
) {
754 do_error(_("couldn't malloc dir2 shortform copy\n"));
757 memmove(oldsfp
, newsfp
, oldsize
);
758 INT_SET(newsfp
->hdr
.count
, ARCH_CONVERT
,
759 INT_GET(oldsfp
->hdr
.count
, ARCH_CONVERT
));
760 newsfp
->hdr
.i8count
= 0;
761 ino
= XFS_DIR2_SF_GET_INUMBER(oldsfp
, &oldsfp
->hdr
.parent
);
762 XFS_DIR2_SF_PUT_INUMBER(newsfp
, &ino
, &newsfp
->hdr
.parent
);
763 oldsfep
= XFS_DIR2_SF_FIRSTENTRY(oldsfp
);
764 newsfep
= XFS_DIR2_SF_FIRSTENTRY(newsfp
);
765 while ((int)((char *)oldsfep
- (char *)oldsfp
) < oldsize
) {
766 newsfep
->namelen
= oldsfep
->namelen
;
767 XFS_DIR2_SF_PUT_OFFSET(newsfep
,
768 XFS_DIR2_SF_GET_OFFSET(oldsfep
));
769 memmove(newsfep
->name
, oldsfep
->name
, newsfep
->namelen
);
770 ino
= XFS_DIR2_SF_GET_INUMBER(oldsfp
,
771 XFS_DIR2_SF_INUMBERP(oldsfep
));
772 XFS_DIR2_SF_PUT_INUMBER(newsfp
, &ino
,
773 XFS_DIR2_SF_INUMBERP(newsfep
));
774 oldsfep
= XFS_DIR2_SF_NEXTENTRY(oldsfp
, oldsfep
);
775 newsfep
= XFS_DIR2_SF_NEXTENTRY(newsfp
, newsfep
);
777 *next_sfep
= newsfep
;
782 * Regenerate legal (minimal) offsets for the shortform directory.
785 process_sf_dir2_fixoff(
790 xfs_dir2_sf_entry_t
*sfep
;
793 for (i
= 0, sfp
= &dip
->di_u
.di_dir2sf
,
794 sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
),
795 offset
= XFS_DIR2_DATA_FIRST_OFFSET
;
796 i
< INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
);
797 i
++, sfep
= XFS_DIR2_SF_NEXTENTRY(sfp
, sfep
)) {
798 XFS_DIR2_SF_PUT_OFFSET(sfep
, offset
);
799 offset
+= XFS_DIR2_DATA_ENTSIZE(sfep
->namelen
);
804 * this routine performs inode discovery and tries to fix things
805 * in place. available redundancy -- inode data size should match
806 * used directory space in inode.
807 * a non-zero return value means the directory is bogus and should be blasted.
816 int *dino_dirty
, /* out - 1 if dinode buffer dirty */
817 char *dirname
, /* directory pathname */
818 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
819 int *repair
) /* out - 1 if dir was fixed up */
825 __int64_t ino_dir_size
;
827 ino_tree_node_t
*irec_p
;
829 char *junkreason
= NULL
;
832 char name
[MAXNAMELEN
+ 1];
834 xfs_dir2_sf_entry_t
*next_sfep
;
838 xfs_dir2_sf_entry_t
*sfep
;
841 xfs_dir2_sf_entry_t
*tmp_sfep
;
844 sfp
= &dip
->di_u
.di_dir2sf
;
845 max_size
= XFS_DFORK_DSIZE(dip
, mp
);
846 num_entries
= INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
);
847 ino_dir_size
= INT_GET(dip
->di_core
.di_size
, ARCH_CONVERT
);
848 offset
= XFS_DIR2_DATA_FIRST_OFFSET
;
849 bad_offset
= *repair
= 0;
851 ASSERT(ino_dir_size
<= max_size
);
854 * Initialize i8 based on size of parent inode number.
856 i8
= (XFS_DIR2_SF_GET_INUMBER(sfp
, &sfp
->hdr
.parent
)
857 > XFS_DIR2_MAX_SHORT_INUM
);
860 * check for bad entry count
862 if (num_entries
* XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
, 1) +
863 XFS_DIR2_SF_HDR_SIZE(0) > max_size
||
868 * run through entries, stop at first bad entry, don't need
869 * to check for .. since that's encoded in its own field
871 sfep
= next_sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
);
873 i
< num_entries
&& ino_dir_size
> (char *)next_sfep
- (char *)sfp
;
879 lino
= XFS_DIR2_SF_GET_INUMBER(sfp
,
880 XFS_DIR2_SF_INUMBERP(sfep
));
882 * if entry points to self, junk it since only '.' or '..'
883 * should do that and shortform dirs don't contain either
884 * entry. if inode number is invalid, trash entry.
885 * if entry points to special inodes, trash it.
886 * if inode is unknown but number is valid,
887 * add it to the list of uncertain inodes. don't
888 * have to worry about an entry pointing to a
889 * deleted lost+found inode because the entry was
890 * deleted at the same time that the inode was cleared.
894 junkreason
= _("current");
895 } else if (verify_inum(mp
, lino
)) {
897 junkreason
= _("invalid");
898 } else if (lino
== mp
->m_sb
.sb_rbmino
) {
900 junkreason
= _("realtime bitmap");
901 } else if (lino
== mp
->m_sb
.sb_rsumino
) {
903 junkreason
= _("realtime summary");
904 } else if (lino
== mp
->m_sb
.sb_uquotino
) {
906 junkreason
= _("user quota");
907 } else if (lino
== mp
->m_sb
.sb_gquotino
) {
909 junkreason
= _("group quota");
910 } else if ((irec_p
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
911 XFS_INO_TO_AGINO(mp
, lino
))) != NULL
) {
913 * if inode is marked free and we're in inode
914 * discovery mode, leave the entry alone for now.
915 * if the inode turns out to be used, we'll figure
916 * that out when we scan it. If the inode really
917 * is free, we'll hit this code again in phase 4
918 * after we've finished inode discovery and blow
919 * out the entry then.
921 ino_off
= XFS_INO_TO_AGINO(mp
, lino
) -
922 irec_p
->ino_startnum
;
923 ASSERT(is_inode_confirmed(irec_p
, ino_off
));
924 if (is_inode_free(irec_p
, ino_off
) && !ino_discovery
) {
926 junkreason
= _("free");
928 } else if (ino_discovery
) {
930 * put the inode on the uncertain list. we'll
931 * pull the inode off the list and check it later.
932 * if the inode turns out be bogus, we'll delete
933 * this entry in phase 6.
935 add_inode_uncertain(mp
, lino
, 0);
938 * blow the entry out. we know about all
939 * undiscovered entries now (past inode discovery
940 * phase) so this is clearly a bogus entry.
943 junkreason
= _("non-existent");
945 namelen
= sfep
->namelen
;
947 do_warn(_("entry \"%*.*s\" in shortform directory %llu "
948 "references %s inode %llu\n"),
949 namelen
, namelen
, sfep
->name
, ino
, junkreason
,
953 * if we're really lucky, this is
954 * the last entry in which case we
955 * can use the dir size to set the
956 * namelen value. otherwise, forget
957 * it because we're not going to be
958 * able to find the next entry.
962 if (i
== num_entries
- 1) {
963 namelen
= ino_dir_size
-
964 ((__psint_t
) &sfep
->name
[0] -
967 do_warn(_("zero length entry in "
968 "shortform dir %llu, "
969 "resetting to %d\n"),
971 sfep
->namelen
= namelen
;
973 do_warn(_("zero length entry in "
974 "shortform dir %llu, "
975 "would set to %d\n"),
979 do_warn(_("zero length entry in shortform dir "
983 do_warn(_(", junking %d entries\n"),
986 do_warn(_(", would junk %d entries\n"),
989 * don't process the rest of the directory,
990 * break out of processing looop
994 } else if ((__psint_t
) sfep
- (__psint_t
) sfp
+
995 + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
999 if (i
== num_entries
- 1) {
1000 namelen
= ino_dir_size
-
1001 ((__psint_t
) &sfep
->name
[0] -
1003 do_warn(_("size of last entry overflows space "
1004 "left in in shortform dir %llu, "),
1007 do_warn(_("resetting to %d\n"),
1009 sfep
->namelen
= namelen
;
1012 do_warn(_("would reset to %d\n"),
1016 do_warn(_("size of entry #%d overflows space "
1017 "left in in shortform dir %llu\n"),
1020 if (i
== num_entries
- 1)
1022 _("junking entry #%d\n"),
1026 _("junking %d entries\n"),
1029 if (i
== num_entries
- 1)
1031 _("would junk entry #%d\n"),
1035 _("would junk %d entries\n"),
1044 * check for illegal chars in name.
1045 * no need to check for bad length because
1046 * the length value is stored in a byte
1047 * so it can't be too big, it can only wrap
1049 if (namecheck((char *)&sfep
->name
[0], namelen
)) {
1053 do_warn(_("entry contains illegal character "
1054 "in shortform dir %llu\n"),
1059 if (XFS_DIR2_SF_GET_OFFSET(sfep
) < offset
) {
1060 do_warn(_("entry contains offset out of order in "
1061 "shortform dir %llu\n"),
1065 offset
= XFS_DIR2_SF_GET_OFFSET(sfep
) +
1066 XFS_DIR2_DATA_ENTSIZE(namelen
);
1069 * junk the entry by copying up the rest of the
1070 * fork over the current entry and decrementing
1071 * the entry count. if we're in no_modify mode,
1072 * just issue the warning instead. then continue
1073 * the loop with the next_sfep pointer set to the
1074 * correct place in the fork and other counters
1075 * properly set to reflect the deletion if it
1079 bcopy(sfep
->name
, name
, namelen
);
1080 name
[namelen
] = '\0';
1084 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
);
1085 INT_MOD(dip
->di_core
.di_size
, ARCH_CONVERT
,
1087 ino_dir_size
-= tmp_elen
;
1089 tmp_sfep
= (xfs_dir2_sf_entry_t
*)
1090 ((__psint_t
) sfep
+ tmp_elen
);
1091 tmp_len
= max_size
- ((__psint_t
) tmp_sfep
1094 memmove(sfep
, tmp_sfep
, tmp_len
);
1096 INT_MOD(sfp
->hdr
.count
, ARCH_CONVERT
, -1);
1098 bzero((void *) ((__psint_t
) sfep
+ tmp_len
),
1102 * reset the tmp value to the current
1103 * pointer so we'll process the entry
1109 * WARNING: drop the index i by one
1110 * so it matches the decremented count
1111 * for accurate comparisons later
1118 do_warn(_("junking entry \"%s\" in directory "
1122 do_warn(_("would have junked entry \"%s\" in "
1123 "directory inode %llu\n"),
1126 } else if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
1129 * go onto next entry unless we've just junked an
1130 * entry in which the current entry pointer points
1131 * to an unprocessed entry. have to take into zero-len
1132 * entries into account in no modify mode since we
1133 * calculate size based on next_sfep.
1135 next_sfep
= (tmp_sfep
== NULL
)
1136 ? (xfs_dir2_sf_entry_t
*) ((__psint_t
) sfep
1138 ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
,
1140 : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
,
1145 /* sync up sizes and entry counts */
1147 if (INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) != i
) {
1149 do_warn(_("would have corrected entry count "
1150 "in directory %llu from %d to %d\n"),
1151 ino
, INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
), i
);
1153 do_warn(_("corrected entry count in directory %llu, "
1154 "was %d, now %d\n"),
1155 ino
, INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
), i
);
1156 INT_SET(sfp
->hdr
.count
, ARCH_CONVERT
, i
);
1162 if (sfp
->hdr
.i8count
!= i8
) {
1164 do_warn(_("would have corrected i8 count in directory "
1165 "%llu from %d to %d\n"),
1166 ino
, sfp
->hdr
.i8count
, i8
);
1168 do_warn(_("corrected i8 count in directory %llu, "
1169 "was %d, now %d\n"),
1170 ino
, sfp
->hdr
.i8count
, i8
);
1172 process_sf_dir2_fixi8(sfp
, &next_sfep
);
1174 sfp
->hdr
.i8count
= i8
;
1180 if ((__psint_t
) next_sfep
- (__psint_t
) sfp
!= ino_dir_size
) {
1182 do_warn(_("would have corrected directory %llu size "
1183 "from %lld to %lld\n"),
1184 ino
, (__int64_t
) ino_dir_size
,
1185 (__int64_t
)((__psint_t
)next_sfep
-
1188 do_warn(_("corrected directory %llu size, was %lld, "
1190 ino
, (__int64_t
) ino_dir_size
,
1191 (__int64_t
)((__psint_t
)next_sfep
-
1194 INT_SET(dip
->di_core
.di_size
, ARCH_CONVERT
,
1195 (xfs_fsize_t
)((__psint_t
)next_sfep
-
1202 (INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) + 2) *
1203 sizeof(xfs_dir2_leaf_entry_t
) +
1204 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dirblksize
) {
1205 do_warn(_("directory %llu offsets too high\n"), ino
);
1210 do_warn(_("would have corrected entry offsets in "
1211 "directory %llu\n"),
1214 do_warn(_("corrected entry offsets in "
1215 "directory %llu\n"),
1217 process_sf_dir2_fixoff(dip
);
1224 * check parent (..) entry
1226 *parent
= XFS_DIR2_SF_GET_INUMBER(sfp
, &sfp
->hdr
.parent
);
1229 * if parent entry is bogus, null it out. we'll fix it later .
1231 if (verify_inum(mp
, *parent
)) {
1233 do_warn(_("bogus .. inode number (%llu) in directory inode "
1236 *parent
= NULLFSINO
;
1238 do_warn(_("clearing inode number\n"));
1240 XFS_DIR2_SF_PUT_INUMBER(sfp
, &zero
, &sfp
->hdr
.parent
);
1244 do_warn(_("would clear inode number\n"));
1246 } else if (ino
== mp
->m_sb
.sb_rootino
&& ino
!= *parent
) {
1248 * root directories must have .. == .
1251 do_warn(_("corrected root directory %llu .. entry, "
1252 "was %llu, now %llu\n"),
1255 XFS_DIR2_SF_PUT_INUMBER(sfp
, parent
, &sfp
->hdr
.parent
);
1259 do_warn(_("would have corrected root directory %llu .. "
1260 "entry from %llu to %llu\n"),
1263 } else if (ino
== *parent
&& ino
!= mp
->m_sb
.sb_rootino
) {
1265 * likewise, non-root directories can't have .. pointing
1268 *parent
= NULLFSINO
;
1269 do_warn(_("bad .. entry in directory inode %llu, points to "
1273 do_warn(_("clearing inode number\n"));
1275 XFS_DIR2_SF_PUT_INUMBER(sfp
, &zero
, &sfp
->hdr
.parent
);
1279 do_warn(_("would clear inode number\n"));
1287 * Process one directory data block.
1296 char *dirname
, /* directory pathname */
1297 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1299 int *dot
, /* out - 1 if there is a dot, else 0 */
1300 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1305 xfs_dir2_data_free_t
*bf
;
1307 char *clearreason
= NULL
;
1309 xfs_dir2_data_entry_t
*dep
;
1310 xfs_dir2_data_free_t
*dfp
;
1311 xfs_dir2_data_unused_t
*dup
;
1315 ino_tree_node_t
*irec_p
;
1322 bf
= d
->hdr
.bestfree
;
1324 badbest
= lastfree
= freeseen
= 0;
1325 if (INT_GET(bf
[0].length
, ARCH_CONVERT
) == 0) {
1326 badbest
|= INT_GET(bf
[0].offset
, ARCH_CONVERT
) != 0;
1329 if (INT_GET(bf
[1].length
, ARCH_CONVERT
) == 0) {
1330 badbest
|= INT_GET(bf
[1].offset
, ARCH_CONVERT
) != 0;
1333 if (INT_GET(bf
[2].length
, ARCH_CONVERT
) == 0) {
1334 badbest
|= INT_GET(bf
[2].offset
, ARCH_CONVERT
) != 0;
1337 badbest
|= INT_GET(bf
[0].length
, ARCH_CONVERT
) < INT_GET(bf
[1].length
, ARCH_CONVERT
);
1338 badbest
|= INT_GET(bf
[1].length
, ARCH_CONVERT
) < INT_GET(bf
[2].length
, ARCH_CONVERT
);
1339 while (ptr
< endptr
) {
1340 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1342 * If it's unused, look for the space in the bestfree table.
1343 * If we find it, account for that, else make sure it doesn't
1346 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) == XFS_DIR2_DATA_FREE_TAG
) {
1347 if (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) > endptr
||
1348 INT_GET(dup
->length
, ARCH_CONVERT
) == 0 ||
1349 (INT_GET(dup
->length
, ARCH_CONVERT
) & (XFS_DIR2_DATA_ALIGN
- 1)))
1351 if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup
),
1352 ARCH_CONVERT
) != (char *)dup
- (char *)d
)
1354 badbest
|= lastfree
!= 0;
1355 dfp
= xfs_dir2_data_freefind(d
, dup
);
1358 badbest
|= (freeseen
& (1 << i
)) != 0;
1361 badbest
|= INT_GET(dup
->length
, ARCH_CONVERT
) >
1362 INT_GET(bf
[2].length
, ARCH_CONVERT
);
1363 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1367 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1368 if (ptr
+ XFS_DIR2_DATA_ENTSIZE(dep
->namelen
) > endptr
)
1370 if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep
), ARCH_CONVERT
) !=
1371 (char *)dep
- (char *)d
)
1373 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1377 * Dropped out before we processed everything, give up.
1378 * Phase 6 will kill this block if we don't kill the inode.
1380 if (ptr
!= endptr
) {
1381 do_warn(_("corrupt block %u in directory inode %llu\n"),
1384 do_warn(_("\twill junk block\n"));
1386 do_warn(_("\twould junk block\n"));
1391 * Process the entries now.
1393 while (ptr
< endptr
) {
1394 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1395 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) ==
1396 XFS_DIR2_DATA_FREE_TAG
) {
1397 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1400 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1402 * We may have to blow out an entry because of bad inode
1403 * numbers. Do NOT touch the name until after we've computed
1404 * the hashvalue and done a namecheck() on the name.
1406 if (!ino_discovery
&&
1407 INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
) {
1409 * Don't do a damned thing. We already found this
1410 * (or did it ourselves) during phase 3.
1413 } else if (verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
))) {
1415 * Bad inode number. Clear the inode number and the
1416 * entry will get removed later. We don't trash the
1417 * directory since it's still structurally intact.
1420 clearreason
= _("invalid");
1421 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_rbmino
) {
1423 clearreason
= _("realtime bitmap");
1424 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_rsumino
) {
1426 clearreason
= _("realtime summary");
1427 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_uquotino
) {
1429 clearreason
= _("user quota");
1430 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_gquotino
) {
1432 clearreason
= _("group quota");
1433 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == old_orphanage_ino
) {
1435 * Do nothing, silently ignore it, entry has already
1436 * been marked TBD since old_orphanage_ino is set
1440 } else if ((irec_p
= find_inode_rec(
1441 XFS_INO_TO_AGNO(mp
, INT_GET(dep
->inumber
,
1443 XFS_INO_TO_AGINO(mp
, INT_GET(dep
->inumber
,
1444 ARCH_CONVERT
)))) != NULL
) {
1446 * Inode recs should have only confirmed inodes in them.
1448 ino_off
= XFS_INO_TO_AGINO(mp
, INT_GET(dep
->inumber
,
1449 ARCH_CONVERT
)) - irec_p
->ino_startnum
;
1450 ASSERT(is_inode_confirmed(irec_p
, ino_off
));
1452 * If inode is marked free and we're in inode discovery
1453 * mode, leave the entry alone for now. If the inode
1454 * turns out to be used, we'll figure that out when we
1455 * scan it. If the inode really is free, we'll hit this
1456 * code again in phase 4 after we've finished inode
1457 * discovery and blow out the entry then.
1459 if (!ino_discovery
&& is_inode_free(irec_p
, ino_off
)) {
1461 clearreason
= _("free");
1464 } else if (ino_discovery
) {
1465 add_inode_uncertain(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
), 0);
1469 clearreason
= _("non-existent");
1472 do_warn(_("entry \"%*.*s\" at block %u offset %d in "
1473 "directory inode %llu references %s inode "
1475 dep
->namelen
, dep
->namelen
, dep
->name
,
1476 da_bno
, (char *)ptr
- (char *)d
, ino
,
1478 INT_GET(dep
->inumber
, ARCH_CONVERT
));
1480 * If the name length is 0 (illegal) make it 1 and blast
1483 if (dep
->namelen
== 0) {
1484 do_warn(_("entry at block %u offset %d in directory "
1485 "inode %llu has 0 namelength\n"),
1486 da_bno
, (char *)ptr
- (char *)d
, ino
);
1492 * If needed to clear the inode number, do it now.
1496 do_warn(_("\tclearing inode number in entry at "
1498 (char *)ptr
- (char *)d
);
1499 INT_SET(dep
->inumber
, ARCH_CONVERT
, BADFSINO
);
1502 do_warn(_("\twould clear inode number in entry "
1503 "at offset %d...\n"),
1504 (char *)ptr
- (char *)d
);
1508 * Only complain about illegal names in phase 3 (when inode
1509 * discovery is turned on). Otherwise, we'd complain a lot
1512 junkit
= INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
;
1513 nm_illegal
= namecheck((char *)dep
->name
, dep
->namelen
);
1514 if (ino_discovery
&& nm_illegal
) {
1515 do_warn(_("entry at block %u offset %d in directory "
1516 "inode %llu has illegal name \"%*.*s\": "),
1517 da_bno
, (char *)ptr
- (char *)d
, ino
,
1518 dep
->namelen
, dep
->namelen
, dep
->name
);
1522 * Now we can mark entries with BADFSINO's bad.
1525 INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
) {
1531 * Special .. entry processing.
1533 if (dep
->namelen
== 2 &&
1534 dep
->name
[0] == '.' && dep
->name
[1] == '.') {
1537 *parent
= INT_GET(dep
->inumber
, ARCH_CONVERT
);
1539 * What if .. == .? Legal only in the root
1540 * inode. Blow out entry and set parent to
1541 * NULLFSINO otherwise.
1543 if (ino
== INT_GET(dep
->inumber
, ARCH_CONVERT
) &&
1544 ino
!= mp
->m_sb
.sb_rootino
) {
1545 *parent
= NULLFSINO
;
1546 do_warn(_("bad .. entry in directory "
1547 "inode %llu, points to self: "),
1552 * We have to make sure that . == .. in the
1555 else if (ino
!= INT_GET(dep
->inumber
, ARCH_CONVERT
) &&
1556 ino
== mp
->m_sb
.sb_rootino
) {
1557 do_warn(_("bad .. entry in root "
1558 "directory inode %llu, was "
1560 ino
, INT_GET(dep
->inumber
, ARCH_CONVERT
));
1562 do_warn(_("correcting\n"));
1563 INT_SET(dep
->inumber
, ARCH_CONVERT
, ino
);
1566 do_warn(_("would correct\n"));
1571 * Can't fix the directory unless we know which ..
1572 * entry is the right one. Both have valid inode
1573 * numbers or we wouldn't be here. So since both
1574 * seem equally valid, trash this one.
1577 do_warn(_("multiple .. entries in directory "
1584 * Special . entry processing.
1586 else if (dep
->namelen
== 1 && dep
->name
[0] == '.') {
1589 if (INT_GET(dep
->inumber
, ARCH_CONVERT
) != ino
) {
1590 do_warn(_("bad . entry in directory "
1591 "inode %llu, was %llu: "),
1592 ino
, INT_GET(dep
->inumber
, ARCH_CONVERT
));
1594 do_warn(_("correcting\n"));
1595 INT_SET(dep
->inumber
, ARCH_CONVERT
, ino
);
1598 do_warn(_("would correct\n"));
1602 do_warn(_("multiple . entries in directory "
1609 * All other entries -- make sure only . references self.
1611 else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == ino
) {
1612 do_warn(_("entry \"%*.*s\" in directory inode %llu "
1613 "points to self: "),
1614 dep
->namelen
, dep
->namelen
, dep
->name
, ino
);
1618 * Clear junked entries.
1624 do_warn(_("clearing entry\n"));
1626 do_warn(_("would clear entry\n"));
1630 * Advance to the next entry.
1632 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1635 * Check the bestfree table.
1637 if (freeseen
!= 7 || badbest
) {
1638 do_warn(_("bad bestfree table in block %u in directory inode "
1642 do_warn(_("repairing table\n"));
1643 libxfs_dir2_data_freescan(mp
, d
, &i
, endptr
);
1646 do_warn(_("would repair table\n"));
1653 * Process a block-format directory.
1662 int *dino_dirty
, /* out - 1 if dinode buffer dirty */
1663 char *dirname
, /* directory pathname */
1664 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1666 int *dot
, /* out - 1 if there is a dot, else 0 */
1667 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1668 int *repair
) /* out - 1 if something was fixed */
1670 xfs_dir2_block_t
*block
;
1671 xfs_dir2_leaf_entry_t
*blp
;
1674 xfs_dir2_block_tail_t
*btp
;
1678 *repair
= *dot
= *dotdot
= 0;
1679 *parent
= NULLFSINO
;
1680 nex
= blkmap_getn(blkmap
, mp
->m_dirdatablk
, mp
->m_dirblkfsbs
, &bmp
);
1682 do_warn(_("block %u for directory inode %llu is missing\n"),
1683 mp
->m_dirdatablk
, ino
);
1686 bp
= da_read_buf(mp
, nex
, bmp
);
1689 do_warn(_("can't read block %u for directory inode %llu\n"),
1690 mp
->m_dirdatablk
, ino
);
1697 if (INT_GET(block
->hdr
.magic
, ARCH_CONVERT
) != XFS_DIR2_BLOCK_MAGIC
)
1698 do_warn(_("bad directory block magic # %#x in block %u for "
1699 "directory inode %llu\n"),
1700 INT_GET(block
->hdr
.magic
, ARCH_CONVERT
),
1701 mp
->m_dirdatablk
, ino
);
1703 * process the data area
1704 * this also checks & fixes the bestfree
1706 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
1707 blp
= XFS_DIR2_BLOCK_LEAF_P(btp
);
1709 * Don't let this go past the end of the block.
1711 if ((char *)blp
> (char *)btp
)
1712 blp
= (xfs_dir2_leaf_entry_t
*)btp
;
1713 rval
= process_dir2_data(mp
, ino
, dip
, ino_discovery
, dirname
, parent
,
1714 bp
, dot
, dotdot
, mp
->m_dirdatablk
, (char *)blp
);
1715 if (bp
->dirty
&& !no_modify
) {
1724 * Validates leaf contents, node format directories only.
1725 * magic number and sibling pointers checked by caller.
1726 * Returns 0 if block is ok, 1 if the block is bad.
1727 * Looking for: out of order hash values, bad stale counts.
1730 process_leaf_block_dir2(
1732 xfs_dir2_leaf_t
*leaf
,
1735 xfs_dahash_t last_hashval
,
1736 xfs_dahash_t
*next_hashval
)
1741 for (i
= stale
= 0; i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
); i
++) {
1742 if ((char *)&leaf
->ents
[i
] >= (char *)leaf
+ mp
->m_dirblksize
) {
1743 do_warn(_("bad entry count in block %u of directory "
1748 if (INT_GET(leaf
->ents
[i
].address
, ARCH_CONVERT
) ==
1749 XFS_DIR2_NULL_DATAPTR
)
1751 else if (INT_GET(leaf
->ents
[i
].hashval
, ARCH_CONVERT
) <
1753 do_warn(_("bad hash ordering in block %u of directory "
1758 *next_hashval
= last_hashval
=
1759 INT_GET(leaf
->ents
[i
].hashval
, ARCH_CONVERT
);
1761 if (stale
!= INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
)) {
1762 do_warn(_("bad stale count in block %u of directory "
1771 * Returns 0 if the directory is ok, 1 if it has to be rebuilt.
1774 process_leaf_level_dir2(
1776 dir2_bt_cursor_t
*da_cursor
,
1782 xfs_dahash_t current_hashval
;
1784 xfs_dahash_t greatest_hashval
;
1786 xfs_dir2_leaf_t
*leaf
;
1788 xfs_dablk_t prev_bno
;
1790 da_bno
= da_cursor
->level
[0].bno
;
1791 ino
= da_cursor
->ino
;
1794 current_hashval
= 0;
1798 nex
= blkmap_getn(da_cursor
->blkmap
, da_bno
, mp
->m_dirblkfsbs
,
1801 * Directory code uses 0 as the NULL block pointer since 0
1802 * is the root block and no directory block pointer can point
1803 * to the root block of the btree.
1805 ASSERT(da_bno
!= 0);
1808 do_warn(_("can't map block %u for directory "
1813 bp
= da_read_buf(mp
, nex
, bmp
);
1817 do_warn(_("can't read file block %u for directory "
1824 * Check magic number for leaf directory btree block.
1826 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
1827 XFS_DIR2_LEAFN_MAGIC
) {
1828 do_warn(_("bad directory leaf magic # %#x for "
1829 "directory inode %llu block %u\n"),
1830 INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
),
1837 * For each block, process the block, verify its path,
1838 * then get next block. Update cursor values along the way.
1840 if (process_leaf_block_dir2(mp
, leaf
, da_bno
, ino
,
1841 current_hashval
, &greatest_hashval
)) {
1846 * Index can be set to hdr.count so match the indices of the
1847 * interior blocks -- which at the end of the block will point
1848 * to 1 after the final real entry in the block.
1850 da_cursor
->level
[0].hashval
= greatest_hashval
;
1851 da_cursor
->level
[0].bp
= bp
;
1852 da_cursor
->level
[0].bno
= da_bno
;
1853 da_cursor
->level
[0].index
=
1854 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
);
1855 da_cursor
->level
[0].dirty
= buf_dirty
;
1857 if (INT_GET(leaf
->hdr
.info
.back
, ARCH_CONVERT
) != prev_bno
) {
1858 do_warn(_("bad sibling back pointer for block %u in "
1859 "directory inode %llu\n"),
1865 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1867 if (verify_dir2_path(mp
, da_cursor
, 0)) {
1872 current_hashval
= greatest_hashval
;
1873 ASSERT(buf_dirty
== 0 || (buf_dirty
&& !no_modify
));
1874 if (buf_dirty
&& !no_modify
) {
1879 } while (da_bno
!= 0);
1880 if (verify_final_dir2_path(mp
, da_cursor
, 0)) {
1882 * Verify the final path up (right-hand-side) if still ok.
1884 do_warn(_("bad hash path in directory %llu\n"), ino
);
1888 * Redundant but just for testing.
1890 release_dir2_cursor(mp
, da_cursor
, 0);
1895 * Release all buffers holding interior btree blocks.
1897 err_release_dir2_cursor(mp
, da_cursor
, 0);
1904 * Return 1 if the directory's leaf/node space is corrupted and
1905 * needs to be rebuilt, 0 if it's ok.
1916 dir2_bt_cursor_t da_cursor
;
1919 * Try again -- traverse down left-side of tree until we hit the
1920 * left-most leaf block setting up the btree cursor along the way.
1921 * Then walk the leaf blocks left-to-right, calling a parent
1922 * verification routine each time we traverse a block.
1924 bzero(&da_cursor
, sizeof(da_cursor
));
1925 da_cursor
.ino
= ino
;
1926 da_cursor
.dip
= dip
;
1927 da_cursor
.blkmap
= blkmap
;
1930 * Now process interior node.
1932 if (traverse_int_dir2block(mp
, &da_cursor
, &bno
) == 0)
1936 * Skip directories with a root marked XFS_DIR2_LEAFN_MAGIC
1939 release_dir2_cursor(mp
, &da_cursor
, 0);
1943 * Now pass cursor and bno into leaf-block processing routine.
1944 * The leaf dir level routine checks the interior paths up to
1945 * the root including the final right-most path.
1947 return process_leaf_level_dir2(mp
, &da_cursor
, repair
);
1952 * Process leaf and node directories.
1953 * Process the data blocks then, if it's a node directory, check
1954 * the consistency of those blocks.
1957 process_leaf_node_dir2(
1962 char *dirname
, /* directory pathname */
1963 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1965 int *dot
, /* out - 1 if there is a dot, else 0 */
1966 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1967 int *repair
, /* out - 1 if something was fixed */
1968 int isnode
) /* node directory not leaf */
1972 xfs_dir2_data_t
*data
;
1976 xfs_dfiloff_t ndbno
;
1980 *repair
= *dot
= *dotdot
= good
= 0;
1981 *parent
= NULLFSINO
;
1982 ndbno
= NULLDFILOFF
;
1983 while ((dbno
= blkmap_next_off(blkmap
, ndbno
, &t
)) < mp
->m_dirleafblk
) {
1984 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dirblkfsbs
, &bmp
);
1985 ndbno
= dbno
+ mp
->m_dirblkfsbs
- 1;
1987 do_warn(_("block %llu for directory inode %llu is "
1992 bp
= da_read_buf(mp
, nex
, bmp
);
1995 do_warn(_("can't read block %llu for directory inode "
2001 if (INT_GET(data
->hdr
.magic
, ARCH_CONVERT
) !=
2002 XFS_DIR2_DATA_MAGIC
)
2003 do_warn(_("bad directory block magic # %#x in block "
2004 "%llu for directory inode %llu\n"),
2005 INT_GET(data
->hdr
.magic
, ARCH_CONVERT
),
2007 i
= process_dir2_data(mp
, ino
, dip
, ino_discovery
, dirname
,
2008 parent
, bp
, dot
, dotdot
, (xfs_dablk_t
)dbno
,
2009 (char *)data
+ mp
->m_dirblksize
);
2012 if (bp
->dirty
&& !no_modify
) {
2022 if (dir2_is_badino(ino
))
2025 if (process_node_dir2(mp
, ino
, dip
, blkmap
, repair
))
2026 dir2_add_badlist(ino
);
2032 * Returns 1 if things are bad (directory needs to be junked)
2033 * and 0 if things are ok. If ino_discovery is 1, add unknown
2034 * inodes to uncertain inode list.
2053 *parent
= NULLFSINO
;
2058 * branch off depending on the type of inode. This routine
2059 * is only called ONCE so all the subordinate routines will
2060 * fix '.' and junk '..' if they're bogus.
2063 last
= blkmap_last_off(blkmap
);
2064 if (INT_GET(dip
->di_core
.di_size
, ARCH_CONVERT
) <=
2065 XFS_DFORK_DSIZE(dip
, mp
) &&
2066 dip
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
) {
2068 res
= process_sf_dir2(mp
, ino
, dip
, ino_discovery
, dino_dirty
,
2069 dirname
, parent
, &repair
);
2070 } else if (last
== mp
->m_dirblkfsbs
&&
2071 (dip
->di_core
.di_format
== XFS_DINODE_FMT_EXTENTS
||
2072 dip
->di_core
.di_format
== XFS_DINODE_FMT_BTREE
)) {
2073 res
= process_block_dir2(mp
, ino
, dip
, ino_discovery
,
2074 dino_dirty
, dirname
, parent
, blkmap
, &dot
, &dotdot
,
2076 } else if (last
>= mp
->m_dirleafblk
+ mp
->m_dirblkfsbs
&&
2077 (dip
->di_core
.di_format
== XFS_DINODE_FMT_EXTENTS
||
2078 dip
->di_core
.di_format
== XFS_DINODE_FMT_BTREE
)) {
2079 res
= process_leaf_node_dir2(mp
, ino
, dip
, ino_discovery
,
2080 dirname
, parent
, blkmap
, &dot
, &dotdot
, &repair
,
2081 last
> mp
->m_dirleafblk
+ mp
->m_dirblkfsbs
);
2083 do_warn(_("bad size/format for directory %llu\n"), ino
);
2087 * bad . entries in all directories will be fixed up in phase 6
2090 do_warn(_("no . entry for directory %llu\n"), ino
);
2094 * shortform dirs always have a .. entry. .. for all longform
2095 * directories will get fixed in phase 6. .. for other shortform
2096 * dirs also get fixed there. .. for a shortform root was
2097 * fixed in place since we know what it should be
2099 if (dotdot
== 0 && ino
!= mp
->m_sb
.sb_rootino
) {
2100 do_warn(_("no .. entry for directory %llu\n"), ino
);
2101 } else if (dotdot
== 0 && ino
== mp
->m_sb
.sb_rootino
) {
2102 do_warn(_("no .. entry for root directory %llu\n"), ino
);
2103 need_root_dotdot
= 1;
2106 ASSERT((ino
!= mp
->m_sb
.sb_rootino
&& ino
!= *parent
) ||
2107 (ino
== mp
->m_sb
.sb_rootino
&&
2108 (ino
== *parent
|| need_root_dotdot
== 1)));