2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
37 #include "err_protos.h"
44 * Tag bad directory entries with this.
45 * We can't tag them with -1 since that will look like a
46 * data_unused_t instead of a data_entry_t.
48 #define BADFSINO ((xfs_ino_t)0xfeffffffffffffffULL)
51 * Known bad inode list. These are seen when the leaf and node
52 * block linkages are incorrect.
54 typedef struct dir2_bad
{
56 struct dir2_bad
*next
;
58 dir2_bad_t
*dir2_bad_list
;
66 if ((l
= malloc(sizeof(dir2_bad_t
))) == NULL
) {
68 _("malloc failed (%u bytes) dir2_add_badlist:ino %llu\n"),
69 sizeof(dir2_bad_t
), ino
);
72 l
->next
= dir2_bad_list
;
83 for (l
= dir2_bad_list
; l
; l
= l
->next
)
90 * Multibuffer handling.
91 * V2 directory blocks can be noncontiguous, needing multiple buffers.
105 bplist
= calloc(nex
, sizeof(*bplist
));
106 if (bplist
== NULL
) {
107 do_error(_("couldn't malloc dir2 buffer list\n"));
110 for (i
= 0; i
< nex
; i
++) {
111 bplist
[i
] = libxfs_readbuf(mp
->m_dev
,
112 XFS_FSB_TO_DADDR(mp
, bmp
[i
].startblock
),
113 XFS_FSB_TO_BB(mp
, bmp
[i
].blockcount
), 0);
117 dabuf
= malloc(XFS_DA_BUF_SIZE(nex
));
119 do_error(_("couldn't malloc dir2 buffer header\n"));
126 dabuf
->bbcount
= (short)BTOBB(XFS_BUF_COUNT(bp
));
127 dabuf
->data
= XFS_BUF_PTR(bp
);
130 for (i
= 0, dabuf
->bbcount
= 0; i
< nex
; i
++) {
131 dabuf
->bps
[i
] = bp
= bplist
[i
];
132 dabuf
->bbcount
+= BTOBB(XFS_BUF_COUNT(bp
));
134 dabuf
->data
= malloc(BBTOB(dabuf
->bbcount
));
135 if (dabuf
->data
== NULL
) {
136 do_error(_("couldn't malloc dir2 buffer data\n"));
139 for (i
= off
= 0; i
< nex
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
141 bcopy(XFS_BUF_PTR(bp
), (char *)dabuf
->data
+ off
,
147 for (i
= 0; i
< nex
; i
++)
148 libxfs_putbuf(bplist
[i
]);
163 for (i
=off
=0; i
< dabuf
->nbuf
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
165 bcopy((char *)dabuf
->data
+ off
, XFS_BUF_PTR(bp
),
194 if ((nbuf
= dabuf
->nbuf
) == 1) {
198 bplist
= malloc(nbuf
* sizeof(*bplist
));
199 if (bplist
== NULL
) {
200 do_error(_("couldn't malloc dir2 buffer list\n"));
203 bcopy(dabuf
->bps
, bplist
, nbuf
* sizeof(*bplist
));
204 for (i
= off
= 0; i
< nbuf
; i
++, off
+= XFS_BUF_COUNT(bp
)) {
206 bcopy((char *)dabuf
->data
+ off
, XFS_BUF_PTR(bp
),
211 for (i
= error
= 0; i
< nbuf
; i
++) {
212 e
= libxfs_writebuf(bplist
[i
], 0);
230 if ((nbuf
= dabuf
->nbuf
) == 1) {
234 bplist
= malloc(nbuf
* sizeof(*bplist
));
235 if (bplist
== NULL
) {
236 do_error(_("couldn't malloc dir2 buffer list\n"));
239 bcopy(dabuf
->bps
, bplist
, nbuf
* sizeof(*bplist
));
242 for (i
= 0; i
< nbuf
; i
++)
243 libxfs_putbuf(bplist
[i
]);
249 * walk tree from root to the left-most leaf block reading in
250 * blocks and setting up cursor. passes back file block number of the
251 * left-most leaf block if successful (bno). returns 1 if successful,
255 traverse_int_dir2block(xfs_mount_t
*mp
,
256 dir2_bt_cursor_t
*da_cursor
,
264 xfs_da_intnode_t
*node
;
267 * traverse down left-side of tree until we hit the
268 * left-most leaf block setting up the btree cursor along
271 bno
= mp
->m_dirleafblk
;
274 da_cursor
->active
= 0;
278 * read in each block along the way and set up cursor
280 nex
= blkmap_getn(da_cursor
->blkmap
, bno
, mp
->m_dirblkfsbs
,
286 bp
= da_read_buf(mp
, nex
, bmp
);
289 do_warn(_("can't read block %u for directory inode "
291 bno
, da_cursor
->ino
);
297 if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) ==
298 XFS_DIR2_LEAFN_MAGIC
) {
300 do_warn(_("found non-root LEAFN node in inode "
302 da_cursor
->ino
, bno
);
304 if (INT_GET(node
->hdr
.level
, ARCH_CONVERT
) >= 1) {
305 do_warn(_("LEAFN node level is %d inode %llu "
307 INT_GET(node
->hdr
.level
, ARCH_CONVERT
),
308 da_cursor
->ino
, bno
);
313 } else if (INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
) !=
316 do_warn(_("bad dir magic number 0x%x in inode %llu "
318 INT_GET(node
->hdr
.info
.magic
, ARCH_CONVERT
),
319 da_cursor
->ino
, bno
);
322 if (INT_GET(node
->hdr
.count
, ARCH_CONVERT
) >
323 mp
->m_dir_node_ents
) {
325 do_warn(_("bad record count in inode %llu, count = %d, "
326 "max = %d\n"), da_cursor
->ino
,
327 INT_GET(node
->hdr
.count
, ARCH_CONVERT
),
328 mp
->m_dir_node_ents
);
333 * maintain level counter
336 i
= da_cursor
->active
=
337 INT_GET(node
->hdr
.level
, ARCH_CONVERT
);
339 if (INT_GET(node
->hdr
.level
, ARCH_CONVERT
) == i
- 1) {
342 do_warn(_("bad directory btree for directory "
350 da_cursor
->level
[i
].hashval
=
351 INT_GET(node
->btree
[0].hashval
, ARCH_CONVERT
);
352 da_cursor
->level
[i
].bp
= bp
;
353 da_cursor
->level
[i
].bno
= bno
;
354 da_cursor
->level
[i
].index
= 0;
357 * set up new bno for next level down
359 bno
= INT_GET(node
->btree
[0].before
, ARCH_CONVERT
);
360 } while (node
!= NULL
&& i
> 1);
363 * now return block number and get out
365 *rbno
= da_cursor
->level
[0].bno
= bno
;
369 while (i
> 1 && i
<= da_cursor
->active
) {
370 da_brelse(da_cursor
->level
[i
].bp
);
378 * blow out buffer for this level and all the rest above as well
379 * if error == 0, we are not expecting to encounter any unreleased
380 * buffers (e.g. if we do, it's a mistake). if error == 1, we're
381 * in an error-handling case so unreleased buffers may exist.
384 release_dir2_cursor_int(xfs_mount_t
*mp
,
385 dir2_bt_cursor_t
*cursor
,
389 int level
= prev_level
+ 1;
391 if (cursor
->level
[level
].bp
!= NULL
) {
393 do_warn(_("release_dir2_cursor_int got unexpected "
394 "non-null bp, dabno = %u\n"),
395 cursor
->level
[level
].bno
);
399 da_brelse(cursor
->level
[level
].bp
);
400 cursor
->level
[level
].bp
= NULL
;
403 if (level
< cursor
->active
)
404 release_dir2_cursor_int(mp
, cursor
, level
, error
);
410 release_dir2_cursor(xfs_mount_t
*mp
,
411 dir2_bt_cursor_t
*cursor
,
414 release_dir2_cursor_int(mp
, cursor
, prev_level
, 0);
418 err_release_dir2_cursor(xfs_mount_t
*mp
,
419 dir2_bt_cursor_t
*cursor
,
422 release_dir2_cursor_int(mp
, cursor
, prev_level
, 1);
426 * make sure that all entries in all blocks along the right side of
427 * of the tree are used and hashval's are consistent. level is the
428 * level of the descendent block. returns 0 if good (even if it had
429 * to be fixed up), and 1 if bad. The right edge of the tree is
430 * technically a block boundary. This routine should be used then
431 * instead of verify_dir2_path().
434 verify_final_dir2_path(xfs_mount_t
*mp
,
435 dir2_bt_cursor_t
*cursor
,
438 xfs_da_intnode_t
*node
;
441 int this_level
= p_level
+ 1;
444 * the index should point to the next "unprocessed" entry
445 * in the block which should be the final (rightmost) entry
447 entry
= cursor
->level
[this_level
].index
;
448 node
= (xfs_da_intnode_t
*)(cursor
->level
[this_level
].bp
->data
);
450 * check internal block consistency on this level -- ensure
451 * that all entries are used, encountered and expected hashvals
454 if (entry
!= INT_GET(node
->hdr
.count
, ARCH_CONVERT
) - 1) {
456 _("directory block used/count inconsistency - %d / %hu\n"),
457 entry
, INT_GET(node
->hdr
.count
, ARCH_CONVERT
));
461 * hash values monotonically increasing ???
463 if (cursor
->level
[this_level
].hashval
>=
464 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
465 do_warn(_("directory/attribute block hashvalue inconsistency, "
466 "expected > %u / saw %u\n"),
467 cursor
->level
[this_level
].hashval
,
468 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
));
471 if (INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
) != 0) {
472 do_warn(_("bad directory/attribute forward block pointer, "
473 "expected 0, saw %u\n"),
474 INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
));
478 do_warn(_("bad directory block in inode %llu\n"), cursor
->ino
);
482 * keep track of greatest block # -- that gets
483 * us the length of the directory
485 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
486 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
489 * ok, now check descendant block number against this level
491 if (cursor
->level
[p_level
].bno
!=
492 INT_GET(node
->btree
[entry
].before
, ARCH_CONVERT
)) {
496 if (cursor
->level
[p_level
].hashval
!=
497 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
499 do_warn(_("correcting bad hashval in non-leaf dir "
500 "block\n\tin (level %d) in inode %llu.\n"),
501 this_level
, cursor
->ino
);
502 INT_SET(node
->btree
[entry
].hashval
, ARCH_CONVERT
,
503 cursor
->level
[p_level
].hashval
);
504 cursor
->level
[this_level
].dirty
++;
506 do_warn(_("would correct bad hashval in non-leaf dir "
507 "block\n\tin (level %d) in inode %llu.\n"),
508 this_level
, cursor
->ino
);
513 * release/write buffer
515 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
516 (cursor
->level
[this_level
].dirty
&& !no_modify
));
518 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
519 da_bwrite(mp
, cursor
->level
[this_level
].bp
);
521 da_brelse(cursor
->level
[this_level
].bp
);
523 cursor
->level
[this_level
].bp
= NULL
;
526 * bail out if this is the root block (top of tree)
528 if (this_level
>= cursor
->active
) {
532 * set hashvalue to correctl reflect the now-validated
533 * last entry in this block and continue upwards validation
535 cursor
->level
[this_level
].hashval
=
536 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
);
538 return(verify_final_dir2_path(mp
, cursor
, this_level
));
542 * Verifies the path from a descendant block up to the root.
543 * Should be called when the descendant level traversal hits
544 * a block boundary before crossing the boundary (reading in a new
547 * the directory/attr btrees work differently to the other fs btrees.
548 * each interior block contains records that are <hashval, bno>
549 * pairs. The bno is a file bno, not a filesystem bno. The last
550 * hashvalue in the block <bno> will be <hashval>. BUT unlike
551 * the freespace btrees, the *last* value in each block gets
552 * propagated up the tree instead of the first value in each block.
553 * that is, the interior records point to child blocks and the *greatest*
554 * hash value contained by the child block is the one the block above
555 * uses as the key for the child block.
557 * level is the level of the descendent block. returns 0 if good,
558 * and 1 if bad. The descendant block may be a leaf block.
560 * the invariant here is that the values in the cursor for the
561 * levels beneath this level (this_level) and the cursor index
562 * for this level *must* be valid.
564 * that is, the hashval/bno info is accurate for all
565 * DESCENDANTS and match what the node[index] information
566 * for the current index in the cursor for this level.
568 * the index values in the cursor for the descendant level
569 * are allowed to be off by one as they will reflect the
570 * next entry at those levels to be processed.
572 * the hashvalue for the current level can't be set until
573 * we hit the last entry in the block so, it's garbage
574 * until set by this routine.
576 * bno and bp for the current block/level are always valid
577 * since they have to be set so we can get a buffer for the
581 verify_dir2_path(xfs_mount_t
*mp
,
582 dir2_bt_cursor_t
*cursor
,
585 xfs_da_intnode_t
*node
;
586 xfs_da_intnode_t
*newnode
;
591 int this_level
= p_level
+ 1;
596 * index is currently set to point to the entry that
597 * should be processed now in this level.
599 entry
= cursor
->level
[this_level
].index
;
600 node
= cursor
->level
[this_level
].bp
->data
;
603 * if this block is out of entries, validate this
604 * block and move on to the next block.
605 * and update cursor value for said level
607 if (entry
>= INT_GET(node
->hdr
.count
, ARCH_CONVERT
)) {
609 * update the hash value for this level before
610 * validating it. bno value should be ok since
611 * it was set when the block was first read in.
613 cursor
->level
[this_level
].hashval
=
614 INT_GET(node
->btree
[entry
- 1].hashval
, ARCH_CONVERT
);
617 * keep track of greatest block # -- that gets
618 * us the length of the directory
620 if (cursor
->level
[this_level
].bno
> cursor
->greatest_bno
)
621 cursor
->greatest_bno
= cursor
->level
[this_level
].bno
;
624 * validate the path for the current used-up block
627 if (verify_dir2_path(mp
, cursor
, this_level
))
630 * ok, now get the next buffer and check sibling pointers
632 dabno
= INT_GET(node
->hdr
.info
.forw
, ARCH_CONVERT
);
634 nex
= blkmap_getn(cursor
->blkmap
, dabno
, mp
->m_dirblkfsbs
,
637 do_warn(_("can't get map info for block %u of "
638 "directory inode %llu\n"),
643 bp
= da_read_buf(mp
, nex
, bmp
);
646 do_warn(_("can't read block %u for directory inode "
654 * verify magic number and back pointer, sanity-check
655 * entry count, verify level
658 if (XFS_DA_NODE_MAGIC
!=
659 INT_GET(newnode
->hdr
.info
.magic
, ARCH_CONVERT
)) {
660 do_warn(_("bad magic number %x in block %u for "
661 "directory inode %llu\n"),
662 INT_GET(newnode
->hdr
.info
.magic
, ARCH_CONVERT
),
666 if (INT_GET(newnode
->hdr
.info
.back
, ARCH_CONVERT
) !=
667 cursor
->level
[this_level
].bno
) {
668 do_warn(_("bad back pointer in block %u for directory "
673 if (INT_GET(newnode
->hdr
.count
, ARCH_CONVERT
) >
674 mp
->m_dir_node_ents
) {
675 do_warn(_("entry count %d too large in block %u for "
676 "directory inode %llu\n"),
677 INT_GET(newnode
->hdr
.count
, ARCH_CONVERT
),
681 if (INT_GET(newnode
->hdr
.level
, ARCH_CONVERT
) != this_level
) {
682 do_warn(_("bad level %d in block %u for directory "
684 INT_GET(newnode
->hdr
.level
, ARCH_CONVERT
),
693 * update cursor, write out the *current* level if
694 * required. don't write out the descendant level
696 ASSERT(cursor
->level
[this_level
].dirty
== 0 ||
697 (cursor
->level
[this_level
].dirty
&& !no_modify
));
699 if (cursor
->level
[this_level
].dirty
&& !no_modify
)
700 da_bwrite(mp
, cursor
->level
[this_level
].bp
);
702 da_brelse(cursor
->level
[this_level
].bp
);
703 cursor
->level
[this_level
].bp
= bp
;
704 cursor
->level
[this_level
].dirty
= 0;
705 cursor
->level
[this_level
].bno
= dabno
;
706 cursor
->level
[this_level
].hashval
=
707 INT_GET(newnode
->btree
[0].hashval
, ARCH_CONVERT
);
710 entry
= cursor
->level
[this_level
].index
= 0;
713 * ditto for block numbers
715 if (cursor
->level
[p_level
].bno
!=
716 INT_GET(node
->btree
[entry
].before
, ARCH_CONVERT
)) {
720 * ok, now validate last hashvalue in the descendant
721 * block against the hashval in the current entry
723 if (cursor
->level
[p_level
].hashval
!=
724 INT_GET(node
->btree
[entry
].hashval
, ARCH_CONVERT
)) {
726 do_warn(_("correcting bad hashval in interior dir "
727 "block\n\tin (level %d) in inode %llu.\n"),
728 this_level
, cursor
->ino
);
729 INT_SET(node
->btree
[entry
].hashval
, ARCH_CONVERT
,
730 cursor
->level
[p_level
].hashval
);
731 cursor
->level
[this_level
].dirty
++;
733 do_warn(_("would correct bad hashval in interior dir "
734 "block\n\tin (level %d) in inode %llu.\n"),
735 this_level
, cursor
->ino
);
739 * increment index for this level to point to next entry
740 * (which should point to the next descendant block)
742 cursor
->level
[this_level
].index
++;
747 * Fix up a shortform directory which was in long form (i8count set)
748 * and is now in short form (i8count clear).
749 * Return pointer to the end of the data when done.
752 process_sf_dir2_fixi8(
754 xfs_dir2_sf_entry_t
**next_sfep
)
757 xfs_dir2_sf_t
*newsfp
;
758 xfs_dir2_sf_entry_t
*newsfep
;
759 xfs_dir2_sf_t
*oldsfp
;
760 xfs_dir2_sf_entry_t
*oldsfep
;
764 oldsize
= (__psint_t
)*next_sfep
- (__psint_t
)sfp
;
765 oldsfp
= malloc(oldsize
);
766 if (oldsfp
== NULL
) {
767 do_error(_("couldn't malloc dir2 shortform copy\n"));
770 memmove(oldsfp
, newsfp
, oldsize
);
771 INT_SET(newsfp
->hdr
.count
, ARCH_CONVERT
,
772 INT_GET(oldsfp
->hdr
.count
, ARCH_CONVERT
));
773 newsfp
->hdr
.i8count
= 0;
774 ino
= XFS_DIR2_SF_GET_INUMBER_ARCH(oldsfp
,
775 &oldsfp
->hdr
.parent
, ARCH_CONVERT
);
776 XFS_DIR2_SF_PUT_INUMBER_ARCH(newsfp
, &ino
,
777 &newsfp
->hdr
.parent
, ARCH_CONVERT
);
778 oldsfep
= XFS_DIR2_SF_FIRSTENTRY(oldsfp
);
779 newsfep
= XFS_DIR2_SF_FIRSTENTRY(newsfp
);
780 while ((int)((char *)oldsfep
- (char *)oldsfp
) < oldsize
) {
781 newsfep
->namelen
= oldsfep
->namelen
;
782 XFS_DIR2_SF_PUT_OFFSET_ARCH(newsfep
,
783 XFS_DIR2_SF_GET_OFFSET_ARCH(oldsfep
, ARCH_CONVERT
),
785 memmove(newsfep
->name
, oldsfep
->name
, newsfep
->namelen
);
786 ino
= XFS_DIR2_SF_GET_INUMBER_ARCH(oldsfp
,
787 XFS_DIR2_SF_INUMBERP(oldsfep
), ARCH_CONVERT
);
788 XFS_DIR2_SF_PUT_INUMBER_ARCH(newsfp
, &ino
,
789 XFS_DIR2_SF_INUMBERP(newsfep
), ARCH_CONVERT
);
790 oldsfep
= XFS_DIR2_SF_NEXTENTRY(oldsfp
, oldsfep
);
791 newsfep
= XFS_DIR2_SF_NEXTENTRY(newsfp
, newsfep
);
793 *next_sfep
= newsfep
;
798 * Regenerate legal (minimal) offsets for the shortform directory.
801 process_sf_dir2_fixoff(
806 xfs_dir2_sf_entry_t
*sfep
;
809 for (i
= 0, sfp
= &dip
->di_u
.di_dir2sf
,
810 sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
),
811 offset
= XFS_DIR2_DATA_FIRST_OFFSET
;
812 i
< INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
);
813 i
++, sfep
= XFS_DIR2_SF_NEXTENTRY(sfp
, sfep
)) {
814 XFS_DIR2_SF_PUT_OFFSET_ARCH(sfep
, offset
, ARCH_CONVERT
);
815 offset
+= XFS_DIR2_DATA_ENTSIZE(sfep
->namelen
);
820 * this routine performs inode discovery and tries to fix things
821 * in place. available redundancy -- inode data size should match
822 * used directory space in inode.
823 * a non-zero return value means the directory is bogus and should be blasted.
832 int *dino_dirty
, /* out - 1 if dinode buffer dirty */
833 char *dirname
, /* directory pathname */
834 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
835 int *repair
) /* out - 1 if dir was fixed up */
841 __int64_t ino_dir_size
;
843 ino_tree_node_t
*irec_p
;
845 char *junkreason
= NULL
;
848 char name
[MAXNAMELEN
+ 1];
850 xfs_dir2_sf_entry_t
*next_sfep
;
854 xfs_dir2_sf_entry_t
*sfep
;
857 xfs_dir2_sf_entry_t
*tmp_sfep
;
860 sfp
= &dip
->di_u
.di_dir2sf
;
861 max_size
= XFS_DFORK_DSIZE_ARCH(dip
, mp
, ARCH_CONVERT
);
862 num_entries
= INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
);
863 ino_dir_size
= INT_GET(dip
->di_core
.di_size
, ARCH_CONVERT
);
864 offset
= XFS_DIR2_DATA_FIRST_OFFSET
;
865 bad_offset
= *repair
= 0;
867 ASSERT(ino_dir_size
<= max_size
);
870 * Initialize i8 based on size of parent inode number.
872 i8
= (XFS_DIR2_SF_GET_INUMBER_ARCH(sfp
, &sfp
->hdr
.parent
, ARCH_CONVERT
)
873 > XFS_DIR2_MAX_SHORT_INUM
);
876 * check for bad entry count
878 if (num_entries
* XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
, 1) +
879 XFS_DIR2_SF_HDR_SIZE(0) > max_size
||
884 * run through entries, stop at first bad entry, don't need
885 * to check for .. since that's encoded in its own field
887 sfep
= next_sfep
= XFS_DIR2_SF_FIRSTENTRY(sfp
);
889 i
< num_entries
&& ino_dir_size
> (char *)next_sfep
- (char *)sfp
;
895 lino
= XFS_DIR2_SF_GET_INUMBER_ARCH(sfp
,
896 XFS_DIR2_SF_INUMBERP(sfep
), ARCH_CONVERT
);
898 * if entry points to self, junk it since only '.' or '..'
899 * should do that and shortform dirs don't contain either
900 * entry. if inode number is invalid, trash entry.
901 * if entry points to special inodes, trash it.
902 * if inode is unknown but number is valid,
903 * add it to the list of uncertain inodes. don't
904 * have to worry about an entry pointing to a
905 * deleted lost+found inode because the entry was
906 * deleted at the same time that the inode was cleared.
910 junkreason
= _("current");
911 } else if (verify_inum(mp
, lino
)) {
913 junkreason
= _("invalid");
914 } else if (lino
== mp
->m_sb
.sb_rbmino
) {
916 junkreason
= _("realtime bitmap");
917 } else if (lino
== mp
->m_sb
.sb_rsumino
) {
919 junkreason
= _("realtime summary");
920 } else if (lino
== mp
->m_sb
.sb_uquotino
) {
922 junkreason
= _("user quota");
923 } else if (lino
== mp
->m_sb
.sb_gquotino
) {
925 junkreason
= _("group quota");
926 } else if ((irec_p
= find_inode_rec(XFS_INO_TO_AGNO(mp
, lino
),
927 XFS_INO_TO_AGINO(mp
, lino
))) != NULL
) {
929 * if inode is marked free and we're in inode
930 * discovery mode, leave the entry alone for now.
931 * if the inode turns out to be used, we'll figure
932 * that out when we scan it. If the inode really
933 * is free, we'll hit this code again in phase 4
934 * after we've finished inode discovery and blow
935 * out the entry then.
937 ino_off
= XFS_INO_TO_AGINO(mp
, lino
) -
938 irec_p
->ino_startnum
;
939 ASSERT(is_inode_confirmed(irec_p
, ino_off
));
940 if (is_inode_free(irec_p
, ino_off
) && !ino_discovery
) {
942 junkreason
= _("free");
944 } else if (ino_discovery
) {
946 * put the inode on the uncertain list. we'll
947 * pull the inode off the list and check it later.
948 * if the inode turns out be bogus, we'll delete
949 * this entry in phase 6.
951 add_inode_uncertain(mp
, lino
, 0);
954 * blow the entry out. we know about all
955 * undiscovered entries now (past inode discovery
956 * phase) so this is clearly a bogus entry.
959 junkreason
= _("non-existent");
961 namelen
= sfep
->namelen
;
963 do_warn(_("entry \"%*.*s\" in shortform directory %llu "
964 "references %s inode %llu\n"),
965 namelen
, namelen
, sfep
->name
, ino
, junkreason
,
969 * if we're really lucky, this is
970 * the last entry in which case we
971 * can use the dir size to set the
972 * namelen value. otherwise, forget
973 * it because we're not going to be
974 * able to find the next entry.
978 if (i
== num_entries
- 1) {
979 namelen
= ino_dir_size
-
980 ((__psint_t
) &sfep
->name
[0] -
983 do_warn(_("zero length entry in "
984 "shortform dir %llu, "
985 "resetting to %d\n"),
987 sfep
->namelen
= namelen
;
989 do_warn(_("zero length entry in "
990 "shortform dir %llu, "
991 "would set to %d\n"),
995 do_warn(_("zero length entry in shortform dir "
999 do_warn(_(", junking %d entries\n"),
1002 do_warn(_(", would junk %d entries\n"),
1005 * don't process the rest of the directory,
1006 * break out of processing looop
1010 } else if ((__psint_t
) sfep
- (__psint_t
) sfp
+
1011 + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
)
1015 if (i
== num_entries
- 1) {
1016 namelen
= ino_dir_size
-
1017 ((__psint_t
) &sfep
->name
[0] -
1019 do_warn(_("size of last entry overflows space "
1020 "left in in shortform dir %llu, "),
1023 do_warn(_("resetting to %d\n"),
1025 sfep
->namelen
= namelen
;
1028 do_warn(_("would reset to %d\n"),
1032 do_warn(_("size of entry #%d overflows space "
1033 "left in in shortform dir %llu\n"),
1036 if (i
== num_entries
- 1)
1038 _("junking entry #%d\n"),
1042 _("junking %d entries\n"),
1045 if (i
== num_entries
- 1)
1047 _("would junk entry #%d\n"),
1051 _("would junk %d entries\n"),
1060 * check for illegal chars in name.
1061 * no need to check for bad length because
1062 * the length value is stored in a byte
1063 * so it can't be too big, it can only wrap
1065 if (namecheck((char *)&sfep
->name
[0], namelen
)) {
1069 do_warn(_("entry contains illegal character "
1070 "in shortform dir %llu\n"),
1075 if (XFS_DIR2_SF_GET_OFFSET_ARCH(sfep
, ARCH_CONVERT
) < offset
) {
1076 do_warn(_("entry contains offset out of order in "
1077 "shortform dir %llu\n"),
1081 offset
= XFS_DIR2_SF_GET_OFFSET_ARCH(sfep
, ARCH_CONVERT
) +
1082 XFS_DIR2_DATA_ENTSIZE(namelen
);
1085 * junk the entry by copying up the rest of the
1086 * fork over the current entry and decrementing
1087 * the entry count. if we're in no_modify mode,
1088 * just issue the warning instead. then continue
1089 * the loop with the next_sfep pointer set to the
1090 * correct place in the fork and other counters
1091 * properly set to reflect the deletion if it
1095 bcopy(sfep
->name
, name
, namelen
);
1096 name
[namelen
] = '\0';
1100 XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
, sfep
);
1101 INT_MOD(dip
->di_core
.di_size
, ARCH_CONVERT
,
1103 ino_dir_size
-= tmp_elen
;
1105 tmp_sfep
= (xfs_dir2_sf_entry_t
*)
1106 ((__psint_t
) sfep
+ tmp_elen
);
1107 tmp_len
= max_size
- ((__psint_t
) tmp_sfep
1110 memmove(sfep
, tmp_sfep
, tmp_len
);
1112 INT_MOD(sfp
->hdr
.count
, ARCH_CONVERT
, -1);
1114 bzero((void *) ((__psint_t
) sfep
+ tmp_len
),
1118 * reset the tmp value to the current
1119 * pointer so we'll process the entry
1125 * WARNING: drop the index i by one
1126 * so it matches the decremented count
1127 * for accurate comparisons later
1134 do_warn(_("junking entry \"%s\" in directory "
1138 do_warn(_("would have junked entry \"%s\" in "
1139 "directory inode %llu\n"),
1142 } else if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
1145 * go onto next entry unless we've just junked an
1146 * entry in which the current entry pointer points
1147 * to an unprocessed entry. have to take into zero-len
1148 * entries into account in no modify mode since we
1149 * calculate size based on next_sfep.
1151 next_sfep
= (tmp_sfep
== NULL
)
1152 ? (xfs_dir2_sf_entry_t
*) ((__psint_t
) sfep
1154 ? XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp
,
1156 : XFS_DIR2_SF_ENTSIZE_BYNAME(sfp
,
1161 /* sync up sizes and entry counts */
1163 if (INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) != i
) {
1165 do_warn(_("would have corrected entry count "
1166 "in directory %llu from %d to %d\n"),
1167 ino
, INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
), i
);
1169 do_warn(_("corrected entry count in directory %llu, "
1170 "was %d, now %d\n"),
1171 ino
, INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
), i
);
1172 INT_SET(sfp
->hdr
.count
, ARCH_CONVERT
, i
);
1178 if (sfp
->hdr
.i8count
!= i8
) {
1180 do_warn(_("would have corrected i8 count in directory "
1181 "%llu from %d to %d\n"),
1182 ino
, sfp
->hdr
.i8count
, i8
);
1184 do_warn(_("corrected i8 count in directory %llu, "
1185 "was %d, now %d\n"),
1186 ino
, sfp
->hdr
.i8count
, i8
);
1188 process_sf_dir2_fixi8(sfp
, &next_sfep
);
1190 sfp
->hdr
.i8count
= i8
;
1196 if ((__psint_t
) next_sfep
- (__psint_t
) sfp
!= ino_dir_size
) {
1198 do_warn(_("would have corrected directory %llu size "
1199 "from %lld to %lld\n"),
1200 ino
, (__int64_t
) ino_dir_size
,
1201 (__int64_t
)((__psint_t
)next_sfep
-
1204 do_warn(_("corrected directory %llu size, was %lld, "
1206 ino
, (__int64_t
) ino_dir_size
,
1207 (__int64_t
)((__psint_t
)next_sfep
-
1210 INT_SET(dip
->di_core
.di_size
, ARCH_CONVERT
,
1211 (xfs_fsize_t
)((__psint_t
)next_sfep
-
1218 (INT_GET(sfp
->hdr
.count
, ARCH_CONVERT
) + 2) *
1219 sizeof(xfs_dir2_leaf_entry_t
) +
1220 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dirblksize
) {
1221 do_warn(_("directory %llu offsets too high\n"), ino
);
1226 do_warn(_("would have corrected entry offsets in "
1227 "directory %llu\n"),
1230 do_warn(_("corrected entry offsets in "
1231 "directory %llu\n"),
1233 process_sf_dir2_fixoff(dip
);
1240 * check parent (..) entry
1242 *parent
= XFS_DIR2_SF_GET_INUMBER_ARCH(sfp
,
1243 &sfp
->hdr
.parent
, ARCH_CONVERT
);
1246 * if parent entry is bogus, null it out. we'll fix it later .
1248 if (verify_inum(mp
, *parent
)) {
1250 do_warn(_("bogus .. inode number (%llu) in directory inode "
1253 *parent
= NULLFSINO
;
1255 do_warn(_("clearing inode number\n"));
1257 XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp
, &zero
,
1258 &sfp
->hdr
.parent
, ARCH_CONVERT
);
1262 do_warn(_("would clear inode number\n"));
1264 } else if (ino
== mp
->m_sb
.sb_rootino
&& ino
!= *parent
) {
1266 * root directories must have .. == .
1269 do_warn(_("corrected root directory %llu .. entry, "
1270 "was %llu, now %llu\n"),
1273 XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp
, parent
,
1274 &sfp
->hdr
.parent
, ARCH_CONVERT
);
1278 do_warn(_("would have corrected root directory %llu .. "
1279 "entry from %llu to %llu\n"),
1282 } else if (ino
== *parent
&& ino
!= mp
->m_sb
.sb_rootino
) {
1284 * likewise, non-root directories can't have .. pointing
1287 *parent
= NULLFSINO
;
1288 do_warn(_("bad .. entry in directory inode %llu, points to "
1292 do_warn(_("clearing inode number\n"));
1294 XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp
, &zero
,
1295 &sfp
->hdr
.parent
, ARCH_CONVERT
);
1299 do_warn(_("would clear inode number\n"));
1307 * Process one directory data block.
1316 char *dirname
, /* directory pathname */
1317 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1319 int *dot
, /* out - 1 if there is a dot, else 0 */
1320 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1325 xfs_dir2_data_free_t
*bf
;
1327 char *clearreason
= NULL
;
1329 xfs_dir2_data_entry_t
*dep
;
1330 xfs_dir2_data_free_t
*dfp
;
1331 xfs_dir2_data_unused_t
*dup
;
1335 ino_tree_node_t
*irec_p
;
1342 bf
= d
->hdr
.bestfree
;
1344 badbest
= lastfree
= freeseen
= 0;
1345 if (INT_GET(bf
[0].length
, ARCH_CONVERT
) == 0) {
1346 badbest
|= INT_GET(bf
[0].offset
, ARCH_CONVERT
) != 0;
1349 if (INT_GET(bf
[1].length
, ARCH_CONVERT
) == 0) {
1350 badbest
|= INT_GET(bf
[1].offset
, ARCH_CONVERT
) != 0;
1353 if (INT_GET(bf
[2].length
, ARCH_CONVERT
) == 0) {
1354 badbest
|= INT_GET(bf
[2].offset
, ARCH_CONVERT
) != 0;
1357 badbest
|= INT_GET(bf
[0].length
, ARCH_CONVERT
) < INT_GET(bf
[1].length
, ARCH_CONVERT
);
1358 badbest
|= INT_GET(bf
[1].length
, ARCH_CONVERT
) < INT_GET(bf
[2].length
, ARCH_CONVERT
);
1359 while (ptr
< endptr
) {
1360 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1362 * If it's unused, look for the space in the bestfree table.
1363 * If we find it, account for that, else make sure it doesn't
1366 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) == XFS_DIR2_DATA_FREE_TAG
) {
1367 if (ptr
+ INT_GET(dup
->length
, ARCH_CONVERT
) > endptr
||
1368 INT_GET(dup
->length
, ARCH_CONVERT
) == 0 ||
1369 (INT_GET(dup
->length
, ARCH_CONVERT
) & (XFS_DIR2_DATA_ALIGN
- 1)))
1371 if (INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P_ARCH(dup
,
1372 ARCH_CONVERT
), ARCH_CONVERT
) !=
1373 (char *)dup
- (char *)d
)
1375 badbest
|= lastfree
!= 0;
1376 dfp
= xfs_dir2_data_freefind(d
, dup
);
1379 badbest
|= (freeseen
& (1 << i
)) != 0;
1382 badbest
|= INT_GET(dup
->length
, ARCH_CONVERT
) >
1383 INT_GET(bf
[2].length
, ARCH_CONVERT
);
1384 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1388 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1389 if (ptr
+ XFS_DIR2_DATA_ENTSIZE(dep
->namelen
) > endptr
)
1391 if (INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep
), ARCH_CONVERT
) !=
1392 (char *)dep
- (char *)d
)
1394 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1398 * Dropped out before we processed everything, give up.
1399 * Phase 6 will kill this block if we don't kill the inode.
1401 if (ptr
!= endptr
) {
1402 do_warn(_("corrupt block %u in directory inode %llu\n"),
1405 do_warn(_("\twill junk block\n"));
1407 do_warn(_("\twould junk block\n"));
1412 * Process the entries now.
1414 while (ptr
< endptr
) {
1415 dup
= (xfs_dir2_data_unused_t
*)ptr
;
1416 if (INT_GET(dup
->freetag
, ARCH_CONVERT
) ==
1417 XFS_DIR2_DATA_FREE_TAG
) {
1418 ptr
+= INT_GET(dup
->length
, ARCH_CONVERT
);
1421 dep
= (xfs_dir2_data_entry_t
*)ptr
;
1423 * We may have to blow out an entry because of bad inode
1424 * numbers. Do NOT touch the name until after we've computed
1425 * the hashvalue and done a namecheck() on the name.
1427 if (!ino_discovery
&&
1428 INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
) {
1430 * Don't do a damned thing. We already found this
1431 * (or did it ourselves) during phase 3.
1434 } else if (verify_inum(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
))) {
1436 * Bad inode number. Clear the inode number and the
1437 * entry will get removed later. We don't trash the
1438 * directory since it's still structurally intact.
1441 clearreason
= _("invalid");
1442 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_rbmino
) {
1444 clearreason
= _("realtime bitmap");
1445 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_rsumino
) {
1447 clearreason
= _("realtime summary");
1448 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_uquotino
) {
1450 clearreason
= _("user quota");
1451 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == mp
->m_sb
.sb_gquotino
) {
1453 clearreason
= _("group quota");
1454 } else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == old_orphanage_ino
) {
1456 * Do nothing, silently ignore it, entry has already
1457 * been marked TBD since old_orphanage_ino is set
1461 } else if ((irec_p
= find_inode_rec(
1462 XFS_INO_TO_AGNO(mp
, INT_GET(dep
->inumber
,
1464 XFS_INO_TO_AGINO(mp
, INT_GET(dep
->inumber
,
1465 ARCH_CONVERT
)))) != NULL
) {
1467 * Inode recs should have only confirmed inodes in them.
1469 ino_off
= XFS_INO_TO_AGINO(mp
, INT_GET(dep
->inumber
,
1470 ARCH_CONVERT
)) - irec_p
->ino_startnum
;
1471 ASSERT(is_inode_confirmed(irec_p
, ino_off
));
1473 * If inode is marked free and we're in inode discovery
1474 * mode, leave the entry alone for now. If the inode
1475 * turns out to be used, we'll figure that out when we
1476 * scan it. If the inode really is free, we'll hit this
1477 * code again in phase 4 after we've finished inode
1478 * discovery and blow out the entry then.
1480 if (!ino_discovery
&& is_inode_free(irec_p
, ino_off
)) {
1482 clearreason
= _("free");
1485 } else if (ino_discovery
) {
1486 add_inode_uncertain(mp
, INT_GET(dep
->inumber
, ARCH_CONVERT
), 0);
1490 clearreason
= _("non-existent");
1493 do_warn(_("entry \"%*.*s\" at block %u offset %d in "
1494 "directory inode %llu references %s inode "
1496 dep
->namelen
, dep
->namelen
, dep
->name
,
1497 da_bno
, (char *)ptr
- (char *)d
, ino
,
1499 INT_GET(dep
->inumber
, ARCH_CONVERT
));
1501 * If the name length is 0 (illegal) make it 1 and blast
1504 if (dep
->namelen
== 0) {
1505 do_warn(_("entry at block %u offset %d in directory "
1506 "inode %llu has 0 namelength\n"),
1507 da_bno
, (char *)ptr
- (char *)d
, ino
);
1513 * If needed to clear the inode number, do it now.
1517 do_warn(_("\tclearing inode number in entry at "
1519 (char *)ptr
- (char *)d
);
1520 INT_SET(dep
->inumber
, ARCH_CONVERT
, BADFSINO
);
1523 do_warn(_("\twould clear inode number in entry "
1524 "at offset %d...\n"),
1525 (char *)ptr
- (char *)d
);
1529 * Only complain about illegal names in phase 3 (when inode
1530 * discovery is turned on). Otherwise, we'd complain a lot
1533 junkit
= INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
;
1534 nm_illegal
= namecheck((char *)dep
->name
, dep
->namelen
);
1535 if (ino_discovery
&& nm_illegal
) {
1536 do_warn(_("entry at block %u offset %d in directory "
1537 "inode %llu has illegal name \"%*.*s\": "),
1538 da_bno
, (char *)ptr
- (char *)d
, ino
,
1539 dep
->namelen
, dep
->namelen
, dep
->name
);
1543 * Now we can mark entries with BADFSINO's bad.
1546 INT_GET(dep
->inumber
, ARCH_CONVERT
) == BADFSINO
) {
1552 * Special .. entry processing.
1554 if (dep
->namelen
== 2 &&
1555 dep
->name
[0] == '.' && dep
->name
[1] == '.') {
1558 *parent
= INT_GET(dep
->inumber
, ARCH_CONVERT
);
1560 * What if .. == .? Legal only in the root
1561 * inode. Blow out entry and set parent to
1562 * NULLFSINO otherwise.
1564 if (ino
== INT_GET(dep
->inumber
, ARCH_CONVERT
) &&
1565 ino
!= mp
->m_sb
.sb_rootino
) {
1566 *parent
= NULLFSINO
;
1567 do_warn(_("bad .. entry in directory "
1568 "inode %llu, points to self: "),
1573 * We have to make sure that . == .. in the
1576 else if (ino
!= INT_GET(dep
->inumber
, ARCH_CONVERT
) &&
1577 ino
== mp
->m_sb
.sb_rootino
) {
1578 do_warn(_("bad .. entry in root "
1579 "directory inode %llu, was "
1581 ino
, INT_GET(dep
->inumber
, ARCH_CONVERT
));
1583 do_warn(_("correcting\n"));
1584 INT_SET(dep
->inumber
, ARCH_CONVERT
, ino
);
1587 do_warn(_("would correct\n"));
1592 * Can't fix the directory unless we know which ..
1593 * entry is the right one. Both have valid inode
1594 * numbers or we wouldn't be here. So since both
1595 * seem equally valid, trash this one.
1598 do_warn(_("multiple .. entries in directory "
1605 * Special . entry processing.
1607 else if (dep
->namelen
== 1 && dep
->name
[0] == '.') {
1610 if (INT_GET(dep
->inumber
, ARCH_CONVERT
) != ino
) {
1611 do_warn(_("bad . entry in directory "
1612 "inode %llu, was %llu: "),
1613 ino
, INT_GET(dep
->inumber
, ARCH_CONVERT
));
1615 do_warn(_("correcting\n"));
1616 INT_SET(dep
->inumber
, ARCH_CONVERT
, ino
);
1619 do_warn(_("would correct\n"));
1623 do_warn(_("multiple . entries in directory "
1630 * All other entries -- make sure only . references self.
1632 else if (INT_GET(dep
->inumber
, ARCH_CONVERT
) == ino
) {
1633 do_warn(_("entry \"%*.*s\" in directory inode %llu "
1634 "points to self: "),
1635 dep
->namelen
, dep
->namelen
, dep
->name
, ino
);
1639 * Clear junked entries.
1645 do_warn(_("clearing entry\n"));
1647 do_warn(_("would clear entry\n"));
1651 * Advance to the next entry.
1653 ptr
+= XFS_DIR2_DATA_ENTSIZE(dep
->namelen
);
1656 * Check the bestfree table.
1658 if (freeseen
!= 7 || badbest
) {
1659 do_warn(_("bad bestfree table in block %u in directory inode "
1663 do_warn(_("repairing table\n"));
1664 libxfs_dir2_data_freescan(mp
, d
, &i
, endptr
);
1667 do_warn(_("would repair table\n"));
1674 * Process a block-format directory.
1683 int *dino_dirty
, /* out - 1 if dinode buffer dirty */
1684 char *dirname
, /* directory pathname */
1685 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1687 int *dot
, /* out - 1 if there is a dot, else 0 */
1688 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1689 int *repair
) /* out - 1 if something was fixed */
1691 xfs_dir2_block_t
*block
;
1692 xfs_dir2_leaf_entry_t
*blp
;
1695 xfs_dir2_block_tail_t
*btp
;
1699 *repair
= *dot
= *dotdot
= 0;
1700 *parent
= NULLFSINO
;
1701 nex
= blkmap_getn(blkmap
, mp
->m_dirdatablk
, mp
->m_dirblkfsbs
, &bmp
);
1703 do_warn(_("block %u for directory inode %llu is missing\n"),
1704 mp
->m_dirdatablk
, ino
);
1707 bp
= da_read_buf(mp
, nex
, bmp
);
1710 do_warn(_("can't read block %u for directory inode %llu\n"),
1711 mp
->m_dirdatablk
, ino
);
1718 if (INT_GET(block
->hdr
.magic
, ARCH_CONVERT
) != XFS_DIR2_BLOCK_MAGIC
)
1719 do_warn(_("bad directory block magic # %#x in block %u for "
1720 "directory inode %llu\n"),
1721 INT_GET(block
->hdr
.magic
, ARCH_CONVERT
),
1722 mp
->m_dirdatablk
, ino
);
1724 * process the data area
1725 * this also checks & fixes the bestfree
1727 btp
= XFS_DIR2_BLOCK_TAIL_P(mp
, block
);
1728 blp
= XFS_DIR2_BLOCK_LEAF_P_ARCH(btp
, ARCH_CONVERT
);
1730 * Don't let this go past the end of the block.
1732 if ((char *)blp
> (char *)btp
)
1733 blp
= (xfs_dir2_leaf_entry_t
*)btp
;
1734 rval
= process_dir2_data(mp
, ino
, dip
, ino_discovery
, dirname
, parent
,
1735 bp
, dot
, dotdot
, mp
->m_dirdatablk
, (char *)blp
);
1736 if (bp
->dirty
&& !no_modify
) {
1745 * Validates leaf contents, node format directories only.
1746 * magic number and sibling pointers checked by caller.
1747 * Returns 0 if block is ok, 1 if the block is bad.
1748 * Looking for: out of order hash values, bad stale counts.
1751 process_leaf_block_dir2(
1753 xfs_dir2_leaf_t
*leaf
,
1756 xfs_dahash_t last_hashval
,
1757 xfs_dahash_t
*next_hashval
)
1762 for (i
= stale
= 0; i
< INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
); i
++) {
1763 if ((char *)&leaf
->ents
[i
] >= (char *)leaf
+ mp
->m_dirblksize
) {
1764 do_warn(_("bad entry count in block %u of directory "
1769 if (INT_GET(leaf
->ents
[i
].address
, ARCH_CONVERT
) ==
1770 XFS_DIR2_NULL_DATAPTR
)
1772 else if (INT_GET(leaf
->ents
[i
].hashval
, ARCH_CONVERT
) <
1774 do_warn(_("bad hash ordering in block %u of directory "
1779 *next_hashval
= last_hashval
=
1780 INT_GET(leaf
->ents
[i
].hashval
, ARCH_CONVERT
);
1782 if (stale
!= INT_GET(leaf
->hdr
.stale
, ARCH_CONVERT
)) {
1783 do_warn(_("bad stale count in block %u of directory "
1792 * Returns 0 if the directory is ok, 1 if it has to be rebuilt.
1795 process_leaf_level_dir2(
1797 dir2_bt_cursor_t
*da_cursor
,
1803 xfs_dahash_t current_hashval
;
1805 xfs_dahash_t greatest_hashval
;
1807 xfs_dir2_leaf_t
*leaf
;
1809 xfs_dablk_t prev_bno
;
1811 da_bno
= da_cursor
->level
[0].bno
;
1812 ino
= da_cursor
->ino
;
1815 current_hashval
= 0;
1819 nex
= blkmap_getn(da_cursor
->blkmap
, da_bno
, mp
->m_dirblkfsbs
,
1822 * Directory code uses 0 as the NULL block pointer since 0
1823 * is the root block and no directory block pointer can point
1824 * to the root block of the btree.
1826 ASSERT(da_bno
!= 0);
1829 do_warn(_("can't map block %u for directory "
1834 bp
= da_read_buf(mp
, nex
, bmp
);
1838 do_warn(_("can't read file block %u for directory "
1845 * Check magic number for leaf directory btree block.
1847 if (INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
) !=
1848 XFS_DIR2_LEAFN_MAGIC
) {
1849 do_warn(_("bad directory leaf magic # %#x for "
1850 "directory inode %llu block %u\n"),
1851 INT_GET(leaf
->hdr
.info
.magic
, ARCH_CONVERT
),
1858 * For each block, process the block, verify its path,
1859 * then get next block. Update cursor values along the way.
1861 if (process_leaf_block_dir2(mp
, leaf
, da_bno
, ino
,
1862 current_hashval
, &greatest_hashval
)) {
1867 * Index can be set to hdr.count so match the indices of the
1868 * interior blocks -- which at the end of the block will point
1869 * to 1 after the final real entry in the block.
1871 da_cursor
->level
[0].hashval
= greatest_hashval
;
1872 da_cursor
->level
[0].bp
= bp
;
1873 da_cursor
->level
[0].bno
= da_bno
;
1874 da_cursor
->level
[0].index
=
1875 INT_GET(leaf
->hdr
.count
, ARCH_CONVERT
);
1876 da_cursor
->level
[0].dirty
= buf_dirty
;
1878 if (INT_GET(leaf
->hdr
.info
.back
, ARCH_CONVERT
) != prev_bno
) {
1879 do_warn(_("bad sibling back pointer for block %u in "
1880 "directory inode %llu\n"),
1886 da_bno
= INT_GET(leaf
->hdr
.info
.forw
, ARCH_CONVERT
);
1888 if (verify_dir2_path(mp
, da_cursor
, 0)) {
1893 current_hashval
= greatest_hashval
;
1894 ASSERT(buf_dirty
== 0 || (buf_dirty
&& !no_modify
));
1895 if (buf_dirty
&& !no_modify
) {
1900 } while (da_bno
!= 0);
1901 if (verify_final_dir2_path(mp
, da_cursor
, 0)) {
1903 * Verify the final path up (right-hand-side) if still ok.
1905 do_warn(_("bad hash path in directory %llu\n"), ino
);
1909 * Redundant but just for testing.
1911 release_dir2_cursor(mp
, da_cursor
, 0);
1916 * Release all buffers holding interior btree blocks.
1918 err_release_dir2_cursor(mp
, da_cursor
, 0);
1925 * Return 1 if the directory's leaf/node space is corrupted and
1926 * needs to be rebuilt, 0 if it's ok.
1937 dir2_bt_cursor_t da_cursor
;
1940 * Try again -- traverse down left-side of tree until we hit the
1941 * left-most leaf block setting up the btree cursor along the way.
1942 * Then walk the leaf blocks left-to-right, calling a parent
1943 * verification routine each time we traverse a block.
1945 bzero(&da_cursor
, sizeof(da_cursor
));
1946 da_cursor
.ino
= ino
;
1947 da_cursor
.dip
= dip
;
1948 da_cursor
.blkmap
= blkmap
;
1951 * Now process interior node.
1953 if (traverse_int_dir2block(mp
, &da_cursor
, &bno
) == 0)
1957 * Skip directories with a root marked XFS_DIR2_LEAFN_MAGIC
1960 release_dir2_cursor(mp
, &da_cursor
, 0);
1964 * Now pass cursor and bno into leaf-block processing routine.
1965 * The leaf dir level routine checks the interior paths up to
1966 * the root including the final right-most path.
1968 return process_leaf_level_dir2(mp
, &da_cursor
, repair
);
1973 * Process leaf and node directories.
1974 * Process the data blocks then, if it's a node directory, check
1975 * the consistency of those blocks.
1978 process_leaf_node_dir2(
1983 char *dirname
, /* directory pathname */
1984 xfs_ino_t
*parent
, /* out - NULLFSINO if entry not exist */
1986 int *dot
, /* out - 1 if there is a dot, else 0 */
1987 int *dotdot
, /* out - 1 if there's a dotdot, else 0 */
1988 int *repair
, /* out - 1 if something was fixed */
1989 int isnode
) /* node directory not leaf */
1993 xfs_dir2_data_t
*data
;
1997 xfs_dfiloff_t ndbno
;
2001 *repair
= *dot
= *dotdot
= good
= 0;
2002 *parent
= NULLFSINO
;
2003 ndbno
= NULLDFILOFF
;
2004 while ((dbno
= blkmap_next_off(blkmap
, ndbno
, &t
)) < mp
->m_dirleafblk
) {
2005 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dirblkfsbs
, &bmp
);
2006 ndbno
= dbno
+ mp
->m_dirblkfsbs
- 1;
2008 do_warn(_("block %llu for directory inode %llu is "
2013 bp
= da_read_buf(mp
, nex
, bmp
);
2016 do_warn(_("can't read block %llu for directory inode "
2022 if (INT_GET(data
->hdr
.magic
, ARCH_CONVERT
) !=
2023 XFS_DIR2_DATA_MAGIC
)
2024 do_warn(_("bad directory block magic # %#x in block "
2025 "%llu for directory inode %llu\n"),
2026 INT_GET(data
->hdr
.magic
, ARCH_CONVERT
),
2028 i
= process_dir2_data(mp
, ino
, dip
, ino_discovery
, dirname
,
2029 parent
, bp
, dot
, dotdot
, (xfs_dablk_t
)dbno
,
2030 (char *)data
+ mp
->m_dirblksize
);
2033 if (bp
->dirty
&& !no_modify
) {
2043 if (dir2_is_badino(ino
))
2046 if (process_node_dir2(mp
, ino
, dip
, blkmap
, repair
))
2047 dir2_add_badlist(ino
);
2053 * Returns 1 if things are bad (directory needs to be junked)
2054 * and 0 if things are ok. If ino_discovery is 1, add unknown
2055 * inodes to uncertain inode list.
2074 *parent
= NULLFSINO
;
2079 * branch off depending on the type of inode. This routine
2080 * is only called ONCE so all the subordinate routines will
2081 * fix '.' and junk '..' if they're bogus.
2084 last
= blkmap_last_off(blkmap
);
2085 if (INT_GET(dip
->di_core
.di_size
, ARCH_CONVERT
) <=
2086 XFS_DFORK_DSIZE_ARCH(dip
, mp
, ARCH_CONVERT
) &&
2087 dip
->di_core
.di_format
== XFS_DINODE_FMT_LOCAL
) {
2089 res
= process_sf_dir2(mp
, ino
, dip
, ino_discovery
, dino_dirty
,
2090 dirname
, parent
, &repair
);
2091 } else if (last
== mp
->m_dirblkfsbs
&&
2092 (dip
->di_core
.di_format
== XFS_DINODE_FMT_EXTENTS
||
2093 dip
->di_core
.di_format
== XFS_DINODE_FMT_BTREE
)) {
2094 res
= process_block_dir2(mp
, ino
, dip
, ino_discovery
,
2095 dino_dirty
, dirname
, parent
, blkmap
, &dot
, &dotdot
,
2097 } else if (last
>= mp
->m_dirleafblk
+ mp
->m_dirblkfsbs
&&
2098 (dip
->di_core
.di_format
== XFS_DINODE_FMT_EXTENTS
||
2099 dip
->di_core
.di_format
== XFS_DINODE_FMT_BTREE
)) {
2100 res
= process_leaf_node_dir2(mp
, ino
, dip
, ino_discovery
,
2101 dirname
, parent
, blkmap
, &dot
, &dotdot
, &repair
,
2102 last
> mp
->m_dirleafblk
+ mp
->m_dirblkfsbs
);
2104 do_warn(_("bad size/format for directory %llu\n"), ino
);
2108 * bad . entries in all directories will be fixed up in phase 6
2111 do_warn(_("no . entry for directory %llu\n"), ino
);
2115 * shortform dirs always have a .. entry. .. for all longform
2116 * directories will get fixed in phase 6. .. for other shortform
2117 * dirs also get fixed there. .. for a shortform root was
2118 * fixed in place since we know what it should be
2120 if (dotdot
== 0 && ino
!= mp
->m_sb
.sb_rootino
) {
2121 do_warn(_("no .. entry for directory %llu\n"), ino
);
2122 } else if (dotdot
== 0 && ino
== mp
->m_sb
.sb_rootino
) {
2123 do_warn(_("no .. entry for root directory %llu\n"), ino
);
2124 need_root_dotdot
= 1;
2127 ASSERT((ino
!= mp
->m_sb
.sb_rootino
&& ino
!= *parent
) ||
2128 (ino
== mp
->m_sb
.sb_rootino
&&
2129 (ino
== *parent
|| need_root_dotdot
== 1)));