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