]>
Commit | Line | Data |
---|---|---|
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 | ||
31 | void | |
32 | rtinit(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 | */ | |
58 | int | |
59 | generate_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 | */ | |
133 | int | |
134 | check_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 | */ | |
167 | void | |
168 | process_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 | */ | |
251 | void | |
252 | process_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 |