* Fixed a bug introduced with big-endian fixes in r17557; the super block's blocks_per_ag
field was always 1, and therefore, the last allocation group could grow too large. Thanks to Samuel Rodriguez Perez for reporting the error (bfs_shell was crashing on larger images). * Minor cleanup in BlockAllocator::_Initialize(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21053 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
/* BlockAllocator - block bitmap handling and allocation policies
|
||||
*
|
||||
/*
|
||||
* Copyright 2001-2007, Axel Dörfler, [email protected].
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
//! block bitmap handling and allocation policies
|
||||
|
||||
|
||||
#include "Debug.h"
|
||||
#include "BlockAllocator.h"
|
||||
@@ -451,11 +452,10 @@ BlockAllocator::_Initialize(BlockAllocator *allocator)
|
||||
|
||||
Volume *volume = allocator->fVolume;
|
||||
uint32 blocks = allocator->fBlocksPerGroup;
|
||||
uint32 numBits = 8 * blocks * volume->BlockSize();
|
||||
uint32 blockShift = volume->BlockShift();
|
||||
off_t freeBlocks = 0;
|
||||
|
||||
uint32 *buffer = (uint32 *)malloc(numBits >> 3);
|
||||
uint32 *buffer = (uint32 *)malloc(blocks << blockShift);
|
||||
if (buffer == NULL) {
|
||||
allocator->fLock.Unlock();
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
@@ -463,36 +463,41 @@ BlockAllocator::_Initialize(BlockAllocator *allocator)
|
||||
|
||||
AllocationGroup *groups = allocator->fGroups;
|
||||
off_t offset = 1;
|
||||
int32 num = allocator->fNumGroups;
|
||||
uint32 bitsPerGroup = 8 * (blocks << blockShift);
|
||||
int32 numGroups = allocator->fNumGroups;
|
||||
|
||||
for (int32 i = 0; i < num; i++) {
|
||||
for (int32 i = 0; i < numGroups; i++) {
|
||||
if (read_pos(volume->Device(), offset << blockShift, buffer,
|
||||
blocks << blockShift) < B_OK)
|
||||
break;
|
||||
|
||||
// the last allocation group may contain less blocks than the others
|
||||
if (i == num - 1) {
|
||||
groups[i].fNumBits = volume->NumBlocks() - i * numBits;
|
||||
if (i == numGroups - 1) {
|
||||
groups[i].fNumBits = volume->NumBlocks() - i * bitsPerGroup;
|
||||
groups[i].fNumBlocks = 1 + ((groups[i].NumBits() - 1) >> (blockShift + 3));
|
||||
} else {
|
||||
groups[i].fNumBits = numBits;
|
||||
groups[i].fNumBits = bitsPerGroup;
|
||||
groups[i].fNumBlocks = blocks;
|
||||
}
|
||||
groups[i].fStart = offset;
|
||||
|
||||
// finds all free ranges in this allocation group
|
||||
int32 start = -1, range = 0;
|
||||
int32 size = groups[i].fNumBits, num = 0;
|
||||
int32 numBits = groups[i].fNumBits, bit = 0;
|
||||
int32 count = (numBits + 31) / 32;
|
||||
|
||||
for (int32 k = 0;k < (size >> 2);k++) {
|
||||
for (int32 j = 0; j < 32 && num < size; j++, num++) {
|
||||
for (int32 k = 0; k < count; k++) {
|
||||
for (int32 j = 0; j < 32 && bit < numBits; j++, bit++) {
|
||||
if (buffer[k] & (1UL << j)) {
|
||||
// block is in use
|
||||
if (range > 0) {
|
||||
groups[i].AddFreeRange(start, range);
|
||||
range = 0;
|
||||
}
|
||||
} else if (range++ == 0)
|
||||
start = num;
|
||||
} else if (range++ == 0) {
|
||||
// block is free, start new free range
|
||||
start = bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (range)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/* Volume - BFS super block, mounting, etc.
|
||||
*
|
||||
* Copyright 2001-2006, Axel Dörfler, [email protected].
|
||||
/*
|
||||
* Copyright 2001-2007, Axel Dörfler, [email protected].
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
//! super block, mounting, etc.
|
||||
|
||||
|
||||
#include "Debug.h"
|
||||
#include "Volume.h"
|
||||
@@ -233,7 +234,7 @@ disk_super_block::Initialize(const char *diskName, off_t numBlocks, uint32 block
|
||||
}
|
||||
|
||||
num_ags = HOST_ENDIAN_TO_BFS_INT32(numGroups);
|
||||
blocks_per_ag = HOST_ENDIAN_TO_BFS_INT32(1);
|
||||
blocks_per_ag = HOST_ENDIAN_TO_BFS_INT32(blocksPerGroup);
|
||||
ag_shift = HOST_ENDIAN_TO_BFS_INT32(groupShift);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/* Volume - BFS super block, mounting, etc.
|
||||
*
|
||||
* Copyright 2001-2006, Axel Dörfler, [email protected]. All Rights Reserved.
|
||||
/*
|
||||
* Copyright 2001-2007, Axel Dörfler, [email protected]. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
//! super block, mounting, etc.
|
||||
|
||||
|
||||
#include "Debug.h"
|
||||
#include "Volume.h"
|
||||
@@ -223,7 +224,7 @@ disk_super_block::Initialize(const char *diskName, off_t numBlocks, uint32 block
|
||||
}
|
||||
|
||||
num_ags = HOST_ENDIAN_TO_BFS_INT32(numGroups);
|
||||
blocks_per_ag = HOST_ENDIAN_TO_BFS_INT32(1);
|
||||
blocks_per_ag = HOST_ENDIAN_TO_BFS_INT32(blocksPerGroup);
|
||||
ag_shift = HOST_ENDIAN_TO_BFS_INT32(groupShift);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user