* 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].
|
* Copyright 2001-2007, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! block bitmap handling and allocation policies
|
||||||
|
|
||||||
|
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "BlockAllocator.h"
|
#include "BlockAllocator.h"
|
||||||
@@ -451,11 +452,10 @@ BlockAllocator::_Initialize(BlockAllocator *allocator)
|
|||||||
|
|
||||||
Volume *volume = allocator->fVolume;
|
Volume *volume = allocator->fVolume;
|
||||||
uint32 blocks = allocator->fBlocksPerGroup;
|
uint32 blocks = allocator->fBlocksPerGroup;
|
||||||
uint32 numBits = 8 * blocks * volume->BlockSize();
|
|
||||||
uint32 blockShift = volume->BlockShift();
|
uint32 blockShift = volume->BlockShift();
|
||||||
off_t freeBlocks = 0;
|
off_t freeBlocks = 0;
|
||||||
|
|
||||||
uint32 *buffer = (uint32 *)malloc(numBits >> 3);
|
uint32 *buffer = (uint32 *)malloc(blocks << blockShift);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
allocator->fLock.Unlock();
|
allocator->fLock.Unlock();
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
@@ -463,36 +463,41 @@ BlockAllocator::_Initialize(BlockAllocator *allocator)
|
|||||||
|
|
||||||
AllocationGroup *groups = allocator->fGroups;
|
AllocationGroup *groups = allocator->fGroups;
|
||||||
off_t offset = 1;
|
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,
|
if (read_pos(volume->Device(), offset << blockShift, buffer,
|
||||||
blocks << blockShift) < B_OK)
|
blocks << blockShift) < B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// the last allocation group may contain less blocks than the others
|
// the last allocation group may contain less blocks than the others
|
||||||
if (i == num - 1) {
|
if (i == numGroups - 1) {
|
||||||
groups[i].fNumBits = volume->NumBlocks() - i * numBits;
|
groups[i].fNumBits = volume->NumBlocks() - i * bitsPerGroup;
|
||||||
groups[i].fNumBlocks = 1 + ((groups[i].NumBits() - 1) >> (blockShift + 3));
|
groups[i].fNumBlocks = 1 + ((groups[i].NumBits() - 1) >> (blockShift + 3));
|
||||||
} else {
|
} else {
|
||||||
groups[i].fNumBits = numBits;
|
groups[i].fNumBits = bitsPerGroup;
|
||||||
groups[i].fNumBlocks = blocks;
|
groups[i].fNumBlocks = blocks;
|
||||||
}
|
}
|
||||||
groups[i].fStart = offset;
|
groups[i].fStart = offset;
|
||||||
|
|
||||||
// finds all free ranges in this allocation group
|
// finds all free ranges in this allocation group
|
||||||
int32 start = -1, range = 0;
|
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 k = 0; k < count; k++) {
|
||||||
for (int32 j = 0; j < 32 && num < size; j++, num++) {
|
for (int32 j = 0; j < 32 && bit < numBits; j++, bit++) {
|
||||||
if (buffer[k] & (1UL << j)) {
|
if (buffer[k] & (1UL << j)) {
|
||||||
|
// block is in use
|
||||||
if (range > 0) {
|
if (range > 0) {
|
||||||
groups[i].AddFreeRange(start, range);
|
groups[i].AddFreeRange(start, range);
|
||||||
range = 0;
|
range = 0;
|
||||||
}
|
}
|
||||||
} else if (range++ == 0)
|
} else if (range++ == 0) {
|
||||||
start = num;
|
// block is free, start new free range
|
||||||
|
start = bit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (range)
|
if (range)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/* Volume - BFS super block, mounting, etc.
|
/*
|
||||||
*
|
* Copyright 2001-2007, Axel Dörfler, [email protected].
|
||||||
* Copyright 2001-2006, Axel Dörfler, [email protected].
|
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! super block, mounting, etc.
|
||||||
|
|
||||||
|
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "Volume.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);
|
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);
|
ag_shift = HOST_ENDIAN_TO_BFS_INT32(groupShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/* Volume - BFS super block, mounting, etc.
|
/*
|
||||||
*
|
* Copyright 2001-2007, Axel Dörfler, [email protected]. All Rights Reserved.
|
||||||
* Copyright 2001-2006, Axel Dörfler, [email protected]. All Rights Reserved.
|
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! super block, mounting, etc.
|
||||||
|
|
||||||
|
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "Volume.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);
|
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);
|
ag_shift = HOST_ENDIAN_TO_BFS_INT32(groupShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user