]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/rt.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / repair / rt.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
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.
7 *
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.
11 *
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.
18 *
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.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include "avl.h"
35 #include "globals.h"
36 #include "agheader.h"
37 #include "incore.h"
38 #include "dinode.h"
39 #include "protos.h"
40 #include "err_protos.h"
41 #include "rt.h"
42
43 #define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */
44
45 void
46 rtinit(xfs_mount_t *mp)
47 {
48 if (mp->m_sb.sb_rblocks == 0)
49 return;
50
51 /*
52 * realtime init -- blockmap initialization is
53 * handled by incore_init()
54 */
55 /*
56 sumfile = calloc(mp->m_rsumsize, 1);
57 */
58 if ((btmcompute = calloc(mp->m_sb.sb_rbmblocks *
59 mp->m_sb.sb_blocksize, 1)) == NULL)
60 do_error(
61 _("couldn't allocate memory for incore realtime bitmap.\n"));
62
63 if ((sumcompute = calloc(mp->m_rsumsize, 1)) == NULL)
64 do_error(
65 _("couldn't allocate memory for incore realtime summary info.\n"));
66 }
67
68 /*
69 * generate the real-time bitmap and summary info based on the
70 * incore realtime extent map.
71 */
72 int
73 generate_rtinfo(xfs_mount_t *mp,
74 xfs_rtword_t *words,
75 xfs_suminfo_t *sumcompute)
76 {
77 xfs_drtbno_t extno;
78 xfs_drtbno_t start_ext;
79 int bitsperblock;
80 int bmbno;
81 xfs_rtword_t freebit;
82 xfs_rtword_t bits;
83 int start_bmbno;
84 int i;
85 int offs;
86 int log;
87 int len;
88 int in_extent;
89
90 ASSERT(mp->m_rbmip == NULL);
91
92 bitsperblock = mp->m_sb.sb_blocksize * NBBY;
93 extno = start_ext = 0;
94 bmbno = in_extent = start_bmbno = 0;
95
96 /*
97 * slower but simple, don't play around with trying to set
98 * things one word at a time, just set bit as required.
99 * Have to * track start and end (size) of each range of
100 * free extents to set the summary info properly.
101 */
102 while (extno < mp->m_sb.sb_rextents) {
103 freebit = 1;
104 *words = 0;
105 bits = 0;
106 for (i = 0; i < sizeof(xfs_rtword_t) * NBBY &&
107 extno < mp->m_sb.sb_rextents; i++, extno++) {
108 if (get_rtbno_state(mp, extno) == XR_E_FREE) {
109 sb_frextents++;
110 bits |= freebit;
111
112 if (in_extent == 0) {
113 start_ext = extno;
114 start_bmbno = bmbno;
115 in_extent = 1;
116 }
117 } else if (in_extent == 1) {
118 len = (int) (extno - start_ext);
119 log = XFS_RTBLOCKLOG(len);
120 offs = XFS_SUMOFFS(mp, log, start_bmbno);
121 sumcompute[offs]++;
122 in_extent = 0;
123 }
124
125 freebit <<= 1;
126 }
127 *words = bits;
128 words++;
129
130 if (extno % bitsperblock == 0)
131 bmbno++;
132 }
133 if (in_extent == 1) {
134 len = (int) (extno - start_ext);
135 log = XFS_RTBLOCKLOG(len);
136 offs = XFS_SUMOFFS(mp, log, start_bmbno);
137 sumcompute[offs]++;
138 }
139
140 return(0);
141 }
142
143 #if 0
144 /*
145 * returns 1 if bad, 0 if good
146 */
147 int
148 check_summary(xfs_mount_t *mp)
149 {
150 xfs_drfsbno_t bno;
151 xfs_suminfo_t *csp;
152 xfs_suminfo_t *fsp;
153 int log;
154 int error = 0;
155
156 error = 0;
157 csp = sumcompute;
158 fsp = sumfile;
159 for (log = 0; log < mp->m_rsumlevels; log++) {
160 for (bno = 0;
161 bno < mp->m_sb.sb_rbmblocks;
162 bno++, csp++, fsp++) {
163 if (*csp != *fsp) {
164 do_warn(
165 _("rt summary mismatch, size %d block %llu, file: %d, computed: %d\n"),
166 log, bno, *fsp, *csp);
167 error = 1;
168 }
169 }
170 }
171
172 return(error);
173 }
174
175 /*
176 * examine the real-time bitmap file and compute summary
177 * info off it. Should probably be changed to compute
178 * the summary information off the incore computed bitmap
179 * instead of the realtime bitmap file
180 */
181 void
182 process_rtbitmap(xfs_mount_t *mp,
183 xfs_dinode_t *dino,
184 blkmap_t *blkmap)
185 {
186 int error;
187 int bit;
188 int bitsperblock;
189 int bmbno;
190 int end_bmbno;
191 xfs_dfsbno_t bno;
192 xfs_buf_t *bp;
193 xfs_drtbno_t extno;
194 int i;
195 int len;
196 int log;
197 int offs;
198 int prevbit;
199 int start_bmbno;
200 int start_bit;
201 xfs_rtword_t *words;
202
203 ASSERT(mp->m_rbmip == NULL);
204
205 bitsperblock = mp->m_sb.sb_blocksize * NBBY;
206 prevbit = 0;
207 extno = 0;
208 error = 0;
209
210 end_bmbno = howmany(INT_GET(dino->di_core.di_size, ARCH_CONVERT), mp->m_sb.sb_blocksize);
211
212 for (bmbno = 0; bmbno < end_bmbno; bmbno++) {
213 bno = blkmap_get(blkmap, bmbno);
214
215 if (bno == NULLDFSBNO) {
216 do_warn(_("can't find block %d for rtbitmap inode\n"),
217 bmbno);
218 error = 1;
219 continue;
220 }
221 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
222 XFS_FSB_TO_BB(mp, 1));
223 if (!bp) {
224 do_warn(_("can't read block %d for rtbitmap inode\n"),
225 bmbno);
226 error = 1;
227 continue;
228 }
229 words = (xfs_rtword_t *)bp->b_un.b_addr;
230 for (bit = 0;
231 bit < bitsperblock && extno < mp->m_sb.sb_rextents;
232 bit++, extno++) {
233 if (isset(words, bit)) {
234 set_rtbno_state(mp, extno, XR_E_FREE);
235 sb_frextents++;
236 if (prevbit == 0) {
237 start_bmbno = bmbno;
238 start_bit = bit;
239 prevbit = 1;
240 }
241 } else if (prevbit == 1) {
242 len = (bmbno - start_bmbno) * bitsperblock +
243 (bit - start_bit);
244 log = XFS_RTBLOCKLOG(len);
245 offs = XFS_SUMOFFS(mp, log, start_bmbno);
246 sumcompute[offs]++;
247 prevbit = 0;
248 }
249 }
250 libxfs_putbuf(bp);
251 if (extno == mp->m_sb.sb_rextents)
252 break;
253 }
254 if (prevbit == 1) {
255 len = (bmbno - start_bmbno) * bitsperblock + (bit - start_bit);
256 log = XFS_RTBLOCKLOG(len);
257 offs = XFS_SUMOFFS(mp, log, start_bmbno);
258 sumcompute[offs]++;
259 }
260 }
261
262 /*
263 * copy the real-time summary file data into memory
264 */
265 void
266 process_rtsummary(xfs_mount_t *mp,
267 xfs_dinode_t *dino,
268 blkmap_t *blkmap)
269 {
270 xfs_fsblock_t bno;
271 xfs_buf_t *bp;
272 char *bytes;
273 int sumbno;
274
275 for (sumbno = 0; sumbno < blkmap->count; sumbno++) {
276 bno = blkmap_get(blkmap, sumbno);
277 if (bno == NULLDFSBNO) {
278 do_warn(_("block %d for rtsummary inode is missing\n"),
279 sumbno);
280 error++;
281 continue;
282 }
283 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
284 XFS_FSB_TO_BB(mp, 1));
285 if (!bp) {
286 do_warn(_("can't read block %d for rtsummary inode\n"),
287 sumbno);
288 error++;
289 continue;
290 }
291 bytes = bp->b_un.b_addr;
292 bcopy(bytes, (char *)sumfile + sumbno * mp->m_sb.sb_blocksize,
293 mp->m_sb.sb_blocksize);
294 libxfs_putbuf(bp);
295 }
296 }
297 #endif