]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/phase3.c
2 * Copyright (c) 2000-2001 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/
39 #include "err_protos.h"
43 * walks an unlinked list, returns 1 on an error (bogus pointer) or
47 walk_unlinked_list(xfs_mount_t
*mp
, xfs_agnumber_t agno
, xfs_agino_t start_ino
)
51 xfs_agino_t current_ino
= start_ino
;
55 while (current_ino
!= NULLAGINO
) {
56 if (verify_aginum(mp
, agno
, current_ino
))
58 if ((bp
= get_agino_buf(mp
, agno
, current_ino
, &dip
)) == NULL
)
61 * if this looks like a decent inode, then continue
62 * following the unlinked pointers. If not, bail.
64 if (verify_dinode(mp
, dip
, agno
, current_ino
) == 0) {
66 * check if the unlinked list points to an unknown
67 * inode. if so, put it on the uncertain inode list
68 * and set block map appropriately.
70 if (find_inode_rec(agno
, current_ino
) == NULL
) {
71 add_aginode_uncertain(agno
, current_ino
, 1);
72 agbno
= XFS_AGINO_TO_AGBNO(mp
, current_ino
);
74 switch (state
= get_agbno_state(mp
,
79 set_agbno_state(mp
, agno
, agbno
,
84 "bad state in block map %d\n",
90 * the block looks like inodes
91 * so be conservative and try
92 * to scavenge what's in there.
93 * if what's there is completely
94 * bogus, it'll show up later
95 * and the inode will be trashed
96 * anyway, hopefully without
97 * losing too much other data
99 set_agbno_state(mp
, agno
, agbno
,
104 current_ino
= dip
->di_next_unlinked
;
106 current_ino
= NULLAGINO
;;
115 process_agi_unlinked(xfs_mount_t
*mp
, xfs_agnumber_t agno
)
123 bp
= libxfs_readbuf(mp
->m_dev
, XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR
),
124 mp
->m_sb
.sb_sectsize
/BBSIZE
, 0);
126 do_error("cannot read agi block %lld for ag %u\n",
127 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR
), agno
);
131 agip
= XFS_BUF_TO_AGI(bp
);
133 ASSERT(no_modify
|| INT_GET(agip
->agi_seqno
, ARCH_CONVERT
) == agno
);
135 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
136 if (INT_GET(agip
->agi_unlinked
[i
], ARCH_CONVERT
) != NULLAGINO
) {
137 err
+= walk_unlinked_list(mp
, agno
,
138 INT_GET(agip
->agi_unlinked
[i
], ARCH_CONVERT
));
143 INT_SET(agip
->agi_unlinked
[i
], ARCH_CONVERT
, NULLAGINO
);
150 do_warn("error following ag %d unlinked list\n", agno
);
152 ASSERT(agi_dirty
== 0 || (agi_dirty
&& !no_modify
));
154 if (agi_dirty
&& !no_modify
)
155 libxfs_writebuf(bp
, 0);
161 phase3(xfs_mount_t
*mp
)
165 printf("Phase 3 - for each AG...\n");
167 printf(" - scan and clear agi unlinked lists...\n");
169 printf(" - scan (but don't clear) agi unlinked lists...\n");
172 * first, let's look at the possibly bogus inodes
174 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
176 * walk unlinked list to add more potential inodes to list
178 process_agi_unlinked(mp
, i
);
179 check_uncertain_aginodes(mp
, i
);
182 /* ok, now that the tree's ok, let's take a good look */
185 " - process known inodes and perform inode discovery...\n");
187 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
188 do_log(" - agno = %d\n", i
);
190 * turn on directory processing (inode discovery) and
191 * attribute processing (extra_attr_check)
193 process_aginodes(mp
, i
, 1, 0, 1);
197 * process newly discovered inode chunks
199 printf(" - process newly discovered inodes...\n");
202 * have to loop until no ag has any uncertain
206 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
207 j
+= process_uncertain_aginodes(mp
, i
);
208 #ifdef XR_INODE_TRACE
210 "\t\t phase 3 - process_uncertain_inodes returns %d\n", j
);