From 68f08f67f519bf2508344836ff87ea7469c2a600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 7 May 2007 10:56:40 +0000 Subject: [PATCH] * 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 --- .../file_systems/bfs/BlockAllocator.cpp | 33 +++++++++++-------- .../kernel/file_systems/bfs/Volume.cpp | 9 ++--- .../kernel/file_systems/bfs/r5/Volume.cpp | 9 ++--- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 70359e845b..0f14ee9e5d 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -1,9 +1,10 @@ -/* BlockAllocator - block bitmap handling and allocation policies - * +/* * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. * 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) diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 611cd26e52..76ab8517d7 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -1,9 +1,10 @@ -/* Volume - BFS super block, mounting, etc. - * - * Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de. +/* + * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. * 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); } diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp b/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp index 0205c87016..c59efc9e22 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp @@ -1,9 +1,10 @@ -/* Volume - BFS super block, mounting, etc. - * - * Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. +/* + * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. 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); }