]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase2.c
merge over kernel changes
[thirdparty/xfsprogs-dev.git] / repair / phase2.c
CommitLineData
2bd0ea18 1/*
0d3e0b37 2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
3 *
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.
7 *
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.
11 *
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.
18 *
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.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
d321ceac 33#include <libxlog.h>
2bd0ea18
NS
34#include "avl.h"
35#include "globals.h"
36#include "agheader.h"
37#include "protos.h"
38#include "err_protos.h"
39#include "incore.h"
40
41void set_mp(xfs_mount_t *mpp);
42void scan_ag(xfs_agnumber_t agno);
43
d321ceac
NS
44/* workaround craziness in the xlog routines */
45int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; }
46
2bd0ea18 47static void
d321ceac 48zero_log(xfs_mount_t *mp)
2bd0ea18 49{
d321ceac
NS
50 int error;
51 xlog_t log;
52 xfs_daddr_t head_blk, tail_blk;
53 dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;
54
55 memset(&log, 0, sizeof(log));
56 if (!x.logdev)
57 x.logdev = x.ddev;
58 x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
59 x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
60
61 log.l_dev = logdev;
62 log.l_logsize = BBTOB(x.logBBsize);
63 log.l_logBBsize = x.logBBsize;
64 log.l_logBBstart = x.logBBstart;
65 log.l_mp = mp;
66
67 if ((error = xlog_find_tail(&log, &head_blk, &tail_blk, 0))) {
94bc4126
NS
68 do_warn("zero_log: cannot find log head/tail "
69 "(xlog_find_tail=%d), zeroing it anyway\n",
70 error);
d321ceac
NS
71 } else {
72 if (verbose) {
73 do_warn("zero_log: head block %lld tail block %lld\n",
74 head_blk, tail_blk);
75 }
76 if (head_blk != tail_blk) {
77 if (zap_log) {
78 do_warn(
79"ALERT: The filesystem has valuable metadata changes in a log which is being\n"
80"destroyed because the -L option was used.\n");
81 } else {
82 do_warn(
83"ERROR: The filesystem has valuable metadata changes in a log which needs to\n"
84"be replayed. Mount the filesystem to replay the log, and unmount it before\n"
85"re-running xfs_repair. If you are unable to mount the filesystem, then use\n"
86"the -L option to destroy the log and attempt a repair.\n"
87"Note that destroying the log may cause corruption -- please attempt a mount\n"
88"of the filesystem before doing this.\n");
89 exit(2);
90 }
91 }
92 }
93
2bd0ea18
NS
94 libxfs_log_clear(logdev,
95 XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
96 (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
d321ceac
NS
97 &mp->m_sb.sb_uuid,
98 XLOG_FMT);
2bd0ea18
NS
99}
100
101/*
102 * ok, at this point, the fs is mounted but the root inode may be
103 * trashed and the ag headers haven't been checked. So we have
104 * a valid xfs_mount_t and superblock but that's about it. That
105 * means we can use macros that use mount/sb fields in calculations
106 * but I/O or btree routines that depend on space maps or inode maps
107 * being correct are verboten.
108 */
109
110void
d321ceac 111phase2(xfs_mount_t *mp)
2bd0ea18
NS
112{
113 xfs_agnumber_t i;
114 xfs_agblock_t b;
115 int j;
116 ino_tree_node_t *ino_rec;
117
118 /* now we can start using the buffer cache routines */
119 set_mp(mp);
120
121 /* Check whether this fs has internal or external log */
122 if (mp->m_sb.sb_logstart == 0) {
d321ceac 123 if (!x.logname) {
2bd0ea18
NS
124 fprintf (stderr,
125 "This filesystem has an external log. "
126 "Specify log device with the -l option.\n");
127 exit (1);
128 }
129
130 fprintf (stderr, "Phase 2 - using external log on %s\n",
d321ceac 131 x.logname);
2bd0ea18
NS
132 } else
133 fprintf (stderr, "Phase 2 - using internal log\n");
134
135 /* Zero log if applicable */
136 if (!no_modify) {
137 do_log(" - zero log...\n");
d321ceac 138 zero_log(mp);
2bd0ea18
NS
139 }
140
141 do_log(" - scan filesystem freespace and inode maps...\n");
142
143 /*
144 * account for space used by ag headers and log if internal
145 */
146 set_bmap_log(mp);
147 set_bmap_fs(mp);
148
149 bad_ino_btree = 0;
150
151 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
152 scan_ag(i);
153#ifdef XR_INODE_TRACE
154 print_inode_list(i);
155#endif
156 }
157
158 /*
159 * make sure we know about the root inode chunk
160 */
161 if ((ino_rec = find_inode_rec(0, mp->m_sb.sb_rootino)) == NULL) {
162 ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 &&
163 mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2);
164 do_warn("root inode chunk not found\n");
165
166 /*
167 * mark the first 3 used, the rest are free
168 */
169 ino_rec = set_inode_used_alloc(0,
170 (xfs_agino_t) mp->m_sb.sb_rootino);
171 set_inode_used(ino_rec, 1);
172 set_inode_used(ino_rec, 2);
173
174 for (j = 3; j < XFS_INODES_PER_CHUNK; j++)
175 set_inode_free(ino_rec, j);
176
177 /*
178 * also mark blocks
179 */
180 for (b = 0; b < mp->m_ialloc_blks; b++) {
181 set_agbno_state(mp, 0,
182 b + XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino),
183 XR_E_INO);
184 }
185 } else {
186 do_log(" - found root inode chunk\n");
187
188 /*
189 * blocks are marked, just make sure they're in use
190 */
191 if (is_inode_free(ino_rec, 0)) {
192 do_warn("root inode marked free, ");
193 set_inode_used(ino_rec, 0);
194 if (!no_modify)
195 do_warn("correcting\n");
196 else
197 do_warn("would correct\n");
198 }
199
200 if (is_inode_free(ino_rec, 1)) {
201 do_warn("realtime bitmap inode marked free, ");
202 set_inode_used(ino_rec, 1);
203 if (!no_modify)
204 do_warn("correcting\n");
205 else
206 do_warn("would correct\n");
207 }
208
209 if (is_inode_free(ino_rec, 2)) {
210 do_warn("realtime summary inode marked free, ");
211 set_inode_used(ino_rec, 2);
212 if (!no_modify)
213 do_warn("correcting\n");
214 else
215 do_warn("would correct\n");
216 }
217 }
218}