* 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:
Axel Dörfler
2008-07-02 09:15:04 +00:00
parent 0aad734230
commit 13de3d0767
6 changed files with 52 additions and 11 deletions
@@ -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();
+10 -1
View File
@@ -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;
+3 -3
View File
@@ -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) {