]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/phase2.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
13 #include "err_protos.h"
18 /* workaround craziness in the xlog routines */
19 int xlog_recover_do_trans(struct xlog
*log
, xlog_recover_t
*t
, int p
)
31 struct xlog
*log
= mp
->m_log
;
33 memset(log
, 0, sizeof(struct xlog
));
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
);
37 if (xfs_sb_version_hassector(&mp
->m_sb
))
38 x
.lbsize
<<= (mp
->m_sb
.sb_logsectlog
- BBSHIFT
);
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
);
45 if (xfs_sb_version_hassector(&mp
->m_sb
)) {
46 log
->l_sectbb_log
= mp
->m_sb
.sb_logsectlog
- BBSHIFT
;
47 ASSERT(log
->l_sectbb_log
<= mp
->m_sectbb_log
);
48 /* for larger sector sizes, must have v2 or external log */
49 ASSERT(log
->l_sectbb_log
== 0 ||
50 log
->l_logBBstart
== 0 ||
51 xfs_sb_version_haslogv2(&mp
->m_sb
));
52 ASSERT(mp
->m_sb
.sb_logsectlog
>= BBSHIFT
);
54 log
->l_sectbb_mask
= (1 << log
->l_sectbb_log
) - 1;
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
62 error
= xlog_find_tail(log
, &head_blk
, &tail_blk
);
65 _("zero_log: cannot find log head/tail (xlog_find_tail=%d)\n"),
67 if (!no_modify
&& !zap_log
) {
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"));
77 _("zero_log: head block %" PRId64
" tail block %" PRId64
"\n"),
80 if (head_blk
!= tail_blk
) {
81 if (!no_modify
&& zap_log
) {
83 "ALERT: The filesystem has valuable metadata changes in a log which is being\n"
84 "destroyed because the -L option was used.\n"));
85 } else if (no_modify
) {
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"));
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"
97 "of the filesystem before doing this.\n"));
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
109 if (!no_modify
&& zap_log
) {
110 libxfs_log_clear(log
->l_dev
, NULL
,
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
),
114 xfs_sb_version_haslogv2(&mp
->m_sb
) ? 2 : 1,
115 mp
->m_sb
.sb_logsunit
, XLOG_FMT
, XLOG_INIT_CYCLE
, true);
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"));
124 * Finally, seed the max LSN from the current state of the log if this
125 * is a v5 filesystem.
127 if (xfs_sb_version_hascrc(&mp
->m_sb
))
128 libxfs_max_lsn
= log
->l_last_sync_lsn
;
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.
142 struct xfs_mount
*mp
,
146 ino_tree_node_t
*ino_rec
;
148 /* now we can start using the buffer cache routines */
151 /* Check whether this fs has internal or external log */
152 if (mp
->m_sb
.sb_logstart
== 0) {
154 do_error(_("This filesystem has an external log. "
155 "Specify log device with the -l option.\n"));
157 do_log(_("Phase 2 - using external log on %s\n"), x
.logname
);
159 do_log(_("Phase 2 - using internal log\n"));
161 /* Zero log if applicable */
162 do_log(_(" - zero log...\n"));
165 do_log(_(" - scan filesystem freespace and inode maps...\n"));
169 set_progress_msg(PROG_FMT_SCAN_AG
, (uint64_t) glob_agcount
);
171 scan_ags(mp
, scan_threads
);
176 * make sure we know about the root inode chunk
178 if ((ino_rec
= find_inode_rec(mp
, 0, mp
->m_sb
.sb_rootino
)) == NULL
) {
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);
181 do_warn(_("root inode chunk not found\n"));
184 * mark the first 3 used, the rest are free
186 ino_rec
= set_inode_used_alloc(mp
, 0,
187 (xfs_agino_t
) mp
->m_sb
.sb_rootino
);
188 set_inode_used(ino_rec
, 1);
189 set_inode_used(ino_rec
, 2);
191 for (j
= 3; j
< XFS_INODES_PER_CHUNK
; j
++)
192 set_inode_free(ino_rec
, j
);
197 set_bmap_ext(0, XFS_INO_TO_AGBNO(mp
, mp
->m_sb
.sb_rootino
),
198 mp
->m_ialloc_blks
, XR_E_INO
);
200 do_log(_(" - found root inode chunk\n"));
203 * blocks are marked, just make sure they're in use
205 if (is_inode_free(ino_rec
, 0)) {
206 do_warn(_("root inode marked free, "));
207 set_inode_used(ino_rec
, 0);
209 do_warn(_("correcting\n"));
211 do_warn(_("would correct\n"));
214 if (is_inode_free(ino_rec
, 1)) {
215 do_warn(_("realtime bitmap inode marked free, "));
216 set_inode_used(ino_rec
, 1);
218 do_warn(_("correcting\n"));
220 do_warn(_("would correct\n"));
223 if (is_inode_free(ino_rec
, 2)) {
224 do_warn(_("realtime summary inode marked free, "));
225 set_inode_used(ino_rec
, 2);
227 do_warn(_("correcting\n"));
229 do_warn(_("would correct\n"));