Added minimum block support needed by the physical partition allocator.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5647 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d8b4553a67
commit
52368aac43
@ -112,43 +112,49 @@ Allocator::GetExtent(Udf::extent_address extent)
|
|||||||
|
|
||||||
\param block Output parameter into which the number of the
|
\param block Output parameter into which the number of the
|
||||||
allocated block is stored.
|
allocated block is stored.
|
||||||
|
\param minimumBlock The minimum acceptable block number (used
|
||||||
|
by the physical partition allocator).
|
||||||
|
|
||||||
\return
|
\return
|
||||||
- B_OK: Success.
|
- B_OK: Success.
|
||||||
- error code: Failure, no blocks available.
|
- error code: Failure, no blocks available.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
Allocator::GetNextBlock(uint32 &block)
|
Allocator::GetNextBlock(uint32 &block, uint32 minimumBlock)
|
||||||
{
|
{
|
||||||
status_t error = InitCheck();
|
status_t error = InitCheck();
|
||||||
if (!error) {
|
if (!error) {
|
||||||
Udf::extent_address extent;
|
Udf::extent_address extent;
|
||||||
error = GetNextExtent(BlockSize(), true, extent);
|
error = GetNextExtent(BlockSize(), true, extent, minimumBlock);
|
||||||
if (!error)
|
if (!error)
|
||||||
block = extent.location();
|
block = extent.location();
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Allocates the next available block.
|
/*! \brief Allocates the next available extent of given length.
|
||||||
|
|
||||||
\param length The desired length (in bytes) of the extent.
|
\param length The desired length (in bytes) of the extent.
|
||||||
\param contiguous If false, signals that an extent of shorter length will
|
\param contiguous If false, signals that an extent of shorter length will
|
||||||
be accepted. This allows for small chunks of
|
be accepted. This allows for small chunks of
|
||||||
unallocated space to be consumed, provided a
|
unallocated space to be consumed, provided a
|
||||||
contiguous chunk is not needed.
|
contiguous chunk is not needed.
|
||||||
\param block Output parameter into which the extent as allocated
|
\param extent Output parameter into which the extent as allocated
|
||||||
is stored. Note that the length field of the extent
|
is stored. Note that the length field of the extent
|
||||||
may be shorter than the length parameter passed
|
may be shorter than the length parameter passed
|
||||||
to this function is \a contiguous is false.
|
to this function is \a contiguous is false.
|
||||||
|
\param minimumStartingBlock The minimum acceptable starting block
|
||||||
|
for the extent (used by the physical
|
||||||
|
partition allocator).
|
||||||
|
|
||||||
\return
|
\return
|
||||||
- B_OK: Success.
|
- B_OK: Success.
|
||||||
- error code: Failure.
|
- error code: Failure.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
||||||
Udf::extent_address &extent)
|
Udf::extent_address &extent,
|
||||||
|
uint32 minimumStartingBlock)
|
||||||
{
|
{
|
||||||
uint32 length = BlocksFor(_length);
|
uint32 length = BlocksFor(_length);
|
||||||
bool isPartial = false;
|
bool isPartial = false;
|
||||||
@ -159,8 +165,34 @@ Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
|||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
uint32 chunkOffset = i->location();
|
uint32 chunkOffset = i->location();
|
||||||
uint32 chunkLength = BlocksFor(i->length());
|
uint32 chunkLength = BlocksFor(i->length());
|
||||||
if (length <= chunkLength) {
|
if (chunkOffset < minimumStartingBlock)
|
||||||
|
{
|
||||||
|
if (minimumStartingBlock < chunkOffset+chunkLength) {
|
||||||
|
// Start of chunk is below min starting block. See if
|
||||||
|
// any part of the chunk would make for an acceptable
|
||||||
|
// allocation
|
||||||
|
uint32 difference = minimumStartingBlock - chunkOffset;
|
||||||
|
uint32 newOffset = minimumStartingBlock;
|
||||||
|
uint32 newLength = chunkLength-difference;
|
||||||
|
if (length <= newLength) {
|
||||||
|
// new chunk is still long enough
|
||||||
|
Udf::extent_address newExtent(newOffset, _length);
|
||||||
|
if (GetExtent(newExtent) == B_OK) {
|
||||||
|
extent = newExtent;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
} else if (!contiguous) {
|
||||||
|
// new chunk is too short, but we're allowed to
|
||||||
|
// allocate a shorter extent, so we'll do it.
|
||||||
|
Udf::extent_address newExtent(newOffset, newLength<<BlockShift());
|
||||||
|
if (GetExtent(newExtent) == B_OK) {
|
||||||
|
extent = newExtent;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (length <= chunkLength) {
|
||||||
// Chunk is larger than necessary. Allocate first
|
// Chunk is larger than necessary. Allocate first
|
||||||
// length blocks, and resize the chunk appropriately.
|
// length blocks, and resize the chunk appropriately.
|
||||||
extent.set_location(chunkOffset);
|
extent.set_location(chunkOffset);
|
||||||
@ -181,6 +213,9 @@ Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
|||||||
}
|
}
|
||||||
// No sufficient chunk found, so try to allocate from the tail
|
// No sufficient chunk found, so try to allocate from the tail
|
||||||
uint32 maxLength = LONG_MAX-Length();
|
uint32 maxLength = LONG_MAX-Length();
|
||||||
|
if (minimumStartingBlock > Tail())
|
||||||
|
maxLength -= minimumStartingBlock - Tail();
|
||||||
|
uint32 tail = minimumStartingBlock > Tail() ? minimumStartingBlock : Tail();
|
||||||
if (length > maxLength) {
|
if (length > maxLength) {
|
||||||
if (contiguous)
|
if (contiguous)
|
||||||
error = B_DEVICE_FULL;
|
error = B_DEVICE_FULL;
|
||||||
@ -190,10 +225,12 @@ Allocator::GetNextExtent(uint32 _length, bool contiguous,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
extent.set_location(Length());
|
Udf::extent_address newExtent(tail, isPartial ? length<<BlockShift() : _length);
|
||||||
extent.set_length(isPartial ? length<<BlockShift() : _length);
|
if (GetExtent(newExtent) == B_OK) {
|
||||||
fLength += length;
|
extent = newExtent;
|
||||||
}
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,10 @@ public:
|
|||||||
status_t GetBlock(uint32 block);
|
status_t GetBlock(uint32 block);
|
||||||
status_t GetExtent(Udf::extent_address extent);
|
status_t GetExtent(Udf::extent_address extent);
|
||||||
|
|
||||||
status_t GetNextBlock(uint32 &block);
|
status_t GetNextBlock(uint32 &block, uint32 minimumBlock = 0);
|
||||||
status_t GetNextExtent(uint32 length, bool contiguous,
|
status_t GetNextExtent(uint32 length, bool contiguous,
|
||||||
Udf::extent_address &extent);
|
Udf::extent_address &extent,
|
||||||
|
uint32 minimumStartingBlock = 0);
|
||||||
|
|
||||||
uint32 Length() const { return fLength; }
|
uint32 Length() const { return fLength; }
|
||||||
uint32 Tail() const { return fLength; } //!< Returns the first unallocated block in the tail
|
uint32 Tail() const { return fLength; } //!< Returns the first unallocated block in the tail
|
||||||
|
Loading…
Reference in New Issue
Block a user