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