xfs: Fixes and refactoring some parts
Found some bugs while testing different possible cases of Extent based directories (1 extentmap case). Also did some refactoring. Change-Id: Icb3b6e21de100c1bee93779c419bb2e86c694ae6 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3118 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
19488d5c68
commit
8897bed702
@@ -49,18 +49,11 @@ Extent::FillBlockBuffer()
|
||||
if (fBlockBuffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
Volume* volume = fInode->GetVolume();
|
||||
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
|
||||
xfs_daddr_t readPos =
|
||||
fInode->FileSystemBlockToAddr(fMap->br_startblock);
|
||||
|
||||
uint64 agNo = FSBLOCKS_TO_AGNO(fMap->br_startblock, volume);
|
||||
uint64 agBlockNo = FSBLOCKS_TO_AGBLOCKNO(fMap->br_startblock, volume);
|
||||
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(volume->BlockLog(),
|
||||
((uint64)(agNo * numberOfBlocksInAg) + agBlockNo));
|
||||
|
||||
xfs_daddr_t readPos = blockToRead * BASICBLOCKSIZE;
|
||||
|
||||
TRACE("blockToRead: (%ld), readPos: (%ld)\n", blockToRead, readPos);
|
||||
if (read_pos(volume->Device(), readPos, fBlockBuffer, len) != len) {
|
||||
if (read_pos(fInode->GetVolume()->Device(), readPos, fBlockBuffer, len)
|
||||
!= len) {
|
||||
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
@@ -157,6 +150,7 @@ Extent::GetNext(char* name, size_t* length, xfs_ino_t* ino)
|
||||
|
||||
int numberOfEntries = B_BENDIAN_TO_HOST_INT32(BlockTail()->count);
|
||||
TRACE("numberOfEntries:(%d)\n", numberOfEntries);
|
||||
uint16 currentOffset = (char*)entry - fBlockBuffer;
|
||||
|
||||
for (int i = 0; i < numberOfEntries; i++) {
|
||||
TRACE("EntryNumber:(%d)\n", i);
|
||||
@@ -164,19 +158,19 @@ Extent::GetNext(char* name, size_t* length, xfs_ino_t* ino)
|
||||
|
||||
if (B_BENDIAN_TO_HOST_INT16(unusedEntry->freetag) == DIR2_FREE_TAG) {
|
||||
TRACE("Unused entry found\n");
|
||||
i--;
|
||||
currentOffset += B_BENDIAN_TO_HOST_INT16(unusedEntry->length);
|
||||
entry = (void*)
|
||||
((char*)entry + B_BENDIAN_TO_HOST_INT16(unusedEntry->length));
|
||||
continue;
|
||||
}
|
||||
ExtentDataEntry* dataEntry = (ExtentDataEntry*) entry;
|
||||
|
||||
uint16 currentOffset = (char*)dataEntry - fBlockBuffer;
|
||||
TRACE("GetNext: fOffset:(%d), currentOffset:(%d)\n",
|
||||
fOffset, currentOffset);
|
||||
|
||||
if (fOffset >= currentOffset) {
|
||||
entry = (void*)((char*)entry + EntrySize(dataEntry->namelen));
|
||||
currentOffset += EntrySize(dataEntry->namelen);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#define DIR2_FREE_TAG 0xffff
|
||||
#define XFS_DIR2_DATA_FD_COUNT 3
|
||||
#define EXTENT_REC_SIZE 128
|
||||
#define MASK(n) ((1UL << n) - 1)
|
||||
#define FSBLOCKS_TO_AGNO(n, volume) ((n) >> volume->AgBlocksLog())
|
||||
#define FSBLOCKS_TO_AGBLOCKNO(n, volume) ((n) & MASK(volume->AgBlocksLog()))
|
||||
#define EXTENT_SIZE 16
|
||||
#define BLOCKNO_FROM_ADDRESS(n, volume) \
|
||||
((n) >> (volume->BlockLog() + volume->DirBlockLog()))
|
||||
|
||||
@@ -37,6 +37,13 @@ xfs_inode_t::SwapEndian()
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
xfs_inode_t::ForkOffset() const
|
||||
{
|
||||
return di_forkoff;
|
||||
}
|
||||
|
||||
|
||||
xfs_rfsblock_t
|
||||
xfs_inode_t::BlockCount() const
|
||||
{
|
||||
@@ -216,6 +223,24 @@ Inode::GetFromDisk()
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
Inode::FileSystemBlockToAddr(uint64 block)
|
||||
{
|
||||
xfs_agblock_t numberOfBlocksInAg = fVolume->AgBlocks();
|
||||
|
||||
uint64 agNo = FSBLOCKS_TO_AGNO(block, fVolume);
|
||||
uint64 agBlockNo = FSBLOCKS_TO_AGBLOCKNO(block, fVolume);
|
||||
|
||||
xfs_fsblock_t actualBlockToRead =
|
||||
FSBLOCKS_TO_BASICBLOCKS(fVolume->BlockLog(),
|
||||
((uint64)(agNo * numberOfBlocksInAg) + agBlockNo));
|
||||
TRACE("blockToRead:(%d)\n", actualBlockToRead);
|
||||
|
||||
uint64 readPos = actualBlockToRead * (BASICBLOCKSIZE);
|
||||
return readPos;
|
||||
}
|
||||
|
||||
|
||||
Inode::~Inode()
|
||||
{
|
||||
delete fBuffer;
|
||||
|
||||
@@ -32,10 +32,13 @@
|
||||
// Gets the offset into the block from the inode number
|
||||
#define DIR_DFORK_PTR(dir_ino_ptr) (void*) \
|
||||
((char*) dir_ino_ptr + DATA_FORK_OFFSET)
|
||||
#define DIR_AFORK_PTR(dir_ino_ptr) \
|
||||
(void*)((char*)XFS_DFORK_PTR + \
|
||||
((uint32)dir_ino_ptr->di_forkoff<<3))
|
||||
#define DIR_AFORK_PTR(dir_ino_ptr, forkoff) \
|
||||
(void*)((char*)DIR_DFORK_PTR(dir_ino_ptr) + \
|
||||
(((uint32)forkoff)<<3))
|
||||
#define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0
|
||||
#define MASK(n) ((1UL << n) - 1)
|
||||
#define FSBLOCKS_TO_AGNO(n, volume) ((n) >> volume->AgBlocksLog())
|
||||
#define FSBLOCKS_TO_AGBLOCKNO(n, volume) ((n) & MASK(volume->AgBlocksLog()))
|
||||
|
||||
|
||||
// xfs_da_blkinfo_t
|
||||
@@ -92,7 +95,7 @@ struct xfs_inode_t {
|
||||
uint32 UserId() const;
|
||||
uint32 GroupId() const;
|
||||
xfs_extnum_t DataExtentsCount() const;
|
||||
|
||||
uint8 ForkOffset() const;
|
||||
uint16 di_magic;
|
||||
uint16 di_mode;
|
||||
// uses standard S_Ixxx
|
||||
@@ -191,6 +194,9 @@ public:
|
||||
bool HasFileTypeField() const;
|
||||
xfs_extnum_t DataExtentsCount() const
|
||||
{ return fNode->DataExtentsCount(); }
|
||||
uint64 FileSystemBlockToAddr(uint64 block);
|
||||
uint8 ForkOffset() const
|
||||
{ return fNode->ForkOffset(); }
|
||||
|
||||
private:
|
||||
status_t GetFromDisk();
|
||||
|
||||
@@ -115,21 +115,11 @@ LeafDirectory::FillBuffer(int type, char* blockBuffer, int howManyBlocksFurthur)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
Volume* volume = fInode->GetVolume();
|
||||
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
|
||||
xfs_daddr_t readPos =
|
||||
fInode->FileSystemBlockToAddr(map->br_startblock + howManyBlocksFurthur);
|
||||
|
||||
uint64 agNo =
|
||||
FSBLOCKS_TO_AGNO(map->br_startblock + howManyBlocksFurthur, volume);
|
||||
uint64 agBlockNo =
|
||||
FSBLOCKS_TO_AGBLOCKNO(map->br_startblock + howManyBlocksFurthur, volume);
|
||||
|
||||
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(volume->BlockLog(),
|
||||
(agNo * numberOfBlocksInAg + agBlockNo));
|
||||
|
||||
xfs_daddr_t readPos = blockToRead * BASICBLOCKSIZE;
|
||||
|
||||
TRACE("blockToRead: (%ld), readPos: (%ld)\n", blockToRead, readPos);
|
||||
if (read_pos(volume->Device(), readPos, blockBuffer, len) != len) {
|
||||
if (read_pos(fInode->GetVolume()->Device(), readPos, blockBuffer, len)
|
||||
!= len) {
|
||||
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
@@ -146,7 +136,8 @@ LeafDirectory::FillBuffer(int type, char* blockBuffer, int howManyBlocksFurthur)
|
||||
} else if (type == LEAF) {
|
||||
fLeafBuffer = blockBuffer;
|
||||
ExtentLeafHeader* header = (ExtentLeafHeader*) fLeafBuffer;
|
||||
TRACE("NumberOfEntries in leaf: (%d)\n", B_BENDIAN_TO_HOST_INT16(header->count));
|
||||
TRACE("NumberOfEntries in leaf: (%d)\n",
|
||||
B_BENDIAN_TO_HOST_INT16(header->count));
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -101,21 +101,11 @@ NodeDirectory::FillBuffer(int type, char* blockBuffer, int howManyBlocksFurthur)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
Volume* volume = fInode->GetVolume();
|
||||
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
|
||||
xfs_daddr_t readPos =
|
||||
fInode->FileSystemBlockToAddr(map->br_startblock + howManyBlocksFurthur);
|
||||
|
||||
uint64 agNo
|
||||
= FSBLOCKS_TO_AGNO(map->br_startblock + howManyBlocksFurthur, volume);
|
||||
uint64 agBlockNo
|
||||
= FSBLOCKS_TO_AGBLOCKNO(map->br_startblock + howManyBlocksFurthur, volume);
|
||||
|
||||
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(volume->BlockLog(),
|
||||
((uint64)(agNo * numberOfBlocksInAg) + agBlockNo));
|
||||
|
||||
xfs_daddr_t readPos = blockToRead * (BASICBLOCKSIZE);
|
||||
|
||||
TRACE("blockToRead: (%ld), readPos: (%ld)\n", blockToRead, readPos);
|
||||
if (read_pos(volume->Device(), readPos, blockBuffer, len) != len) {
|
||||
if (read_pos(fInode->GetVolume()->Device(), readPos, blockBuffer, len)
|
||||
!= len) {
|
||||
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user