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