diff --git a/zircon/system/ulib/minfs/allocator/inode-manager.cpp b/zircon/system/ulib/minfs/allocator/inode-manager.cpp index 9d4fa2cfbf3cac075f85798f42dd38724fae39f3..2bcdb03e9636a069b0558d8353b9e182d83d1394 100644 --- a/zircon/system/ulib/minfs/allocator/inode-manager.cpp +++ b/zircon/system/ulib/minfs/allocator/inode-manager.cpp @@ -12,7 +12,12 @@ namespace minfs { InodeManager::InodeManager(Bcache* bc, blk_t start_block) : - bc_(bc), start_block_(start_block) {} + start_block_(start_block) { +#ifndef __Fuchsia__ + bc_ = bc; +#endif +} + InodeManager::~InodeManager() = default; zx_status_t InodeManager::Create(Bcache* bc, SuperblockManager* sb, fs::ReadTxn* txn, @@ -74,6 +79,10 @@ void InodeManager::Update(WriteTxn* txn, ino_t ino, const Inode* inode) { #endif } +const Allocator* InodeManager::GetInodeAllocator() const { + return inode_allocator_.get(); +} + void InodeManager::Load(ino_t ino, Inode* out) const { // obtain the block of the inode table we need uint32_t off_of_ino = (ino % kMinfsInodesPerBlock) * kMinfsInodeSize; diff --git a/zircon/system/ulib/minfs/allocator/inode-manager.h b/zircon/system/ulib/minfs/allocator/inode-manager.h index 3b9f87ef93f2e0041abb53895bbc76da8110ab33..9dfbcb7d9058c35f2a880120dca77d433e8dd7f6 100644 --- a/zircon/system/ulib/minfs/allocator/inode-manager.h +++ b/zircon/system/ulib/minfs/allocator/inode-manager.h @@ -26,6 +26,9 @@ class InspectableInodeManager { public: virtual ~InspectableInodeManager() {} + // Gets immutable reference to the inode allocator. + virtual const Allocator* GetInodeAllocator() const = 0; + // Loads the inode from storage. virtual void Load(ino_t inode_num, Inode* out) const = 0; }; @@ -59,6 +62,8 @@ public: void Update(WriteTxn* txn, ino_t ino, const Inode* inode); // InspectableInodeManager interface: + const Allocator* GetInodeAllocator() const final; + void Load(ino_t ino, Inode* out) const final; // Extend the number of inodes managed. @@ -68,11 +73,10 @@ public: zx_status_t Grow(size_t inodes); private: - friend class MinfsChecker; - InodeManager(Bcache* bc, blk_t start_block); - +#ifndef __Fuchsia__ Bcache* bc_; +#endif blk_t start_block_; fbl::unique_ptr<Allocator> inode_allocator_; #ifdef __Fuchsia__ diff --git a/zircon/system/ulib/minfs/fsck.cpp b/zircon/system/ulib/minfs/fsck.cpp index 01168db8c4fd4a5253163967f4f6800350be70f7..b88377f5d77fd2dfbf527eeb67688b07dbc6b537 100644 --- a/zircon/system/ulib/minfs/fsck.cpp +++ b/zircon/system/ulib/minfs/fsck.cpp @@ -70,7 +70,7 @@ zx_status_t MinfsChecker::GetInode(Inode* inode, ino_t ino) { return ZX_ERR_OUT_OF_RANGE; } - fs_->inodes_->Load(ino, inode); + fs_->GetInodeManager()->Load(ino, inode); if ((inode->magic != kMinfsMagicFile) && (inode->magic != kMinfsMagicDir)) { FS_TRACE_ERROR("check: ino %u has bad magic %#x\n", ino, inode->magic); return ZX_ERR_IO_DATA_INTEGRITY; @@ -217,7 +217,8 @@ zx_status_t MinfsChecker::CheckDirectory(Inode* inode, ino_t ino, bool dot_or_dotdot = false; if ((de->namelen == 0) || (de->namelen > (rlen - MINFS_DIRENT_SIZE))) { - FS_TRACE_ERROR("check: ino#%u: de[%u]: invalid namelen %u\n", ino, eno, de->namelen); + FS_TRACE_ERROR("check: ino#%u: de[%u]: invalid namelen %u\n", ino, eno, + de->namelen); return ZX_ERR_IO_DATA_INTEGRITY; } if ((de->namelen == 1) && (de->name[0] == '.')) { @@ -227,7 +228,8 @@ zx_status_t MinfsChecker::CheckDirectory(Inode* inode, ino_t ino, dot_or_dotdot = true; dot = true; if (de->ino != ino) { - FS_TRACE_ERROR("check: ino#%u: de[%u]: '.' ino=%u (not self!)\n", ino, eno, de->ino); + FS_TRACE_ERROR("check: ino#%u: de[%u]: '.' ino=%u (not self!)\n", ino, eno, + de->ino); } } if ((de->namelen == 2) && (de->name[0] == '.') && (de->name[1] == '.')) { @@ -237,13 +239,14 @@ zx_status_t MinfsChecker::CheckDirectory(Inode* inode, ino_t ino, dot_or_dotdot = true; dotdot = true; if (de->ino != parent) { - FS_TRACE_ERROR("check: ino#%u: de[%u]: '..' ino=%u (not parent!)\n", ino, eno, de->ino); + FS_TRACE_ERROR("check: ino#%u: de[%u]: '..' ino=%u (not parent!)\n", ino, eno, + de->ino); } } //TODO: check for cycles (non-dot/dotdot dir ref already in checked bitmap) if (flags & CD_DUMP) { - FS_TRACE_DEBUG("ino#%u: de[%u]: ino=%u type=%u '%.*s' %s\n", ino, eno, de->ino, de->type, - de->namelen, de->name, is_last ? "[last]" : ""); + FS_TRACE_DEBUG("ino#%u: de[%u]: ino=%u type=%u '%.*s' %s\n", ino, eno, de->ino, + de->type, de->namelen, de->name, is_last ? "[last]" : ""); } if (flags & CD_RECURSE) { @@ -280,7 +283,7 @@ const char* MinfsChecker::CheckDataBlock(blk_t bno) { if (bno >= fs_->Info().block_count) { return "out of range"; } - if (!fs_->block_allocator_->CheckAllocated(bno)) { + if (!fs_->GetBlockAllocator()->CheckAllocated(bno)) { return "not allocated"; } if (checked_blocks_.Get(bno, bno + 1)) { @@ -393,7 +396,7 @@ zx_status_t MinfsChecker::CheckFile(Inode* inode, ino_t ino) { void MinfsChecker::CheckReserved() { // Check reserved inode '0'. - if (fs_->inodes_->inode_allocator_->CheckAllocated(0)) { + if (fs_->GetInodeManager()->GetInodeAllocator()->CheckAllocated(0)) { checked_inodes_.Set(0, 1); alloc_inodes_++; } else { @@ -402,7 +405,7 @@ void MinfsChecker::CheckReserved() { } // Check reserved data block '0'. - if (fs_->block_allocator_->CheckAllocated(0)) { + if (fs_->GetBlockAllocator()->CheckAllocated(0)) { checked_blocks_.Set(0, 1); alloc_blocks_++; } else { @@ -438,7 +441,7 @@ zx_status_t MinfsChecker::CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot checked_inodes_.Set(ino, ino + 1); alloc_inodes_++; - if (!fs_->inodes_->inode_allocator_->CheckAllocated(ino)) { + if (!fs_->GetInodeManager()->GetInodeAllocator()->CheckAllocated(ino)) { FS_TRACE_WARN("check: ino#%u: not marked in-use\n", ino); conforming_ = false; } @@ -455,8 +458,8 @@ zx_status_t MinfsChecker::CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot return status; } } else { - FS_TRACE_DEBUG("ino#%u: FILE blks=%u links=%u size=%u\n", ino, inode.block_count, inode.link_count, - inode.size); + FS_TRACE_DEBUG("ino#%u: FILE blks=%u links=%u size=%u\n", ino, inode.block_count, + inode.link_count, inode.size); if ((status = CheckFile(&inode, ino)) < 0) { return status; } @@ -516,7 +519,7 @@ zx_status_t MinfsChecker::CheckForUnusedBlocks() const { unsigned missing = 0; for (unsigned n = 0; n < fs_->Info().block_count; n++) { - if (fs_->block_allocator_->CheckAllocated(n)) { + if (fs_->GetBlockAllocator()->CheckAllocated(n)) { if (!checked_blocks_.Get(n, n + 1)) { missing++; } @@ -533,7 +536,7 @@ zx_status_t MinfsChecker::CheckForUnusedBlocks() const { zx_status_t MinfsChecker::CheckForUnusedInodes() const { unsigned missing = 0; for (unsigned n = 0; n < fs_->Info().inode_count; n++) { - if (fs_->inodes_->inode_allocator_->CheckAllocated(n)) { + if (fs_->GetInodeManager()->GetInodeAllocator()->CheckAllocated(n)) { if (!checked_inodes_.Get(n, n + 1)) { missing++; } @@ -587,7 +590,7 @@ zx_status_t MinfsChecker::CheckJournal() const { #ifdef __Fuchsia__ journal_block = fs_->Info().journal_start_block; #else - journal_block = fs_->offsets_.JournalStartBlock(); + journal_block = fs_->GetBlockOffsets().JournalStartBlock(); #endif if (fs_->bc_->Readblk(journal_block, data) < 0) { diff --git a/zircon/system/ulib/minfs/minfs-private.h b/zircon/system/ulib/minfs/minfs-private.h index 49c0d4d116cc7702f31b32f9ba8839eba7018a2b..f3572d1ed7c4dc1896058da1eefab562231ee2b2 100644 --- a/zircon/system/ulib/minfs/minfs-private.h +++ b/zircon/system/ulib/minfs/minfs-private.h @@ -166,8 +166,16 @@ public: // Gets an immutable reference to the InodeManager. virtual const InspectableInodeManager* GetInodeManager() const = 0; + // Gets an immutable reference to the block_allocator. + virtual const Allocator* GetBlockAllocator() const = 0; + // Reads a block at the |start_block_num| location. virtual zx_status_t ReadBlock(blk_t start_block_num, void* out_data) const = 0; + +#ifndef __Fuchsia__ + // Gets an immutable copy of offsets_. + virtual const BlockOffsets GetBlockOffsets() const = 0; +#endif }; class Minfs : @@ -347,6 +355,16 @@ public: return inodes_.get(); } + const Allocator* GetBlockAllocator() const final { + return block_allocator_.get(); + } + +#ifndef __Fuchsia__ + const BlockOffsets GetBlockOffsets() const final { + return offsets_; + } +#endif + zx_status_t ReadBlock(blk_t start_block_num, void* data) const final; const TransactionLimits& Limits() const { @@ -363,8 +381,6 @@ public: fbl::unique_ptr<Bcache> bc_; private: - // Fsck can introspect Minfs - friend class MinfsChecker; using HashTable = fbl::HashTable<ino_t, VnodeMinfs*>; #ifdef __Fuchsia__ diff --git a/zircon/system/ulib/minfs/test/inspector-test.cpp b/zircon/system/ulib/minfs/test/inspector-test.cpp index 6d818eee6670a2519ac31d962e8d7cd0fbca2546..660dc0df0919dddf370cec6787a9a94814df75f3 100644 --- a/zircon/system/ulib/minfs/test/inspector-test.cpp +++ b/zircon/system/ulib/minfs/test/inspector-test.cpp @@ -23,12 +23,17 @@ public: MockInodeManager& operator=(MockInodeManager&&) = delete; void Load(ino_t inode_num, Inode* out) const final; + const Allocator* GetInodeAllocator() const final; }; MockInodeManager::MockInodeManager() {} void MockInodeManager::Load(ino_t inode_num, Inode* out) const {} +const Allocator* MockInodeManager::GetInodeAllocator() const { + return nullptr; +} + constexpr Superblock superblock = {}; // Mock Minfs class to be used in inspector tests. @@ -48,6 +53,10 @@ public: return nullptr; } + const Allocator* GetBlockAllocator() const final { + return nullptr; + } + zx_status_t ReadBlock(blk_t start_block_num, void* out_data) const final { return ZX_OK; } diff --git a/zircon/system/ulib/minfs/vnode.h b/zircon/system/ulib/minfs/vnode.h index 79044a05ea928af822ba15d594c5cfe42e8ff69f..72b0de9c24a329cbd2f0ecfd793af7da3d1dfcd7 100644 --- a/zircon/system/ulib/minfs/vnode.h +++ b/zircon/system/ulib/minfs/vnode.h @@ -199,9 +199,6 @@ public: // of "File + Directory + Vnode" being a single class. They should be transitioned to // private. protected: - // Fsck can introspect Minfs - friend class MinfsChecker; - VnodeMinfs(Minfs* fs); // fs::Vnode interface.