2
* Copyright (c) 2000 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);