added 5 changesets to branch 'refs/remotes/ahenriksson-github/production' old head: 8b02d716f39e109e2b30a89357e6420be69fb03a new head: 59ba972f9d6dab2f6728df339b9f56acd3c10d22 ---------------------------------------------------------------------------- 2576c22: Printing a message when an attribute is not found makes checkfs very noisy 2c90bce: Logic error with resize stop condition 4193c71: Added "nodes processed" counter to resizefs f0daaeb: minimum must be a power of two in BlockAllocator::AllocateBlocks() 59ba972: Moving root and index directory was completely broken [ ahenriksson <sausageboy@xxxxxxxxx> ] ---------------------------------------------------------------------------- 6 files changed, 82 insertions(+), 22 deletions(-) src/add-ons/kernel/file_systems/bfs/Inode.cpp | 15 +++- src/add-ons/kernel/file_systems/bfs/Journal.cpp | 12 ++-- .../kernel/file_systems/bfs/ResizeVisitor.cpp | 60 +++++++++++++--- .../kernel/file_systems/bfs/ResizeVisitor.h | 5 +- .../kernel/file_systems/bfs/kernel_interface.cpp | 6 +- src/tools/bfs_shell/command_resizefs.cpp | 6 +- ############################################################################ Commit: 2576c2290571fa436d870558b8fd00014d4eee82 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Jul 18 14:49:02 2012 UTC Printing a message when an attribute is not found makes checkfs very noisy ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index e822593..bbb85b6 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -1223,7 +1223,7 @@ Inode::ReadAttribute(const char* name, int32 type, off_t pos, uint8* buffer, ReleaseAttribute(attribute); } - RETURN_ERROR(status); + return status; } ############################################################################ Commit: 2c90bcec496d585d6513e4486b8d2b36af7da7b0 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Jul 18 15:16:21 2012 UTC Logic error with resize stop condition ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 89a8301..e6aab3c 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -766,9 +766,9 @@ bfs_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, uint32 cmd, return B_NO_INIT; if (resizer->Next() == B_ENTRY_NOT_FOUND) { - // other return values will be saved away in the - // resize_control - return B_ENTRY_NOT_FOUND; + // are we really done, or is this an error? + if (resizer->Control().status == B_OK) + return B_ENTRY_NOT_FOUND; } return user_memcpy(buffer, &resizer->Control(), ############################################################################ Commit: 4193c7102f3e01a16bd863d38eb11ca36fd3db31 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Jul 18 15:16:47 2012 UTC Added "nodes processed" counter to resizefs ---------------------------------------------------------------------------- diff --git a/src/tools/bfs_shell/command_resizefs.cpp b/src/tools/bfs_shell/command_resizefs.cpp index 5127cb4..22e7906 100644 --- a/src/tools/bfs_shell/command_resizefs.cpp +++ b/src/tools/bfs_shell/command_resizefs.cpp @@ -91,6 +91,7 @@ command_resizefs(int argc, const char* const* argv) } bool resizeFailed = false; + uint64 counter = 0; // move all files out of the way while (true) { @@ -99,6 +100,9 @@ command_resizefs(int argc, const char* const* argv) if (status == B_ENTRY_NOT_FOUND) break; + if (++counter % 50 == 0) + fssh_dprintf("%9Ld nodes processed\x1b[1A\n", counter); + // we couldn't return the resizefs_control struct if (status != B_OK) { fssh_dprintf("Error: Couldn't perform 'next' ioctl\n"); @@ -181,7 +185,7 @@ PrintError(const resize_control& result) void PrintStats(const resize_control& result) { - fssh_dprintf("\tInodes moved: %" B_PRIu64 "\n", + fssh_dprintf(" Inodes moved: %" B_PRIu64 "\n", result.stats.inodes_moved); fssh_dprintf("\tData streams moved: %" B_PRIu64 "\n\n", result.stats.streams_moved); ############################################################################ Commit: f0daaeb55837e9b9841b7749490d4a894761ec1f Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Jul 19 16:58:23 2012 UTC minimum must be a power of two in BlockAllocator::AllocateBlocks() ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 06cecaf..00ec40a 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -1111,13 +1111,17 @@ Journal::MoveLog(block_run newLog) Transaction transaction(fVolume, 0); status = allocator.AllocateBlocks(transaction, 0, oldEnd, - allocationSize, allocationSize, allocatedRun, oldEnd, newEnd); + allocationSize, 1, allocatedRun, oldEnd, newEnd); if (status != B_OK) return status; - ASSERT(allocatedRun.AllocationGroup() == 0); - ASSERT(allocatedRun.Start() == oldEnd); - ASSERT(allocatedRun.Length() == allocationSize); + if (allocatedRun.AllocationGroup() != 0 + || allocatedRun.Start() != oldEnd + || allocatedRun.Length() != allocationSize) { + // we couldn't allocate what we wanted, this means that we + // failed to move all data from this area + return B_ERROR; + } status = transaction.Done(); if (status != B_OK) ############################################################################ Commit: 59ba972f9d6dab2f6728df339b9f56acd3c10d22 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Jul 19 17:01:59 2012 UTC Moving root and index directory was completely broken ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index bbb85b6..e21f207 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -602,6 +602,10 @@ Inode::InitCheck(bool checkNode) const void Inode::SetID(ino_t ID) { + // set parent ID if we are our own parent + if (Parent() == BlockRun()) + fNode.parent = fVolume->ToBlockRun(ID); + fID = ID; fNode.inode_num = fVolume->ToBlockRun(ID); } @@ -3363,8 +3367,15 @@ Inode::Copy(Transaction& transaction, off_t targetBlock) memcpy(targetData, sourceData, fVolume->BlockSize()); + block_run targetRun = fVolume->ToBlockRun(targetBlock); + // update inode ID in target block - target.WritableNode()->inode_num = fVolume->ToBlockRun(targetBlock); + target.WritableNode()->inode_num = targetRun; + + // also update parent reference in the rare case of us being our + // own parent + if (Parent() == BlockRun()) + target.WritableNode()->parent = targetRun; return B_OK; } diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index c541c77..60e7221 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -327,10 +327,6 @@ status_t ResizeVisitor::_UpdateParent(Transaction& transaction, Inode* inode, off_t newInodeID, const char* treeName) { - // are we the root node or index directory? - if (inode->BlockRun() == inode->Parent()) - return B_OK; - // get Inode of parent Vnode parentVnode(GetVolume(), inode->Parent()); Inode* parent; @@ -382,7 +378,7 @@ ResizeVisitor::_UpdateAttributeDirectory(Transaction& transaction, Inode* inode, status_t ResizeVisitor::_UpdateIndexReferences(Transaction& transaction, Inode* inode, - off_t newInodeID) + off_t newInodeID, bool rootOrIndexDir) { // update user file attributes AttributeIterator iterator(inode); @@ -417,7 +413,9 @@ ResizeVisitor::_UpdateIndexReferences(Transaction& transaction, Inode* inode, } // update built-in attributes - if (inode->InNameIndex()) { + + // the root node is not in the name index even though InNameIndex() is true + if (inode->InNameIndex() && !rootOrIndexDir) { status = index.SetTo("name"); if (status != B_OK) return status; @@ -535,10 +533,34 @@ ResizeVisitor::_UpdateChildren(Transaction& transaction, Inode* inode, status_t +ResizeVisitor::_UpdateSuperBlock(Inode* inode, off_t newInodeID) +{ + MutexLocker(GetVolume()->Lock()); + disk_super_block& superBlock = GetVolume()->SuperBlock(); + + if (inode->BlockRun() == superBlock.root_dir) { + INFORM(("New root directory: block %" B_PRIdOFF "\n", newInodeID)); + superBlock.root_dir = GetVolume()->ToBlockRun(newInodeID); + } else if (inode->BlockRun() == superBlock.indices) { + INFORM(("New index directory: block %" B_PRIdOFF "\n", newInodeID)); + superBlock.indices = GetVolume()->ToBlockRun(newInodeID); + } else { + FATAL(("_UpdateSuperBlock: Expected inode %" B_PRIdINO + " to be root or index directory!\n", inode->ID())); + return B_BAD_VALUE; + } + + return GetVolume()->WriteSuperBlock(); +} + + +status_t ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) { Transaction transaction(GetVolume(), 0); + bool rootOrIndexDir = inode->BlockRun() == inode->Parent(); + block_run run; status_t status = GetVolume()->Allocator().AllocateBlocks(transaction, 0, 0, 1, 1, run, fBeginBlock, fEndBlock); @@ -554,9 +576,11 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) if (status != B_OK) return status; - status = _UpdateParent(transaction, inode, newInodeID, treeName); - if (status != B_OK) - return status; + if (!rootOrIndexDir) { + status = _UpdateParent(transaction, inode, newInodeID, treeName); + if (status != B_OK) + return status; + } // update parent reference in attribute directory if we have one if (!inode->Attributes().IsZero()) { @@ -565,7 +589,8 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) return status; } - status = _UpdateIndexReferences(transaction, inode, newInodeID); + status = _UpdateIndexReferences(transaction, inode, newInodeID, + rootOrIndexDir); if (status != B_OK) return status; @@ -586,7 +611,20 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) if (status != B_OK) return status; - return transaction.Done(); + status = transaction.Done(); + if (status != B_OK) + return status; + + if (rootOrIndexDir) { + status = _UpdateSuperBlock(inode, newInodeID); + if (status != B_OK) { + // we've already completed the transaction, this is very bad + FATAL(("_MoveInode: Could not write super block!\n")); + return status; + } + } + + return B_OK; } diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.h b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.h index 91ecb29..7a0ea7b 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.h +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.h @@ -45,11 +45,14 @@ private: Transaction& transaction, Inode* inode, block_run newInodeRun); status_t _UpdateIndexReferences(Transaction& transaction, - Inode* inode, off_t newInodeID); + Inode* inode, off_t newInodeID, + bool rootOrIndexDir); status_t _UpdateTree(Transaction& transaction, Inode* inode, off_t newInodeID); status_t _UpdateChildren(Transaction& transaction, Inode* inode, off_t newInodeID); + status_t _UpdateSuperBlock(Inode* inode, + off_t newInodeID); status_t _MoveInode(Inode* inode, off_t& newInodeID, const char* treeName);