]>
Commit | Line | Data |
---|---|---|
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 | |
30 | void set_mp(xfs_mount_t *mpp); | |
2bd0ea18 | 31 | |
d321ceac | 32 | /* workaround craziness in the xlog routines */ |
999f0b9c DC |
33 | int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) |
34 | { | |
35 | return 0; | |
36 | } | |
d321ceac | 37 | |
2bd0ea18 | 38 | static void |
d321ceac | 39 | zero_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 | ||
113 | void | |
364a126c DC |
114 | phase2( |
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 | } |