1 |
/* Block allocation routines |
/* Block allocation routines |
2 |
|
|
3 |
Copyright (C) 1995,99,2000 Free Software Foundation, Inc. |
Copyright (C) 1995, 1999, 2000, 2005 Free Software Foundation, Inc. |
4 |
|
|
5 |
Converted to work under the hurd by Miles Bader <miles@gnu.org> |
Converted to work under the hurd by Miles Bader <miles@gnu.org> |
6 |
|
|
92 |
block, count); |
block, count); |
93 |
} |
} |
94 |
gdp = group_desc (block_group); |
gdp = group_desc (block_group); |
95 |
bh = bptr (gdp->bg_block_bitmap); |
bh = buffer_lookup (gdp->bg_block_bitmap); |
96 |
|
|
97 |
if (in_range (gdp->bg_block_bitmap, block, gcount) || |
if (in_range (gdp->bg_block_bitmap, block, gcount) || |
98 |
in_range (gdp->bg_inode_bitmap, block, gcount) || |
in_range (gdp->bg_inode_bitmap, block, gcount) || |
114 |
} |
} |
115 |
|
|
116 |
record_global_poke (bh); |
record_global_poke (bh); |
117 |
|
buffer_ref (gdp); |
118 |
record_global_poke (gdp); |
record_global_poke (gdp); |
119 |
|
|
120 |
block += gcount; |
block += gcount; |
140 |
block_t prealloc_goal, |
block_t prealloc_goal, |
141 |
block_t *prealloc_count, block_t *prealloc_block) |
block_t *prealloc_count, block_t *prealloc_block) |
142 |
{ |
{ |
143 |
char *bh; |
char *bh = 0; |
144 |
char *p, *r; |
char *p, *r; |
145 |
int i, j, k, tmp; |
int i, j, k, tmp; |
146 |
unsigned long lmap; |
unsigned long lmap; |
165 |
|
|
166 |
ext2_debug ("goal=%u", goal); |
ext2_debug ("goal=%u", goal); |
167 |
|
|
168 |
repeat: |
repeat: |
169 |
|
assert (! bh); |
170 |
/* |
/* |
171 |
* First, test whether the goal block is free. |
* First, test whether the goal block is free. |
172 |
*/ |
*/ |
173 |
if (goal < sblock->s_first_data_block || goal >= sblock->s_blocks_count) |
if (goal < sblock->s_first_data_block || goal >= sblock->s_blocks_count) |
174 |
goal = sblock->s_first_data_block; |
goal = sblock->s_first_data_block; |
181 |
if (j) |
if (j) |
182 |
goal_attempts++; |
goal_attempts++; |
183 |
#endif |
#endif |
184 |
bh = bptr (gdp->bg_block_bitmap); |
bh = buffer_lookup (gdp->bg_block_bitmap); |
185 |
|
|
186 |
ext2_debug ("goal is at %d:%d", i, j); |
ext2_debug ("goal is at %d:%d", i, j); |
187 |
|
|
196 |
if (j) |
if (j) |
197 |
{ |
{ |
198 |
/* |
/* |
199 |
* The goal was occupied; search forward for a free |
* The goal was occupied; search forward for a free |
200 |
* block within the next 32 blocks |
* block within the next 32 blocks |
201 |
*/ |
*/ |
202 |
lmap = ((((unsigned long *) bh)[j >> 5]) >> |
lmap = ((((unsigned long *) bh)[j >> 5]) >> |
203 |
((j & 31) + 1)); |
((j & 31) + 1)); |
244 |
j = k; |
j = k; |
245 |
goto got_block; |
goto got_block; |
246 |
} |
} |
247 |
|
|
248 |
|
buffer_put (bh); |
249 |
|
bh = 0; |
250 |
} |
} |
251 |
|
|
252 |
ext2_debug ("bit not found in block group %d", i); |
ext2_debug ("bit not found in block group %d", i); |
253 |
|
|
254 |
/* |
/* |
255 |
* Now search the rest of the groups. We assume that |
* Now search the rest of the groups. We assume that |
256 |
* i and gdp correctly point to the last group visited. |
* i and gdp correctly point to the last group visited. |
257 |
*/ |
*/ |
258 |
for (k = 0; k < groups_count; k++) |
for (k = 0; k < groups_count; k++) |
259 |
{ |
{ |
269 |
spin_unlock (&global_lock); |
spin_unlock (&global_lock); |
270 |
return 0; |
return 0; |
271 |
} |
} |
272 |
bh = bptr (gdp->bg_block_bitmap); |
assert (! bh); |
273 |
|
bh = buffer_lookup (gdp->bg_block_bitmap); |
274 |
r = memscan (bh, 0, sblock->s_blocks_per_group >> 3); |
r = memscan (bh, 0, sblock->s_blocks_per_group >> 3); |
275 |
j = (r - bh) << 3; |
j = (r - bh) << 3; |
276 |
if (j < sblock->s_blocks_per_group) |
if (j < sblock->s_blocks_per_group) |
280 |
sblock->s_blocks_per_group); |
sblock->s_blocks_per_group); |
281 |
if (j >= sblock->s_blocks_per_group) |
if (j >= sblock->s_blocks_per_group) |
282 |
{ |
{ |
283 |
|
buffer_put (bh); |
284 |
|
bh = 0; |
285 |
ext2_error ("free blocks count corrupted for block group %d", i); |
ext2_error ("free blocks count corrupted for block group %d", i); |
286 |
spin_unlock (&global_lock); |
spin_unlock (&global_lock); |
287 |
return 0; |
return 0; |
288 |
} |
} |
289 |
|
|
290 |
search_back: |
search_back: |
291 |
|
assert (bh); |
292 |
/* |
/* |
293 |
* We have succeeded in finding a free byte in the block |
* We have succeeded in finding a free byte in the block |
294 |
* bitmap. Now search backwards up to 7 bits to find the |
* bitmap. Now search backwards up to 7 bits to find the |
295 |
* start of this group of free blocks. |
* start of this group of free blocks. |
296 |
*/ |
*/ |
297 |
for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh); k++, j--); |
for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh); k++, j--); |
298 |
|
|
299 |
got_block: |
got_block: |
300 |
|
assert (bh); |
301 |
|
|
302 |
ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count); |
ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count); |
303 |
|
|
304 |
tmp = j + i * sblock->s_blocks_per_group + sblock->s_first_data_block; |
tmp = j + i * sblock->s_blocks_per_group + sblock->s_first_data_block; |
311 |
if (set_bit (j, bh)) |
if (set_bit (j, bh)) |
312 |
{ |
{ |
313 |
ext2_warning ("bit already set for block %d", j); |
ext2_warning ("bit already set for block %d", j); |
314 |
|
buffer_put (bh); |
315 |
|
bh = 0; |
316 |
goto repeat; |
goto repeat; |
317 |
} |
} |
318 |
|
|
329 |
ext2_debug ("found bit %d", j); |
ext2_debug ("found bit %d", j); |
330 |
|
|
331 |
/* |
/* |
332 |
* Do block preallocation now if required. |
* Do block preallocation now if required. |
333 |
*/ |
*/ |
334 |
#ifdef EXT2_PREALLOCATE |
#ifdef EXT2_PREALLOCATE |
335 |
if (prealloc_goal) |
if (prealloc_goal) |
360 |
j = tmp; |
j = tmp; |
361 |
|
|
362 |
record_global_poke (bh); |
record_global_poke (bh); |
363 |
|
bh = 0; |
364 |
|
|
365 |
if (j >= sblock->s_blocks_count) |
if (j >= sblock->s_blocks_count) |
366 |
{ |
{ |
373 |
j, goal_hits, goal_attempts); |
j, goal_hits, goal_attempts); |
374 |
|
|
375 |
gdp->bg_free_blocks_count--; |
gdp->bg_free_blocks_count--; |
376 |
|
buffer_ref (gdp); |
377 |
record_global_poke (gdp); |
record_global_poke (gdp); |
378 |
|
|
379 |
sblock->s_free_blocks_count--; |
sblock->s_free_blocks_count--; |
380 |
sblock_dirty = 1; |
sblock_dirty = 1; |
381 |
|
|
382 |
sync_out: |
sync_out: |
383 |
|
assert (! bh); |
384 |
spin_unlock (&global_lock); |
spin_unlock (&global_lock); |
385 |
alloc_sync (0); |
alloc_sync (0); |
386 |
|
|
402 |
gdp = NULL; |
gdp = NULL; |
403 |
for (i = 0; i < groups_count; i++) |
for (i = 0; i < groups_count; i++) |
404 |
{ |
{ |
405 |
|
void *bh; |
406 |
gdp = group_desc (i); |
gdp = group_desc (i); |
407 |
desc_count += gdp->bg_free_blocks_count; |
desc_count += gdp->bg_free_blocks_count; |
408 |
x = count_free (bptr (gdp->bg_block_bitmap), block_size); |
bh = buffer_lookup (gdp->bg_block_bitmap); |
409 |
|
x = count_free (bh, block_size); |
410 |
|
buffer_put (bh); |
411 |
printf ("group %d: stored = %d, counted = %lu", |
printf ("group %d: stored = %d, counted = %lu", |
412 |
i, gdp->bg_free_blocks_count, x); |
i, gdp->bg_free_blocks_count, x); |
413 |
bitmap_count += x; |
bitmap_count += x; |
468 |
|
|
469 |
gdp = group_desc (i); |
gdp = group_desc (i); |
470 |
desc_count += gdp->bg_free_blocks_count; |
desc_count += gdp->bg_free_blocks_count; |
471 |
bh = bptr (gdp->bg_block_bitmap); |
bh = buffer_lookup (gdp->bg_block_bitmap); |
472 |
|
|
473 |
if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock, |
if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock, |
474 |
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) |
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) |
494 |
ext2_error ("block #%d of the inode table in group %d is marked free", j, i); |
ext2_error ("block #%d of the inode table in group %d is marked free", j, i); |
495 |
|
|
496 |
x = count_free (bh, block_size); |
x = count_free (bh, block_size); |
497 |
|
buffer_put (bh); |
498 |
if (gdp->bg_free_blocks_count != x) |
if (gdp->bg_free_blocks_count != x) |
499 |
ext2_error ("wrong free blocks count for group %d," |
ext2_error ("wrong free blocks count for group %d," |
500 |
" stored = %d, counted = %lu", |
" stored = %d, counted = %lu", |