]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/phase2.c
aee39130dba5841e8bdbd97eec1a5d804939242e
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
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
7 * published by the Free Software Foundation.
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.
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
19 #include "xfs/libxfs.h"
20 #include "xfs/libxlog.h"
25 #include "err_protos.h"
30 void set_mp(xfs_mount_t
*mpp
);
32 /* workaround craziness in the xlog routines */
33 int xlog_recover_do_trans(struct xlog
*log
, xlog_recover_t
*t
, int p
)
39 zero_log(xfs_mount_t
*mp
)
43 xfs_daddr_t head_blk
, tail_blk
;
45 memset(&log
, 0, sizeof(log
));
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
);
49 if (xfs_sb_version_hassector(&mp
->m_sb
))
50 x
.lbsize
<<= (mp
->m_sb
.sb_logsectlog
- BBSHIFT
);
52 log
.l_dev
= mp
->m_logdev_targp
;
53 log
.l_logBBsize
= x
.logBBsize
;
54 log
.l_logBBstart
= x
.logBBstart
;
55 log
.l_sectBBsize
= BTOBB(x
.lbsize
);
57 if (xfs_sb_version_hassector(&mp
->m_sb
)) {
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 ||
63 xfs_sb_version_haslogv2(&mp
->m_sb
));
64 ASSERT(mp
->m_sb
.sb_logsectlog
>= BBSHIFT
);
66 log
.l_sectbb_mask
= (1 << log
.l_sectbb_log
) - 1;
68 if ((error
= xlog_find_tail(&log
, &head_blk
, &tail_blk
))) {
69 do_warn(_("zero_log: cannot find log head/tail "
70 "(xlog_find_tail=%d), zeroing it anyway\n"),
75 _("zero_log: head block %" PRId64
" tail block %" PRId64
"\n"),
78 if (head_blk
!= tail_blk
) {
81 "ALERT: The filesystem has valuable metadata changes in a log which is being\n"
82 "destroyed because the -L option was used.\n"));
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"
90 "of the filesystem before doing this.\n"));
96 libxfs_log_clear(log
.l_dev
,
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
),
100 xfs_sb_version_haslogv2(&mp
->m_sb
) ? 2 : 1,
101 mp
->m_sb
.sb_logsunit
, XLOG_FMT
);
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.
115 struct xfs_mount
*mp
,
119 ino_tree_node_t
*ino_rec
;
121 /* now we can start using the buffer cache routines */
124 /* Check whether this fs has internal or external log */
125 if (mp
->m_sb
.sb_logstart
== 0) {
127 do_error(_("This filesystem has an external log. "
128 "Specify log device with the -l option.\n"));
130 do_log(_("Phase 2 - using external log on %s\n"), x
.logname
);
132 do_log(_("Phase 2 - using internal log\n"));
134 /* Zero log if applicable */
136 do_log(_(" - zero log...\n"));
140 do_log(_(" - scan filesystem freespace and inode maps...\n"));
144 set_progress_msg(PROG_FMT_SCAN_AG
, (__uint64_t
) glob_agcount
);
146 scan_ags(mp
, scan_threads
);
151 * make sure we know about the root inode chunk
153 if ((ino_rec
= find_inode_rec(mp
, 0, mp
->m_sb
.sb_rootino
)) == NULL
) {
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);
156 do_warn(_("root inode chunk not found\n"));
159 * mark the first 3 used, the rest are free
161 ino_rec
= set_inode_used_alloc(mp
, 0,
162 (xfs_agino_t
) mp
->m_sb
.sb_rootino
);
163 set_inode_used(ino_rec
, 1);
164 set_inode_used(ino_rec
, 2);
166 for (j
= 3; j
< XFS_INODES_PER_CHUNK
; j
++)
167 set_inode_free(ino_rec
, j
);
172 set_bmap_ext(0, XFS_INO_TO_AGBNO(mp
, mp
->m_sb
.sb_rootino
),
173 mp
->m_ialloc_blks
, XR_E_INO
);
175 do_log(_(" - found root inode chunk\n"));
178 * blocks are marked, just make sure they're in use
180 if (is_inode_free(ino_rec
, 0)) {
181 do_warn(_("root inode marked free, "));
182 set_inode_used(ino_rec
, 0);
184 do_warn(_("correcting\n"));
186 do_warn(_("would correct\n"));
189 if (is_inode_free(ino_rec
, 1)) {
190 do_warn(_("realtime bitmap inode marked free, "));
191 set_inode_used(ino_rec
, 1);
193 do_warn(_("correcting\n"));
195 do_warn(_("would correct\n"));
198 if (is_inode_free(ino_rec
, 2)) {
199 do_warn(_("realtime summary inode marked free, "));
200 set_inode_used(ino_rec
, 2);
202 do_warn(_("correcting\n"));
204 do_warn(_("would correct\n"));