* Build fix (bfs_inode::InitCheck() is now const), and cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35494 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2009, Axel Dörfler, [email protected].
|
* Copyright 2003-2010, 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,29 +23,30 @@ using namespace BFS;
|
|||||||
|
|
||||||
|
|
||||||
class CachedBlock {
|
class CachedBlock {
|
||||||
public:
|
public:
|
||||||
CachedBlock(Volume &volume);
|
CachedBlock(Volume& volume);
|
||||||
CachedBlock(Volume &volume, block_run run);
|
CachedBlock(Volume& volume, block_run run);
|
||||||
~CachedBlock();
|
~CachedBlock();
|
||||||
|
|
||||||
uint8 *SetTo(block_run run);
|
uint8* SetTo(block_run run);
|
||||||
uint8 *SetTo(off_t offset);
|
uint8* SetTo(off_t offset);
|
||||||
|
|
||||||
void Unset();
|
void Unset();
|
||||||
|
|
||||||
uint8 *Block() const { return fBlock; }
|
uint8* Block() const { return fBlock; }
|
||||||
off_t BlockNumber() const { return fBlockNumber; }
|
off_t BlockNumber() const { return fBlockNumber; }
|
||||||
uint32 BlockSize() const { return fVolume.BlockSize(); }
|
uint32 BlockSize() const { return fVolume.BlockSize(); }
|
||||||
uint32 BlockShift() const { return fVolume.BlockShift(); }
|
uint32 BlockShift() const
|
||||||
|
{ return fVolume.BlockShift(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Volume &fVolume;
|
Volume& fVolume;
|
||||||
off_t fBlockNumber;
|
off_t fBlockNumber;
|
||||||
uint8 *fBlock;
|
uint8* fBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CachedBlock::CachedBlock(Volume &volume)
|
CachedBlock::CachedBlock(Volume& volume)
|
||||||
:
|
:
|
||||||
fVolume(volume),
|
fVolume(volume),
|
||||||
fBlockNumber(-1LL),
|
fBlockNumber(-1LL),
|
||||||
@@ -77,26 +78,27 @@ CachedBlock::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint8 *
|
inline uint8*
|
||||||
CachedBlock::SetTo(off_t block)
|
CachedBlock::SetTo(off_t block)
|
||||||
{
|
{
|
||||||
if (block == fBlockNumber)
|
if (block == fBlockNumber)
|
||||||
return fBlock;
|
return fBlock;
|
||||||
if (fBlock == NULL) {
|
if (fBlock == NULL) {
|
||||||
fBlock = (uint8 *)malloc(BlockSize());
|
fBlock = (uint8*)malloc(BlockSize());
|
||||||
if (fBlock == NULL)
|
if (fBlock == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fBlockNumber = block;
|
fBlockNumber = block;
|
||||||
if (read_pos(fVolume.Device(), block << BlockShift(), fBlock, BlockSize()) < (ssize_t)BlockSize())
|
if (read_pos(fVolume.Device(), block << BlockShift(), fBlock, BlockSize())
|
||||||
|
< (ssize_t)BlockSize())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return fBlock;
|
return fBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint8 *
|
inline uint8*
|
||||||
CachedBlock::SetTo(block_run run)
|
CachedBlock::SetTo(block_run run)
|
||||||
{
|
{
|
||||||
return SetTo(fVolume.ToBlock(run));
|
return SetTo(fVolume.ToBlock(run));
|
||||||
@@ -106,20 +108,22 @@ CachedBlock::SetTo(block_run run)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
Stream::Stream(Volume &volume, block_run run)
|
Stream::Stream(Volume& volume, block_run run)
|
||||||
:
|
:
|
||||||
fVolume(volume)
|
fVolume(volume)
|
||||||
{
|
{
|
||||||
if (read_pos(volume.Device(), volume.ToOffset(run), this, sizeof(bfs_inode)) != sizeof(bfs_inode))
|
if (read_pos(volume.Device(), volume.ToOffset(run), this, sizeof(bfs_inode))
|
||||||
|
!= sizeof(bfs_inode))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Stream::Stream(Volume &volume, off_t id)
|
Stream::Stream(Volume& volume, off_t id)
|
||||||
:
|
:
|
||||||
fVolume(volume)
|
fVolume(volume)
|
||||||
{
|
{
|
||||||
if (read_pos(volume.Device(), volume.ToOffset(id), this, sizeof(bfs_inode)) != sizeof(bfs_inode))
|
if (read_pos(volume.Device(), volume.ToOffset(id), this, sizeof(bfs_inode))
|
||||||
|
!= sizeof(bfs_inode))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,13 +141,13 @@ Stream::InitCheck()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::GetNextSmallData(const small_data **_smallData) const
|
Stream::GetNextSmallData(const small_data** _smallData) const
|
||||||
{
|
{
|
||||||
// TODO: Stream derives from bfs_inode and we read only sizeof(bfs_inode)
|
// TODO: Stream derives from bfs_inode and we read only sizeof(bfs_inode)
|
||||||
// bytes from disk, i.e. the small data region is not in memory.
|
// bytes from disk, i.e. the small data region is not in memory.
|
||||||
panic("Stream::GetNextSmallData(): small data region is not loaded!");
|
panic("Stream::GetNextSmallData(): small data region is not loaded!");
|
||||||
|
|
||||||
const small_data *smallData = *_smallData;
|
const small_data* smallData = *_smallData;
|
||||||
|
|
||||||
// begin from the start?
|
// begin from the start?
|
||||||
if (smallData == NULL)
|
if (smallData == NULL)
|
||||||
@@ -162,13 +166,13 @@ Stream::GetNextSmallData(const small_data **_smallData) const
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::GetName(char *name, size_t size) const
|
Stream::GetName(char* name, size_t size) const
|
||||||
{
|
{
|
||||||
const small_data *smallData = NULL;
|
const small_data* smallData = NULL;
|
||||||
while (GetNextSmallData(&smallData) == B_OK) {
|
while (GetNextSmallData(&smallData) == B_OK) {
|
||||||
if (*smallData->Name() == FILE_NAME_NAME
|
if (*smallData->Name() == FILE_NAME_NAME
|
||||||
&& smallData->NameSize() == FILE_NAME_NAME_LENGTH) {
|
&& smallData->NameSize() == FILE_NAME_NAME_LENGTH) {
|
||||||
strlcpy(name, (const char *)smallData->Data(), size);
|
strlcpy(name, (const char*)smallData->Data(), size);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,12 +181,12 @@ Stream::GetName(char *name, size_t size) const
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::ReadLink(char *buffer, size_t bufferSize)
|
Stream::ReadLink(char* buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
// link in the stream
|
// link in the stream
|
||||||
|
|
||||||
if (Flags() & INODE_LONG_SYMLINK)
|
if (Flags() & INODE_LONG_SYMLINK)
|
||||||
return ReadAt(0, (uint8 *)buffer, &bufferSize);
|
return ReadAt(0, (uint8*)buffer, &bufferSize);
|
||||||
|
|
||||||
// link in the inode
|
// link in the inode
|
||||||
|
|
||||||
@@ -192,12 +196,13 @@ Stream::ReadLink(char *buffer, size_t bufferSize)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
Stream::FindBlockRun(off_t pos, block_run& run, off_t& offset)
|
||||||
{
|
{
|
||||||
// find matching block run
|
// find matching block run
|
||||||
|
|
||||||
if (data.MaxDirectRange() > 0 && pos >= data.MaxDirectRange()) {
|
if (data.MaxDirectRange() > 0 && pos >= data.MaxDirectRange()) {
|
||||||
if (data.MaxDoubleIndirectRange() > 0 && pos >= data.MaxIndirectRange()) {
|
if (data.MaxDoubleIndirectRange() > 0
|
||||||
|
&& pos >= data.MaxIndirectRange()) {
|
||||||
// access to double indirect blocks
|
// access to double indirect blocks
|
||||||
|
|
||||||
CachedBlock cached(fVolume);
|
CachedBlock cached(fVolume);
|
||||||
@@ -211,7 +216,7 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
off_t start = pos - data.MaxIndirectRange();
|
off_t start = pos - data.MaxIndirectRange();
|
||||||
int32 index = start / indirectSize;
|
int32 index = start / indirectSize;
|
||||||
|
|
||||||
block_run *indirect = (block_run *)cached.SetTo(
|
block_run* indirect = (block_run*)cached.SetTo(
|
||||||
fVolume.ToBlock(data.double_indirect) + index / runsPerBlock);
|
fVolume.ToBlock(data.double_indirect) + index / runsPerBlock);
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -221,13 +226,14 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
|
|
||||||
int32 current = (start % indirectSize) / directSize;
|
int32 current = (start % indirectSize) / directSize;
|
||||||
|
|
||||||
indirect = (block_run *)cached.SetTo(
|
indirect = (block_run*)cached.SetTo(fVolume.ToBlock(indirect[
|
||||||
fVolume.ToBlock(indirect[index % runsPerBlock]) + current / runsPerBlock);
|
index % runsPerBlock]) + current / runsPerBlock);
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
run = indirect[current % runsPerBlock];
|
run = indirect[current % runsPerBlock];
|
||||||
offset = data.MaxIndirectRange() + (index * indirectSize) + (current * directSize);
|
offset = data.MaxIndirectRange() + (index * indirectSize)
|
||||||
|
+ (current * directSize);
|
||||||
//printf("\tfCurrent = %ld, fRunFileOffset = %Ld, fRunBlockEnd = %Ld, fRun = %ld,%d\n",fCurrent,fRunFileOffset,fRunBlockEnd,fRun.allocation_group,fRun.start);
|
//printf("\tfCurrent = %ld, fRunFileOffset = %Ld, fRunBlockEnd = %Ld, fRun = %ld,%d\n",fCurrent,fRunFileOffset,fRunBlockEnd,fRun.allocation_group,fRun.start);
|
||||||
} else {
|
} else {
|
||||||
// access to indirect blocks
|
// access to indirect blocks
|
||||||
@@ -238,8 +244,8 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
CachedBlock cached(fVolume);
|
CachedBlock cached(fVolume);
|
||||||
off_t block = fVolume.ToBlock(data.indirect);
|
off_t block = fVolume.ToBlock(data.indirect);
|
||||||
|
|
||||||
for (int32 i = 0;i < data.indirect.Length();i++) {
|
for (int32 i = 0; i < data.indirect.Length(); i++) {
|
||||||
block_run *indirect = (block_run *)cached.SetTo(block + i);
|
block_run* indirect = (block_run *)cached.SetTo(block + i);
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
@@ -248,10 +254,12 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
if (indirect[current].IsZero())
|
if (indirect[current].IsZero())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
runBlockEnd += indirect[current].Length() << cached.BlockShift();
|
runBlockEnd
|
||||||
|
+= indirect[current].Length() << cached.BlockShift();
|
||||||
if (runBlockEnd > pos) {
|
if (runBlockEnd > pos) {
|
||||||
run = indirect[current];
|
run = indirect[current];
|
||||||
offset = runBlockEnd - (run.Length() << cached.BlockShift());
|
offset = runBlockEnd -
|
||||||
|
(run.Length() << cached.BlockShift());
|
||||||
//printf("reading from indirect block: %ld,%d\n",fRun.allocation_group,fRun.start);
|
//printf("reading from indirect block: %ld,%d\n",fRun.allocation_group,fRun.start);
|
||||||
//printf("### indirect-run[%ld] = (%ld,%d,%d), offset = %Ld\n",fCurrent,fRun.allocation_group,fRun.start,fRun.length,fRunFileOffset);
|
//printf("### indirect-run[%ld] = (%ld,%d,%d), offset = %Ld\n",fCurrent,fRun.allocation_group,fRun.start,fRun.length,fRunFileOffset);
|
||||||
return fVolume.ValidateBlockRun(run);
|
return fVolume.ValidateBlockRun(run);
|
||||||
@@ -286,7 +294,7 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
Stream::ReadAt(off_t pos, uint8* buffer, size_t* _length)
|
||||||
{
|
{
|
||||||
// set/check boundaries for pos/length
|
// set/check boundaries for pos/length
|
||||||
|
|
||||||
@@ -312,15 +320,17 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
uint32 bytesRead = 0;
|
uint32 bytesRead = 0;
|
||||||
uint32 blockSize = fVolume.BlockSize();
|
uint32 blockSize = fVolume.BlockSize();
|
||||||
uint32 blockShift = fVolume.BlockShift();
|
uint32 blockShift = fVolume.BlockShift();
|
||||||
uint8 *block;
|
uint8* block;
|
||||||
|
|
||||||
// the first block_run we read could not be aligned to the block_size boundary
|
// the first block_run we read could not be aligned to the block_size boundary
|
||||||
// (read partial block at the beginning)
|
// (read partial block at the beginning)
|
||||||
|
|
||||||
// pos % block_size == (pos - offset) % block_size, offset % block_size == 0
|
// pos % block_size == (pos - offset) % block_size, offset % block_size == 0
|
||||||
if (pos % blockSize != 0) {
|
if (pos % blockSize != 0) {
|
||||||
run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start() + ((pos - offset) >> blockShift));
|
run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start()
|
||||||
run.length = HOST_ENDIAN_TO_BFS_INT16(run.Length() - ((pos - offset) >> blockShift));
|
+ ((pos - offset) >> blockShift));
|
||||||
|
run.length = HOST_ENDIAN_TO_BFS_INT16(run.Length()
|
||||||
|
- ((pos - offset) >> blockShift));
|
||||||
|
|
||||||
CachedBlock cached(fVolume, run);
|
CachedBlock cached(fVolume, run);
|
||||||
if ((block = cached.Block()) == NULL) {
|
if ((block = cached.Block()) == NULL) {
|
||||||
@@ -355,8 +365,10 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
// offset is the offset to the current pos in the block_run
|
// offset is the offset to the current pos in the block_run
|
||||||
run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start() + ((pos - offset) >> blockShift));
|
run.start = HOST_ENDIAN_TO_BFS_INT16(run.Start()
|
||||||
run.length = HOST_ENDIAN_TO_BFS_INT16(run.Length() - ((pos - offset) >> blockShift));
|
+ ((pos - offset) >> blockShift));
|
||||||
|
run.length = HOST_ENDIAN_TO_BFS_INT16(run.Length()
|
||||||
|
- ((pos - offset) >> blockShift));
|
||||||
|
|
||||||
if (uint32(run.Length() << blockShift) > length) {
|
if (uint32(run.Length() << blockShift) > length) {
|
||||||
if (length < blockSize) {
|
if (length < blockSize) {
|
||||||
@@ -373,7 +385,8 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
partial = true;
|
partial = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_pos(fVolume.Device(), fVolume.ToOffset(run), buffer + bytesRead, run.Length() << fVolume.BlockShift()) < B_OK) {
|
if (read_pos(fVolume.Device(), fVolume.ToOffset(run), buffer + bytesRead,
|
||||||
|
run.Length() << fVolume.BlockShift()) < B_OK) {
|
||||||
*_length = bytesRead;
|
*_length = bytesRead;
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
@@ -403,8 +416,8 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Node *
|
Node*
|
||||||
Stream::NodeFactory(Volume &volume, off_t id)
|
Stream::NodeFactory(Volume& volume, off_t id)
|
||||||
{
|
{
|
||||||
Stream stream(volume, id);
|
Stream stream(volume, id);
|
||||||
if (stream.InitCheck() != B_OK)
|
if (stream.InitCheck() != B_OK)
|
||||||
@@ -424,9 +437,9 @@ Stream::NodeFactory(Volume &volume, off_t id)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
bfs_inode::InitCheck(Volume *volume)
|
bfs_inode::InitCheck(Volume* volume) const
|
||||||
{
|
{
|
||||||
if (Flags() & INODE_NOT_READY) {
|
if ((Flags() & INODE_NOT_READY) != 0) {
|
||||||
// the other fields may not yet contain valid values
|
// the other fields may not yet contain valid values
|
||||||
return B_BUSY;
|
return B_BUSY;
|
||||||
}
|
}
|
||||||
@@ -447,9 +460,8 @@ bfs_inode::InitCheck(Volume *volume)
|
|||||||
|| attributes.Start() > (1L << volume->AllocationGroupShift()))
|
|| attributes.Start() > (1L << volume->AllocationGroupShift()))
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
// ToDo: Add some tests to check the integrity of the other stuff here,
|
// TODO: Add some tests to check the integrity of the other stuff here,
|
||||||
// especially for the data_stream!
|
// especially for the data_stream!
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user