* Fixed wrong group block offset computation: the
ext2_super_block::first_data_block must be used; the superblock offset doesn't matter if the block size is greater than 2KB. * Fixed block access beyond the 4GB limit - we need to cast the block to a 64 bit type in ext2_get_file_map() before shifting it. * Tested with various larger ext3 disks, and everything seems to work fine. * Added some optional debug output. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26213 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -11,6 +11,14 @@
|
||||
#include "Inode.h"
|
||||
|
||||
|
||||
//#define TRACE_EXT2
|
||||
#ifdef TRACE_EXT2
|
||||
# define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
|
||||
#else
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(Inode* inode)
|
||||
:
|
||||
fInode(inode),
|
||||
@@ -24,7 +32,7 @@ DirectoryIterator::~DirectoryIterator()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
status_t
|
||||
DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
||||
{
|
||||
if (fOffset + sizeof(ext2_dir_entry) >= fInode->Size())
|
||||
@@ -48,6 +56,10 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
||||
fOffset += entry.Length();
|
||||
}
|
||||
|
||||
TRACE("offset %Ld: entry ino %lu, length %u, name length %u, type %u\n",
|
||||
fOffset, entry.InodeID(), entry.Length(), entry.NameLength(),
|
||||
entry.FileType());
|
||||
|
||||
// read name
|
||||
|
||||
size_t length = entry.NameLength();
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
#include "CachedBlock.h"
|
||||
|
||||
|
||||
//#define TRACE_EXT2
|
||||
#ifdef TRACE_EXT2
|
||||
# define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
|
||||
#else
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
Inode::Inode(Volume* volume, ino_t id)
|
||||
:
|
||||
fVolume(volume),
|
||||
@@ -23,6 +31,7 @@ Inode::Inode(Volume* volume, ino_t id)
|
||||
|
||||
uint32 block;
|
||||
if (volume->GetInodeBlock(id, block) == B_OK) {
|
||||
TRACE("inode %Ld at block %lu\n", ID(), block);
|
||||
ext2_inode* inodes = (ext2_inode*)block_cache_get(volume->BlockCache(),
|
||||
block);
|
||||
if (inodes != NULL)
|
||||
@@ -150,7 +159,7 @@ Inode::FindBlock(off_t offset, uint32& block)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
//dprintf("FindBlock(offset %Ld): %lu\n", offset, block);
|
||||
TRACE("inode %Ld: FindBlock(offset %Ld): %lu\n", ID(), offset, block);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
#include "Inode.h"
|
||||
|
||||
|
||||
//#define TRACE_EXT2
|
||||
#ifdef TRACE_EXT2
|
||||
# define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
|
||||
#else
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
class DeviceOpener {
|
||||
public:
|
||||
DeviceOpener(int fd, int mode);
|
||||
@@ -268,13 +276,20 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
||||
// initialize short hands to the super block (to save byte swapping)
|
||||
fBlockShift = fSuperBlock.BlockShift();
|
||||
fBlockSize = 1UL << fSuperBlock.BlockShift();
|
||||
fFirstDataBlock = fSuperBlock.FirstDataBlock();
|
||||
|
||||
fNumGroups = (fSuperBlock.NumBlocks() - fSuperBlock.FirstDataBlock() - 1)
|
||||
fNumGroups = (fSuperBlock.NumBlocks() - fFirstDataBlock - 1)
|
||||
/ fSuperBlock.BlocksPerGroup() + 1;
|
||||
fGroupsPerBlock = fBlockSize / sizeof(ext2_block_group);
|
||||
|
||||
TRACE("block size %ld, num groups %ld, groups per block %ld, first %lu\n",
|
||||
fBlockSize, fNumGroups, fGroupsPerBlock, fFirstDataBlock);
|
||||
TRACE("features %lx, incompatible features %lx, read-only features %lx\n",
|
||||
fSuperBlock.CompatibleFeatures(), fSuperBlock.IncompatibleFeatures(),
|
||||
fSuperBlock.ReadOnlyFeatures());
|
||||
|
||||
uint32 blockCount = (fNumGroups + fGroupsPerBlock - 1) / fGroupsPerBlock;
|
||||
|
||||
|
||||
fGroupBlocks = (ext2_block_group**)malloc(blockCount * sizeof(void*));
|
||||
if (fGroupBlocks == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@@ -298,8 +313,9 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
||||
// all went fine
|
||||
opener.Keep();
|
||||
return B_OK;
|
||||
} else
|
||||
dprintf("ext2: could not create root node: get_vnode() failed!\n");
|
||||
} else {
|
||||
TRACE("could not create root node: get_vnode() failed!\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -344,7 +360,7 @@ Volume::_GroupBlockOffset(uint32 blockIndex)
|
||||
if ((fSuperBlock.IncompatibleFeatures()
|
||||
& EXT2_INCOMPATIBLE_FEATURE_META_GROUP) == 0
|
||||
|| blockIndex < fSuperBlock.FirstMetaBlockGroup())
|
||||
return EXT2_SUPER_BLOCK_OFFSET + fBlockSize * (1 + blockIndex);
|
||||
return (fFirstDataBlock + blockIndex + 1) << fBlockShift;
|
||||
|
||||
panic("meta block");
|
||||
return 0;
|
||||
@@ -380,6 +396,9 @@ Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
|
||||
}
|
||||
|
||||
fGroupBlocks[blockIndex] = groupBlock;
|
||||
|
||||
TRACE("group [%ld]: inode table %ld\n", index,
|
||||
(fGroupBlocks[blockIndex] + index % fGroupsPerBlock)->InodeTable());
|
||||
}
|
||||
|
||||
*_group = fGroupBlocks[blockIndex] + index % fGroupsPerBlock;
|
||||
|
||||
@@ -62,6 +62,7 @@ private:
|
||||
uint32 fFlags;
|
||||
uint32 fBlockSize;
|
||||
uint32 fBlockShift;
|
||||
uint32 fFirstDataBlock;
|
||||
uint32 fNumGroups;
|
||||
uint32 fGroupsPerBlock;
|
||||
ext2_block_group** fGroupBlocks;
|
||||
|
||||
@@ -45,7 +45,7 @@ struct ext2_super_block {
|
||||
uint16 block_group;
|
||||
uint32 compatible_features;
|
||||
uint32 incompatible_features;
|
||||
uint32 readonly_features;
|
||||
uint32 read_only_features;
|
||||
uint8 uuid[16];
|
||||
char name[16];
|
||||
char last_mount_point[64];
|
||||
@@ -53,7 +53,7 @@ struct ext2_super_block {
|
||||
uint8 preallocated_blocks;
|
||||
uint8 preallocated_directory_blocks;
|
||||
uint16 _padding;
|
||||
|
||||
|
||||
// journaling ext3 support
|
||||
uint8 journal_uuid[16];
|
||||
uint32 journal_inode;
|
||||
@@ -85,7 +85,7 @@ struct ext2_super_block {
|
||||
uint32 CompatibleFeatures() const
|
||||
{ return B_LENDIAN_TO_HOST_INT32(compatible_features); }
|
||||
uint32 ReadOnlyFeatures() const
|
||||
{ return B_LENDIAN_TO_HOST_INT32(readonly_features); }
|
||||
{ return B_LENDIAN_TO_HOST_INT32(read_only_features); }
|
||||
uint32 IncompatibleFeatures() const
|
||||
{ return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ ext2_get_file_map(fs_volume* _volume, fs_vnode* _node, off_t offset,
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
off_t blockOffset = block << volume->BlockShift();
|
||||
off_t blockOffset = (off_t)block << volume->BlockShift();
|
||||
uint32 blockLength = volume->BlockSize();
|
||||
|
||||
if (index > 0 && vecs[index - 1].offset == blockOffset - blockLength) {
|
||||
|
||||
Reference in New Issue
Block a user