]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase2.c
xfsprogs: simplify internal includes
[thirdparty/xfsprogs-dev.git] / repair / phase2.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
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
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
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.
dfc130f3 13 *
da23017d
NS
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
2bd0ea18
NS
17 */
18
6b803e5a
CH
19#include "libxfs.h"
20#include "libxlog.h"
2bd0ea18
NS
21#include "avl.h"
22#include "globals.h"
23#include "agheader.h"
24#include "protos.h"
25#include "err_protos.h"
26#include "incore.h"
06fbdda9 27#include "progress.h"
364a126c 28#include "scan.h"
2bd0ea18
NS
29
30void set_mp(xfs_mount_t *mpp);
2bd0ea18 31
d321ceac 32/* workaround craziness in the xlog routines */
999f0b9c
DC
33int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p)
34{
35 return 0;
36}
d321ceac 37
2bd0ea18 38static void
d321ceac 39zero_log(xfs_mount_t *mp)
2bd0ea18 40{
d321ceac 41 int error;
999f0b9c 42 struct xlog log;
d321ceac 43 xfs_daddr_t head_blk, tail_blk;
d321ceac
NS
44
45 memset(&log, 0, sizeof(log));
d321ceac
NS
46 x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
47 x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
999f0b9c
DC
48 x.lbsize = BBSIZE;
49 if (xfs_sb_version_hassector(&mp->m_sb))
50 x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);
d321ceac 51
75c8b434 52 log.l_dev = mp->m_logdev_targp;
d321ceac
NS
53 log.l_logBBsize = x.logBBsize;
54 log.l_logBBstart = x.logBBstart;
999f0b9c 55 log.l_sectBBsize = BTOBB(x.lbsize);
d321ceac 56 log.l_mp = mp;
5e656dbb 57 if (xfs_sb_version_hassector(&mp->m_sb)) {
2aa2e7b9
BN
58 log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
59 ASSERT(log.l_sectbb_log <= mp->m_sectbb_log);
60 /* for larger sector sizes, must have v2 or external log */
61 ASSERT(log.l_sectbb_log == 0 ||
62 log.l_logBBstart == 0 ||
5e656dbb 63 xfs_sb_version_haslogv2(&mp->m_sb));
2aa2e7b9
BN
64 ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
65 }
66 log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1;
d321ceac 67
5e656dbb 68 if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) {
507f4e33
NS
69 do_warn(_("zero_log: cannot find log head/tail "
70 "(xlog_find_tail=%d), zeroing it anyway\n"),
94bc4126 71 error);
d321ceac
NS
72 } else {
73 if (verbose) {
5d1b7f0f
CH
74 do_warn(
75 _("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"),
d321ceac
NS
76 head_blk, tail_blk);
77 }
78 if (head_blk != tail_blk) {
79 if (zap_log) {
507f4e33 80 do_warn(_(
d321ceac 81"ALERT: The filesystem has valuable metadata changes in a log which is being\n"
507f4e33 82"destroyed because the -L option was used.\n"));
d321ceac 83 } else {
507f4e33 84 do_warn(_(
d321ceac
NS
85"ERROR: The filesystem has valuable metadata changes in a log which needs to\n"
86"be replayed. Mount the filesystem to replay the log, and unmount it before\n"
87"re-running xfs_repair. If you are unable to mount the filesystem, then use\n"
88"the -L option to destroy the log and attempt a repair.\n"
89"Note that destroying the log may cause corruption -- please attempt a mount\n"
507f4e33 90"of the filesystem before doing this.\n"));
d321ceac
NS
91 exit(2);
92 }
93 }
94 }
95
75c8b434 96 libxfs_log_clear(log.l_dev,
2bd0ea18
NS
97 XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
98 (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
d321ceac 99 &mp->m_sb.sb_uuid,
5e656dbb 100 xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1,
73bf5988 101 mp->m_sb.sb_logsunit, XLOG_FMT);
2bd0ea18
NS
102}
103
104/*
105 * ok, at this point, the fs is mounted but the root inode may be
106 * trashed and the ag headers haven't been checked. So we have
107 * a valid xfs_mount_t and superblock but that's about it. That
108 * means we can use macros that use mount/sb fields in calculations
109 * but I/O or btree routines that depend on space maps or inode maps
110 * being correct are verboten.
111 */
112
113void
364a126c
DC
114phase2(
115 struct xfs_mount *mp,
116 int scan_threads)
2bd0ea18 117{
2bd0ea18
NS
118 int j;
119 ino_tree_node_t *ino_rec;
120
121 /* now we can start using the buffer cache routines */
122 set_mp(mp);
123
124 /* Check whether this fs has internal or external log */
125 if (mp->m_sb.sb_logstart == 0) {
507f4e33
NS
126 if (!x.logname)
127 do_error(_("This filesystem has an external log. "
128 "Specify log device with the -l option.\n"));
dfc130f3 129
507f4e33 130 do_log(_("Phase 2 - using external log on %s\n"), x.logname);
2bd0ea18 131 } else
507f4e33 132 do_log(_("Phase 2 - using internal log\n"));
2bd0ea18
NS
133
134 /* Zero log if applicable */
135 if (!no_modify) {
507f4e33 136 do_log(_(" - zero log...\n"));
d321ceac 137 zero_log(mp);
2bd0ea18
NS
138 }
139
507f4e33 140 do_log(_(" - scan filesystem freespace and inode maps...\n"));
2bd0ea18 141
2bd0ea18
NS
142 bad_ino_btree = 0;
143
06fbdda9
MV
144 set_progress_msg(PROG_FMT_SCAN_AG, (__uint64_t) glob_agcount);
145
364a126c 146 scan_ags(mp, scan_threads);
48d49157 147
06fbdda9
MV
148 print_final_rpt();
149
2bd0ea18
NS
150 /*
151 * make sure we know about the root inode chunk
152 */
1ae311d5 153 if ((ino_rec = find_inode_rec(mp, 0, mp->m_sb.sb_rootino)) == NULL) {
2bd0ea18
NS
154 ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 &&
155 mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2);
507f4e33 156 do_warn(_("root inode chunk not found\n"));
2bd0ea18
NS
157
158 /*
159 * mark the first 3 used, the rest are free
160 */
1ae311d5 161 ino_rec = set_inode_used_alloc(mp, 0,
2bd0ea18
NS
162 (xfs_agino_t) mp->m_sb.sb_rootino);
163 set_inode_used(ino_rec, 1);
164 set_inode_used(ino_rec, 2);
165
166 for (j = 3; j < XFS_INODES_PER_CHUNK; j++)
167 set_inode_free(ino_rec, j);
168
169 /*
170 * also mark blocks
171 */
8961bfde
BN
172 set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino),
173 mp->m_ialloc_blks, XR_E_INO);
2bd0ea18 174 } else {
507f4e33 175 do_log(_(" - found root inode chunk\n"));
2bd0ea18
NS
176
177 /*
178 * blocks are marked, just make sure they're in use
179 */
180 if (is_inode_free(ino_rec, 0)) {
507f4e33 181 do_warn(_("root inode marked free, "));
2bd0ea18
NS
182 set_inode_used(ino_rec, 0);
183 if (!no_modify)
507f4e33 184 do_warn(_("correcting\n"));
2bd0ea18 185 else
507f4e33 186 do_warn(_("would correct\n"));
2bd0ea18
NS
187 }
188
189 if (is_inode_free(ino_rec, 1)) {
507f4e33 190 do_warn(_("realtime bitmap inode marked free, "));
2bd0ea18
NS
191 set_inode_used(ino_rec, 1);
192 if (!no_modify)
507f4e33 193 do_warn(_("correcting\n"));
2bd0ea18 194 else
507f4e33 195 do_warn(_("would correct\n"));
2bd0ea18
NS
196 }
197
198 if (is_inode_free(ino_rec, 2)) {
507f4e33 199 do_warn(_("realtime summary inode marked free, "));
2bd0ea18
NS
200 set_inode_used(ino_rec, 2);
201 if (!no_modify)
507f4e33 202 do_warn(_("correcting\n"));
2bd0ea18 203 else
507f4e33 204 do_warn(_("would correct\n"));
2bd0ea18
NS
205 }
206 }
207}