]>
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> | |
2bd0ea18 NS |
20 | #include "avl.h" |
21 | #include "globals.h" | |
22 | #include "incore.h" | |
23 | #include "agheader.h" | |
24 | #include "protos.h" | |
25 | #include "err_protos.h" | |
3b6ac903 | 26 | #include "threads.h" |
2bd0ea18 | 27 | |
9a5c6ff4 AE |
28 | /* |
29 | * push a block allocation record onto list. assumes list | |
30 | * if set to NULL if empty. | |
31 | */ | |
32 | void | |
33 | record_allocation(ba_rec_t *addr, ba_rec_t *list) | |
34 | { | |
35 | addr->next = list; | |
36 | list = addr; | |
37 | ||
38 | return; | |
39 | } | |
40 | ||
41 | void | |
42 | free_allocations(ba_rec_t *list) | |
43 | { | |
44 | ba_rec_t *current = list; | |
45 | ||
46 | while (list != NULL) { | |
47 | list = list->next; | |
48 | free(current); | |
49 | current = list; | |
50 | } | |
51 | ||
52 | return; | |
53 | } | |
54 | ||
62bdee38 | 55 | /* ba bmap setupstuff. setting/getting state is in incore.h */ |
241ea1c1 | 56 | |
62bdee38 AE |
57 | void |
58 | setup_bmap(xfs_agnumber_t agno, xfs_agblock_t numblocks, xfs_drtbno_t rtblocks) | |
241ea1c1 | 59 | { |
62bdee38 AE |
60 | int i; |
61 | size_t size = 0; | |
241ea1c1 | 62 | |
62bdee38 AE |
63 | ba_bmap = (__uint64_t**)malloc(agno*sizeof(__uint64_t *)); |
64 | if (!ba_bmap) | |
65 | do_error(_("couldn't allocate block map pointers\n")); | |
66 | ag_locks = malloc(agno * sizeof(pthread_mutex_t)); | |
67 | if (!ag_locks) | |
68 | do_error(_("couldn't allocate block map locks\n")); | |
241ea1c1 | 69 | |
62bdee38 AE |
70 | for (i = 0; i < agno; i++) { |
71 | size = roundup((numblocks+(NBBY/XR_BB)-1) / (NBBY/XR_BB), | |
72 | sizeof(__uint64_t)); | |
241ea1c1 | 73 | |
62bdee38 AE |
74 | ba_bmap[i] = (__uint64_t*)memalign(sizeof(__uint64_t), size); |
75 | if (!ba_bmap[i]) { | |
76 | do_error(_("couldn't allocate block map, size = %d\n"), | |
77 | numblocks); | |
241ea1c1 CH |
78 | return; |
79 | } | |
62bdee38 AE |
80 | memset(ba_bmap[i], 0, size); |
81 | pthread_mutex_init(&ag_locks[i], NULL); | |
82 | } | |
241ea1c1 | 83 | |
62bdee38 AE |
84 | if (rtblocks == 0) { |
85 | rt_ba_bmap = NULL; | |
241ea1c1 CH |
86 | return; |
87 | } | |
88 | ||
62bdee38 | 89 | size = roundup(rtblocks / (NBBY/XR_BB), sizeof(__uint64_t)); |
241ea1c1 | 90 | |
62bdee38 AE |
91 | rt_ba_bmap=(__uint64_t*)memalign(sizeof(__uint64_t), size); |
92 | if (!rt_ba_bmap) { | |
93 | do_error( | |
94 | _("couldn't allocate realtime block map, size = %llu\n"), | |
95 | rtblocks); | |
241ea1c1 | 96 | return; |
241ea1c1 | 97 | } |
2bd0ea18 | 98 | |
62bdee38 AE |
99 | /* |
100 | * start all real-time as free blocks | |
101 | */ | |
102 | set_bmap_rt(rtblocks); | |
103 | ||
104 | return; | |
241ea1c1 CH |
105 | } |
106 | ||
62bdee38 | 107 | /* ARGSUSED */ |
241ea1c1 | 108 | void |
62bdee38 | 109 | teardown_rt_bmap(xfs_mount_t *mp) |
241ea1c1 | 110 | { |
62bdee38 AE |
111 | if (rt_ba_bmap != NULL) { |
112 | free(rt_ba_bmap); | |
113 | rt_ba_bmap = NULL; | |
114 | } | |
115 | ||
116 | return; | |
241ea1c1 CH |
117 | } |
118 | ||
62bdee38 AE |
119 | /* ARGSUSED */ |
120 | void | |
121 | teardown_ag_bmap(xfs_mount_t *mp, xfs_agnumber_t agno) | |
241ea1c1 | 122 | { |
62bdee38 | 123 | ASSERT(ba_bmap[agno] != NULL); |
241ea1c1 | 124 | |
62bdee38 AE |
125 | free(ba_bmap[agno]); |
126 | ba_bmap[agno] = NULL; | |
241ea1c1 | 127 | |
62bdee38 | 128 | return; |
241ea1c1 CH |
129 | } |
130 | ||
62bdee38 AE |
131 | /* ARGSUSED */ |
132 | void | |
133 | teardown_bmap_finish(xfs_mount_t *mp) | |
241ea1c1 | 134 | { |
62bdee38 AE |
135 | free(ba_bmap); |
136 | ba_bmap = NULL; | |
137 | ||
138 | return; | |
241ea1c1 CH |
139 | } |
140 | ||
141 | void | |
62bdee38 | 142 | teardown_bmap(xfs_mount_t *mp) |
241ea1c1 | 143 | { |
62bdee38 AE |
144 | xfs_agnumber_t i; |
145 | ||
146 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { | |
147 | teardown_ag_bmap(mp, i); | |
148 | } | |
149 | ||
150 | teardown_rt_bmap(mp); | |
151 | teardown_bmap_finish(mp); | |
152 | ||
153 | return; | |
241ea1c1 CH |
154 | } |
155 | ||
62bdee38 AE |
156 | /* |
157 | * block map initialization routines -- realtime, log, fs | |
158 | */ | |
159 | void | |
160 | set_bmap_rt(xfs_drtbno_t num) | |
af20fe69 | 161 | { |
62bdee38 AE |
162 | xfs_drtbno_t j; |
163 | xfs_drtbno_t size; | |
164 | ||
165 | /* | |
166 | * for now, initialize all realtime blocks to be free | |
167 | * (state == XR_E_FREE) | |
168 | */ | |
169 | size = howmany(num / (NBBY/XR_BB), sizeof(__uint64_t)); | |
170 | ||
171 | for (j = 0; j < size; j++) | |
172 | rt_ba_bmap[j] = 0x2222222222222222LL; | |
173 | ||
174 | return; | |
af20fe69 | 175 | } |
2bd0ea18 | 176 | |
62bdee38 AE |
177 | void |
178 | set_bmap_log(xfs_mount_t *mp) | |
af20fe69 | 179 | { |
62bdee38 AE |
180 | xfs_dfsbno_t logend, i; |
181 | ||
182 | if (mp->m_sb.sb_logstart == 0) | |
2bd0ea18 | 183 | return; |
2bd0ea18 | 184 | |
62bdee38 | 185 | logend = mp->m_sb.sb_logstart + mp->m_sb.sb_logblocks; |
2bd0ea18 | 186 | |
62bdee38 AE |
187 | for (i = mp->m_sb.sb_logstart; i < logend ; i++) { |
188 | set_fsbno_state(mp, i, XR_E_INUSE_FS); | |
2bd0ea18 | 189 | } |
62bdee38 AE |
190 | |
191 | return; | |
2bd0ea18 NS |
192 | } |
193 | ||
62bdee38 AE |
194 | void |
195 | set_bmap_fs(xfs_mount_t *mp) | |
2bd0ea18 | 196 | { |
62bdee38 AE |
197 | xfs_agnumber_t i; |
198 | xfs_agblock_t j; | |
199 | xfs_agblock_t end; | |
200 | ||
201 | /* | |
202 | * AG header is 4 sectors | |
203 | */ | |
204 | end = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); | |
205 | ||
206 | for (i = 0; i < mp->m_sb.sb_agcount; i++) | |
207 | for (j = 0; j < end; j++) | |
208 | set_agbno_state(mp, i, j, XR_E_INUSE_FS); | |
2bd0ea18 | 209 | |
62bdee38 AE |
210 | return; |
211 | } | |
2bd0ea18 | 212 | |
62bdee38 | 213 | #if 0 |
2bd0ea18 | 214 | void |
62bdee38 | 215 | set_bmap_fs_bt(xfs_mount_t *mp) |
2bd0ea18 | 216 | { |
62bdee38 AE |
217 | xfs_agnumber_t i; |
218 | xfs_agblock_t j; | |
219 | xfs_agblock_t begin; | |
220 | xfs_agblock_t end; | |
221 | ||
222 | begin = bnobt_root; | |
223 | end = inobt_root + 1; | |
224 | ||
225 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { | |
241ea1c1 | 226 | /* |
62bdee38 | 227 | * account for btree roots |
241ea1c1 | 228 | */ |
62bdee38 AE |
229 | for (j = begin; j < end; j++) |
230 | set_agbno_state(mp, i, j, XR_E_INUSE_FS); | |
2bd0ea18 NS |
231 | } |
232 | ||
62bdee38 | 233 | return; |
2bd0ea18 | 234 | } |
62bdee38 | 235 | #endif |
2bd0ea18 NS |
236 | |
237 | void | |
62bdee38 | 238 | incore_init(xfs_mount_t *mp) |
2bd0ea18 | 239 | { |
62bdee38 AE |
240 | int agcount = mp->m_sb.sb_agcount; |
241 | extern void incore_ino_init(xfs_mount_t *); | |
242 | extern void incore_ext_init(xfs_mount_t *); | |
2bd0ea18 | 243 | |
62bdee38 | 244 | /* init block alloc bmap */ |
2bd0ea18 | 245 | |
62bdee38 AE |
246 | setup_bmap(agcount, mp->m_sb.sb_agblocks, mp->m_sb.sb_rextents); |
247 | incore_ino_init(mp); | |
248 | incore_ext_init(mp); | |
2bd0ea18 | 249 | |
62bdee38 | 250 | /* initialize random globals now that we know the fs geometry */ |
2bd0ea18 | 251 | |
62bdee38 AE |
252 | inodes_per_block = mp->m_sb.sb_inopblock; |
253 | ||
254 | return; | |
2bd0ea18 | 255 | } |
2bd0ea18 | 256 | |
62bdee38 AE |
257 | #if defined(XR_BMAP_TRACE) || defined(XR_BMAP_DBG) |
258 | int | |
259 | get_agbno_state(xfs_mount_t *mp, xfs_agnumber_t agno, | |
260 | xfs_agblock_t ag_blockno) | |
2bd0ea18 | 261 | { |
62bdee38 | 262 | __uint64_t *addr; |
2bd0ea18 | 263 | |
62bdee38 | 264 | addr = ba_bmap[(agno)] + (ag_blockno)/XR_BB_NUM; |
2bd0ea18 | 265 | |
62bdee38 | 266 | return((*addr >> (((ag_blockno)%XR_BB_NUM)*XR_BB)) & XR_BB_MASK); |
2bd0ea18 | 267 | } |
62bdee38 AE |
268 | |
269 | void set_agbno_state(xfs_mount_t *mp, xfs_agnumber_t agno, | |
270 | xfs_agblock_t ag_blockno, int state) | |
271 | { | |
272 | __uint64_t *addr; | |
273 | ||
274 | addr = ba_bmap[(agno)] + (ag_blockno)/XR_BB_NUM; | |
275 | ||
276 | *addr = (((*addr) & | |
277 | (~((__uint64_t) XR_BB_MASK << (((ag_blockno)%XR_BB_NUM)*XR_BB)))) | | |
278 | (((__uint64_t) (state)) << (((ag_blockno)%XR_BB_NUM)*XR_BB))); | |
279 | } | |
280 | ||
281 | int | |
282 | get_fsbno_state(xfs_mount_t *mp, xfs_dfsbno_t blockno) | |
283 | { | |
284 | return(get_agbno_state(mp, XFS_FSB_TO_AGNO(mp, blockno), | |
285 | XFS_FSB_TO_AGBNO(mp, blockno))); | |
286 | } | |
287 | ||
288 | void | |
289 | set_fsbno_state(xfs_mount_t *mp, xfs_dfsbno_t blockno, int state) | |
290 | { | |
291 | set_agbno_state(mp, XFS_FSB_TO_AGNO(mp, blockno), | |
292 | XFS_FSB_TO_AGBNO(mp, blockno), state); | |
293 | ||
294 | return; | |
295 | } | |
296 | #endif |