]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
0d3e0b37 | 2 | * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. |
dfc130f3 | 3 | * |
2bd0ea18 NS |
4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of version 2 of the GNU General Public License as | |
6 | * published by the Free Software Foundation. | |
dfc130f3 | 7 | * |
2bd0ea18 NS |
8 | * This program is distributed in the hope that it would be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
dfc130f3 | 11 | * |
2bd0ea18 NS |
12 | * Further, this software is distributed without any warranty that it is |
13 | * free of the rightful claim of any third person regarding infringement | |
14 | * or the like. Any license provided herein, whether implied or | |
15 | * otherwise, applies only to this software file. Patent licenses, if | |
16 | * any, provided herein do not apply to combinations of this program with | |
17 | * other software, or any other product whatsoever. | |
dfc130f3 | 18 | * |
2bd0ea18 NS |
19 | * You should have received a copy of the GNU General Public License along |
20 | * with this program; if not, write the Free Software Foundation, Inc., 59 | |
21 | * Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
dfc130f3 | 22 | * |
2bd0ea18 NS |
23 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, |
24 | * Mountain View, CA 94043, or: | |
dfc130f3 RC |
25 | * |
26 | * http://www.sgi.com | |
27 | * | |
28 | * For further information regarding this notice, see: | |
29 | * | |
2bd0ea18 NS |
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ |
31 | */ | |
32 | ||
d321ceac | 33 | #include <libxlog.h> |
2bd0ea18 NS |
34 | #include "avl.h" |
35 | #include "globals.h" | |
36 | #include "agheader.h" | |
37 | #include "protos.h" | |
38 | #include "err_protos.h" | |
39 | #include "incore.h" | |
40 | ||
41 | void set_mp(xfs_mount_t *mpp); | |
42 | void scan_ag(xfs_agnumber_t agno); | |
43 | ||
d321ceac NS |
44 | /* workaround craziness in the xlog routines */ |
45 | int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } | |
46 | ||
2bd0ea18 | 47 | static void |
d321ceac | 48 | zero_log(xfs_mount_t *mp) |
2bd0ea18 | 49 | { |
d321ceac NS |
50 | int error; |
51 | xlog_t log; | |
52 | xfs_daddr_t head_blk, tail_blk; | |
53 | dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; | |
54 | ||
55 | memset(&log, 0, sizeof(log)); | |
56 | if (!x.logdev) | |
57 | x.logdev = x.ddev; | |
58 | x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); | |
59 | x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); | |
60 | ||
61 | log.l_dev = logdev; | |
62 | log.l_logsize = BBTOB(x.logBBsize); | |
63 | log.l_logBBsize = x.logBBsize; | |
64 | log.l_logBBstart = x.logBBstart; | |
65 | log.l_mp = mp; | |
66 | ||
67 | if ((error = xlog_find_tail(&log, &head_blk, &tail_blk, 0))) { | |
507f4e33 NS |
68 | do_warn(_("zero_log: cannot find log head/tail " |
69 | "(xlog_find_tail=%d), zeroing it anyway\n"), | |
94bc4126 | 70 | error); |
d321ceac NS |
71 | } else { |
72 | if (verbose) { | |
507f4e33 | 73 | do_warn(_("zero_log: head block %lld tail block %lld\n"), |
d321ceac NS |
74 | head_blk, tail_blk); |
75 | } | |
76 | if (head_blk != tail_blk) { | |
77 | if (zap_log) { | |
507f4e33 | 78 | do_warn(_( |
d321ceac | 79 | "ALERT: The filesystem has valuable metadata changes in a log which is being\n" |
507f4e33 | 80 | "destroyed because the -L option was used.\n")); |
d321ceac | 81 | } else { |
507f4e33 | 82 | do_warn(_( |
d321ceac NS |
83 | "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" |
84 | "be replayed. Mount the filesystem to replay the log, and unmount it before\n" | |
85 | "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" | |
86 | "the -L option to destroy the log and attempt a repair.\n" | |
87 | "Note that destroying the log may cause corruption -- please attempt a mount\n" | |
507f4e33 | 88 | "of the filesystem before doing this.\n")); |
d321ceac NS |
89 | exit(2); |
90 | } | |
91 | } | |
92 | } | |
93 | ||
dfc130f3 | 94 | libxfs_log_clear(logdev, |
2bd0ea18 NS |
95 | XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), |
96 | (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), | |
d321ceac | 97 | &mp->m_sb.sb_uuid, |
73bf5988 SL |
98 | XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, |
99 | mp->m_sb.sb_logsunit, XLOG_FMT); | |
2bd0ea18 NS |
100 | } |
101 | ||
102 | /* | |
103 | * ok, at this point, the fs is mounted but the root inode may be | |
104 | * trashed and the ag headers haven't been checked. So we have | |
105 | * a valid xfs_mount_t and superblock but that's about it. That | |
106 | * means we can use macros that use mount/sb fields in calculations | |
107 | * but I/O or btree routines that depend on space maps or inode maps | |
108 | * being correct are verboten. | |
109 | */ | |
110 | ||
111 | void | |
d321ceac | 112 | phase2(xfs_mount_t *mp) |
2bd0ea18 NS |
113 | { |
114 | xfs_agnumber_t i; | |
115 | xfs_agblock_t b; | |
116 | int j; | |
117 | ino_tree_node_t *ino_rec; | |
118 | ||
119 | /* now we can start using the buffer cache routines */ | |
120 | set_mp(mp); | |
121 | ||
122 | /* Check whether this fs has internal or external log */ | |
123 | if (mp->m_sb.sb_logstart == 0) { | |
507f4e33 NS |
124 | if (!x.logname) |
125 | do_error(_("This filesystem has an external log. " | |
126 | "Specify log device with the -l option.\n")); | |
dfc130f3 | 127 | |
507f4e33 | 128 | do_log(_("Phase 2 - using external log on %s\n"), x.logname); |
2bd0ea18 | 129 | } else |
507f4e33 | 130 | do_log(_("Phase 2 - using internal log\n")); |
2bd0ea18 NS |
131 | |
132 | /* Zero log if applicable */ | |
133 | if (!no_modify) { | |
507f4e33 | 134 | do_log(_(" - zero log...\n")); |
d321ceac | 135 | zero_log(mp); |
2bd0ea18 NS |
136 | } |
137 | ||
507f4e33 | 138 | do_log(_(" - scan filesystem freespace and inode maps...\n")); |
2bd0ea18 NS |
139 | |
140 | /* | |
141 | * account for space used by ag headers and log if internal | |
142 | */ | |
143 | set_bmap_log(mp); | |
144 | set_bmap_fs(mp); | |
145 | ||
146 | bad_ino_btree = 0; | |
147 | ||
148 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { | |
149 | scan_ag(i); | |
150 | #ifdef XR_INODE_TRACE | |
151 | print_inode_list(i); | |
152 | #endif | |
153 | } | |
154 | ||
155 | /* | |
156 | * make sure we know about the root inode chunk | |
157 | */ | |
158 | if ((ino_rec = find_inode_rec(0, mp->m_sb.sb_rootino)) == NULL) { | |
159 | ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 && | |
160 | mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2); | |
507f4e33 | 161 | do_warn(_("root inode chunk not found\n")); |
2bd0ea18 NS |
162 | |
163 | /* | |
164 | * mark the first 3 used, the rest are free | |
165 | */ | |
166 | ino_rec = set_inode_used_alloc(0, | |
167 | (xfs_agino_t) mp->m_sb.sb_rootino); | |
168 | set_inode_used(ino_rec, 1); | |
169 | set_inode_used(ino_rec, 2); | |
170 | ||
171 | for (j = 3; j < XFS_INODES_PER_CHUNK; j++) | |
172 | set_inode_free(ino_rec, j); | |
173 | ||
174 | /* | |
175 | * also mark blocks | |
176 | */ | |
177 | for (b = 0; b < mp->m_ialloc_blks; b++) { | |
178 | set_agbno_state(mp, 0, | |
179 | b + XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino), | |
180 | XR_E_INO); | |
181 | } | |
182 | } else { | |
507f4e33 | 183 | do_log(_(" - found root inode chunk\n")); |
2bd0ea18 NS |
184 | |
185 | /* | |
186 | * blocks are marked, just make sure they're in use | |
187 | */ | |
188 | if (is_inode_free(ino_rec, 0)) { | |
507f4e33 | 189 | do_warn(_("root inode marked free, ")); |
2bd0ea18 NS |
190 | set_inode_used(ino_rec, 0); |
191 | if (!no_modify) | |
507f4e33 | 192 | do_warn(_("correcting\n")); |
2bd0ea18 | 193 | else |
507f4e33 | 194 | do_warn(_("would correct\n")); |
2bd0ea18 NS |
195 | } |
196 | ||
197 | if (is_inode_free(ino_rec, 1)) { | |
507f4e33 | 198 | do_warn(_("realtime bitmap inode marked free, ")); |
2bd0ea18 NS |
199 | set_inode_used(ino_rec, 1); |
200 | if (!no_modify) | |
507f4e33 | 201 | do_warn(_("correcting\n")); |
2bd0ea18 | 202 | else |
507f4e33 | 203 | do_warn(_("would correct\n")); |
2bd0ea18 NS |
204 | } |
205 | ||
206 | if (is_inode_free(ino_rec, 2)) { | |
507f4e33 | 207 | do_warn(_("realtime summary inode marked free, ")); |
2bd0ea18 NS |
208 | set_inode_used(ino_rec, 2); |
209 | if (!no_modify) | |
507f4e33 | 210 | do_warn(_("correcting\n")); |
2bd0ea18 | 211 | else |
507f4e33 | 212 | do_warn(_("would correct\n")); |
2bd0ea18 NS |
213 | } |
214 | } | |
215 | } |