]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
cc08d43e | 2 | * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. |
2bd0ea18 NS |
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 |