From 13de3d07679ac012dcb2f247d615073dd8f56c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 2 Jul 2008 09:15:04 +0000 Subject: [PATCH] * 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 --- .../file_systems/ext2/DirectoryIterator.cpp | 14 ++++++++- .../kernel/file_systems/ext2/Inode.cpp | 11 ++++++- .../kernel/file_systems/ext2/Volume.cpp | 29 +++++++++++++++---- src/add-ons/kernel/file_systems/ext2/Volume.h | 1 + src/add-ons/kernel/file_systems/ext2/ext2.h | 6 ++-- .../file_systems/ext2/kernel_interface.cpp | 2 +- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp b/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp index 3d681e4a48..21ff6e727d 100644 --- a/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp +++ b/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp @@ -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(); diff --git a/src/add-ons/kernel/file_systems/ext2/Inode.cpp b/src/add-ons/kernel/file_systems/ext2/Inode.cpp index 7bc9a34ae4..3a2ffbdf21 100644 --- a/src/add-ons/kernel/file_systems/ext2/Inode.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Inode.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/ext2/Volume.cpp b/src/add-ons/kernel/file_systems/ext2/Volume.cpp index cdd9fd1267..61d15bdc9a 100644 --- a/src/add-ons/kernel/file_systems/ext2/Volume.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Volume.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/ext2/Volume.h b/src/add-ons/kernel/file_systems/ext2/Volume.h index 79a8e6e4d3..76a31c62a6 100644 --- a/src/add-ons/kernel/file_systems/ext2/Volume.h +++ b/src/add-ons/kernel/file_systems/ext2/Volume.h @@ -62,6 +62,7 @@ private: uint32 fFlags; uint32 fBlockSize; uint32 fBlockShift; + uint32 fFirstDataBlock; uint32 fNumGroups; uint32 fGroupsPerBlock; ext2_block_group** fGroupBlocks; diff --git a/src/add-ons/kernel/file_systems/ext2/ext2.h b/src/add-ons/kernel/file_systems/ext2/ext2.h index a0f240c859..25ba969574 100644 --- a/src/add-ons/kernel/file_systems/ext2/ext2.h +++ b/src/add-ons/kernel/file_systems/ext2/ext2.h @@ -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); } diff --git a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp index 298dd2ff30..2f0147f8bb 100644 --- a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp @@ -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) {