added 6 changesets to branch 'refs/remotes/ahenriksson-github/production' old head: a937ebae6f9123dddbdbd2a7e9505ef740f46d89 new head: f29dd67d01bb591bee996cd5914e0546f559882c ---------------------------------------------------------------------------- 7e2431c: Add allocation hint when moving inodes ad39e09: Do the special-caseing of the index directory in get/put_vnode 14df872: Revert "The index root requires some special handling" Conflicts: src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp c90d642: Revert "Switch to util/OpenHashTable.h for the moved inodes table" a0ddc60: Revert "Add mapping from vnode ID to block number for moved inodes" Conflicts: src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp f29dd67: Start preparing for vnode remapping An Inode object stores its block number, and converts it to a vnode ID when needed. Requests for the inode ID are changed depending on what they actually want: Internal operations (BPlusTree updating for instance) use the block numbers, and interactions with the outside world use the vnode ID. For now, vnode IDs and block numbers are differentiated by a simple xor operation in the translation functions. It's unlikely that all places that need to be changed have been changed, but things seem to work fine in when testing casually. [ ahenriksson <sausageboy@xxxxxxxxx> ] ---------------------------------------------------------------------------- 14 files changed, 136 insertions(+), 347 deletions(-) src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp | 4 +- .../kernel/file_systems/bfs/BlockAllocator.cpp | 36 +--- .../kernel/file_systems/bfs/BlockAllocator.h | 3 +- .../kernel/file_systems/bfs/CheckVisitor.cpp | 19 +- .../kernel/file_systems/bfs/FileSystemVisitor.cpp | 30 +--- src/add-ons/kernel/file_systems/bfs/Index.cpp | 4 +- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 40 +++-- src/add-ons/kernel/file_systems/bfs/Inode.h | 35 ++-- .../kernel/file_systems/bfs/ResizeVisitor.cpp | 40 +---- src/add-ons/kernel/file_systems/bfs/Utility.h | 7 - src/add-ons/kernel/file_systems/bfs/Volume.cpp | 146 +--------------- src/add-ons/kernel/file_systems/bfs/Volume.h | 25 +-- .../kernel/file_systems/bfs/kernel_interface.cpp | 93 ++++++---- .../kernel/file_systems/bfs/system_dependencies.h | 1 - ############################################################################ Commit: 7e2431c965185a4c4418f6c80b1417a7d883c53c Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Fri Aug 10 15:44:14 2012 UTC Add allocation hint when moving inodes ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index b49abbd..801c9b7 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -625,12 +625,12 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) bool rootOrIndexDir = inode->BlockRun() == inode->Parent(); + block_run hintRun = GetVolume()->ToBlockRun(inode->ID() % fNumBlocks); + // TODO: this allocation hint could certainly be improved + block_run run; - status_t status = GetVolume()->Allocator().AllocateBlocks(transaction, 0, 0, - 1, 1, run, true); - // TODO: use a hint, maybe old position % new volume size? - // stuff that originally was in the beginning should probably - // stay close to it + status_t status = GetVolume()->Allocator().AllocateBlocks(transaction, + hintRun.AllocationGroup(), hintRun.Start(), 1, 1, run, true); if (status != B_OK) RETURN_ERROR(status); ############################################################################ Commit: ad39e0957126847ba42e4c7506a7e88c22ca2101 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Mon Aug 13 12:29:36 2012 UTC Do the special-caseing of the index directory in get/put_vnode ---------------------------------------------------------------------------- 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 8ba0b18..06efc12 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -283,6 +283,17 @@ bfs_get_vnode(fs_volume* _volume, ino_t _id, fs_vnode* _node, int* _type, return B_ERROR; } + // the index root node is not managed through the VFS layer, so we need + // to return the correct object here to avoid having two out of sync + // objects for the same inode + if (volume->IndicesNode() != NULL && id == volume->IndicesNode()->ID()) { + _node->private_node = volume->IndicesNode(); + _node->ops = &gBFSVnodeOps; + *_type = volume->IndicesNode()->Mode(); + *_flags = 0; + return B_OK; + } + // first inode may be after the log area, we don't go through // the hassle and try to load an earlier block from disk if (id < volume->ToBlock(volume->Log()) + volume->Log().Length() @@ -348,6 +359,11 @@ bfs_put_vnode(fs_volume* _volume, fs_vnode* _node, bool reenter) } } + // the index root node Inode object is allocated when the volume is + // mounted and should not be deleted here + if (volume->IndicesNode() != NULL && inode == volume->IndicesNode()) + return B_OK; + delete inode; return B_OK; } ############################################################################ Commit: 14df87245b0cc566f828302b9291df5d835aab5e Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Mon Aug 13 12:33:07 2012 UTC Revert "The index root requires some special handling" Conflicts: src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp index dbf5acf..a2a759d 100644 --- a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp @@ -165,34 +165,6 @@ FileSystemVisitor::Next() fStack.Push(inode->Attributes()); } - // the index root is not managed by the vnode layer, so we set - // 'inode' to point to the correct object - if (inode->IsIndexRoot()) { - bool error = false; - - if (fVolume->IndicesNode() == NULL) { - FATAL(("Inode claimed to be index root, but the volume does " - "not have indices!\n")); - kernel_debugger("no indices"); - error = true; - } else if (inode->ID() != fVolume->IndicesNode()->ID()) { - FATAL(("Index root inode did not match volume index root!\n")); - kernel_debugger("no match"); - error = true; - } - - if (error) { - status = OpenInodeFailed(B_ERROR, inode->ID(), NULL, NULL, - NULL); - if (status == B_OK) - continue; - - return status; - } - - inode = fVolume->IndicesNode(); - } - bool visitingCurrentDirectory = inode->BlockRun() == fCurrent; status = VisitInode(inode, name); diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index abb4ac0..fa02dde 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -57,8 +57,6 @@ public: { return is_directory(Mode()); } bool IsIndex() const { return is_index(Mode()); } - bool IsIndexRoot() const - { return is_index_root(Mode()); } bool IsAttributeDirectory() const { return (Mode() & S_EXTENDED_TYPES) diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index 801c9b7..ed47c16 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -359,28 +359,11 @@ ResizeVisitor::_UpdateParent(Transaction& transaction, Inode* inode, off_t newInodeID, const char* treeName) { // get Inode of parent - Vnode parentVnode; + Vnode parentVnode(GetVolume(), inode->Parent()); Inode* parent; - status_t status; - - if (inode->IsIndex()) { - parent = GetVolume()->IndicesNode(); - if (parent == NULL) { - FATAL(("Tried to update parent of index, but there was no index " - "root!\n")); - return B_ERROR; - } - - if (parent->BlockRun() != inode->Parent()) { - FATAL(("Inode parent and index directory did not match!\n")); - return B_ERROR; - } - } else { - parentVnode.SetTo(GetVolume(), inode->Parent()); - status = parentVnode.Get(&parent); - if (status != B_OK) - return status; - } + status_t status = parentVnode.Get(&parent); + if (status != B_OK) + return status; parent->WriteLockInTransaction(transaction); diff --git a/src/add-ons/kernel/file_systems/bfs/Utility.h b/src/add-ons/kernel/file_systems/bfs/Utility.h index 1198457..9a06eed 100644 --- a/src/add-ons/kernel/file_systems/bfs/Utility.h +++ b/src/add-ons/kernel/file_systems/bfs/Utility.h @@ -125,13 +125,6 @@ is_index(int mode) inline bool -is_index_root(int mode) -{ - return (mode & (S_EXTENDED_TYPES)) == S_INDEX_DIR && !is_index(mode); -} - - -inline bool is_directory(int mode) { return (mode & (S_EXTENDED_TYPES | S_IFDIR)) == S_IFDIR; ############################################################################ Commit: c90d642fd91cb06461c9f1e9af45b08bcaeb6cdf Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 16 19:33:21 2012 UTC Revert "Switch to util/OpenHashTable.h for the moved inodes table" ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 2f3c1b0..42e27c7 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -60,27 +60,6 @@ private: }; -struct InodeMapValue { - InodeMapValue(ino_t oldID, ino_t newID); - - ino_t fOldID; - ino_t fNewID; - - InodeMapValue* fNext; -}; - - -struct InodeMapDefinitions { - typedef ino_t KeyType; - typedef InodeMapValue ValueType; - - size_t HashKey(ino_t key) const; - size_t Hash(InodeMapValue* value) const; - bool Compare(ino_t key, InodeMapValue* value) const; - InodeMapValue*& GetLink(InodeMapValue* value) const; -}; - - DeviceOpener::DeviceOpener(const char* device, int mode) : fBlockCache(NULL) @@ -212,45 +191,6 @@ DeviceOpener::GetSize(off_t* _size, uint32* _blockSize) // #pragma mark - -InodeMapValue::InodeMapValue(ino_t oldID, ino_t newID) - : - fOldID(oldID), - fNewID(newID) -{ -} - - -size_t -InodeMapDefinitions::HashKey(ino_t key) const -{ - return (size_t)(key >> 32) ^ (size_t)key; -} - - -size_t -InodeMapDefinitions::Hash(InodeMapValue* value) const -{ - return HashKey(value->fOldID); -} - - -bool -InodeMapDefinitions::Compare(ino_t key, InodeMapValue* value) const -{ - return value->fOldID == key; -} - - -InodeMapValue*& -InodeMapDefinitions::GetLink(InodeMapValue* value) const -{ - return value->fNext; -} - - -// #pragma mark - - - bool disk_super_block::IsValid() const { @@ -356,7 +296,6 @@ Volume::Volume(fs_volume* volume) Volume::~Volume() { - FreeMovedInodes(); delete fMovedInodes; rw_lock_destroy(&fMovedInodesLock); @@ -620,11 +559,7 @@ Volume::AddMovedInode(ino_t oldID, ino_t newID) if (fMovedInodes == NULL) return B_NO_MEMORY; - InodeMapValue* newMapping = new(std::nothrow) InodeMapValue(oldID, newID); - if (newMapping == NULL) - return B_NO_MEMORY; - - return fMovedInodes->Insert(newMapping); + return fMovedInodes->Put(oldID, newID); } @@ -635,17 +570,11 @@ Volume::HasMovedInodes() const } -void -Volume::FreeMovedInodes() +InodeMap::Iterator +Volume::MovedInodesIterator() const { - WriteLocker locker(fMovedInodesLock); - - if (fMovedInodes != NULL) { - InodeMap::Iterator iterator = fMovedInodes->GetIterator(); - - while (iterator.HasNext()) - delete iterator.Next(); - } + ASSERT(fMovedInodes != NULL); + return fMovedInodes->GetIterator(); } @@ -658,10 +587,11 @@ Volume::ResolveVnodeID(ino_t vnodeID) if (fMovedInodes == NULL) return vnodeID; + ino_t* inodeID; + // has this inode been moved? - InodeMapValue* entry = fMovedInodes->Lookup(vnodeID); - if (entry != NULL) - return entry->fNewID; + if (fMovedInodes->Get(vnodeID, inodeID)) + return *inodeID; return vnodeID; } @@ -673,7 +603,7 @@ Volume::WasMovedInode(ino_t blockNumber) ASSERT(fMovedInodes != NULL); ReadLocker locker(fMovedInodesLock); - return fMovedInodes->Lookup(blockNumber) != NULL; + return fMovedInodes->ContainsKey(blockNumber); } diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index 0d07b57..faec36a 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -18,8 +18,6 @@ class Inode; class Query; class ResizeVisitor; -struct InodeMapDefinitions; - enum volume_flags { VOLUME_READ_ONLY = 0x0001 @@ -31,7 +29,7 @@ enum volume_initialize_flags { typedef DoublyLinkedList<Inode> InodeList; -typedef BOpenHashTable<InodeMapDefinitions> InodeMap; +typedef HashMap<HashKey64<ino_t>, ino_t> InodeMap; class Volume { @@ -111,7 +109,7 @@ public: rw_lock& MovedInodesLock() { return fMovedInodesLock; } status_t AddMovedInode(ino_t oldID, ino_t newID); bool HasMovedInodes() const; - void FreeMovedInodes(); + InodeMap::Iterator MovedInodesIterator() const; ino_t ResolveVnodeID(ino_t vnodeID); bool WasMovedInode(ino_t blockNumber); diff --git a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h index 68c415d..1b27fea 100644 --- a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h +++ b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h @@ -16,10 +16,10 @@ #else // !BFS_SHELL #include <AutoDeleter.h> +#include <shared/HashMap.h> #include <util/AutoLock.h> #include <util/DoublyLinkedList.h> #include <util/kernel_cpp.h> -#include <util/OpenHashTable.h> #include <util/SinglyLinkedList.h> #include <util/Stack.h> ############################################################################ Commit: a0ddc600d3013646ce4a6905d8736a363cd63827 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 16 19:59:08 2012 UTC Revert "Add mapping from vnode ID to block number for moved inodes" Conflicts: src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 7da1146..53c02a6e 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -788,7 +788,7 @@ BlockAllocator::IsBlockRunOutsideRange(block_run run) const */ status_t BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, - uint16 start, uint16 maximum, uint16 minimum, block_run& run, bool inode) + uint16 start, uint16 maximum, uint16 minimum, block_run& run) { if (maximum == 0) return B_BAD_VALUE; @@ -802,16 +802,6 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, AllocationBlock cached(fVolume); RecursiveLocker lock(fLock); - bool checkMovedInodes = false; - ReadLocker movedInodesLocker; - if (inode) { - movedInodesLocker.SetTo(fVolume->MovedInodesLock(), false); - - // don't check for moved inodes unless the volume actually has them - if (fVolume->HasMovedInodes()) - checkMovedInodes = true; - } - uint32 bitsPerFullBlock = fVolume->BlockSize() << 3; // Express the allowed allocation range in terms of allocation groups and @@ -867,7 +857,7 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, if (start < group.fFirstFree) start = group.fFirstFree; - if (group.fLargestValid && !checkMovedInodes) { + if (group.fLargestValid) { if (group.fLargestLength < bestLength) continue; @@ -897,8 +887,7 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, int32 groupLargestStart = -1; int32 groupLargestLength = -1; int32 currentBit = start; - bool canFindGroupLargest = start == 0 && end == group.NumBits() - && !checkMovedInodes; + bool canFindGroupLargest = start == 0 && end == group.NumBits(); // If end is the first bit in a block, the last block considered is the // previous one, and the end bit is bitsPerFullBlock. @@ -922,22 +911,7 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, // find a block large enough to hold the allocation for (uint32 bit = start % bitsPerFullBlock; bit < endBit; bit++) { - bool isUsed = cached.IsUsed(bit); - - // if we're allocating space for an inode, we treat blocks - // which used to have moved inodes as used - if (checkMovedInodes && !isUsed) { - ino_t currentBlock = fVolume->ToBlock( - block_run::Run(groupIndex, currentBit, 1)); - - // while it might seem excessive to do a hash lookup for - // every bit we check, an inode only requires a single - // block, so we're unlikely to do this more than once, or - // a couple of times at most - isUsed = fVolume->WasMovedInode(currentBlock); - } - - if (!isUsed) { + if (!cached.IsUsed(bit)) { if (currentLength == 0) { // start new range currentStart = currentBit; @@ -1067,7 +1041,7 @@ BlockAllocator::AllocateForInode(Transaction& transaction, if ((type & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR)) == S_DIRECTORY) group += 8; - return AllocateBlocks(transaction, group, 0, 1, 1, run, true); + return AllocateBlocks(transaction, group, 0, 1, 1, run); } diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h index c8bf937..3de7212 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h @@ -47,8 +47,7 @@ public: status_t AllocateBlocks(Transaction& transaction, int32 group, uint16 start, uint16 numBlocks, - uint16 minimum, block_run& run, - bool inode = false); + uint16 minimum, block_run& run); status_t AllocateBlockRun(Transaction& transaction, block_run run); diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index ed47c16..414ae6b 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -612,8 +612,8 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) // TODO: this allocation hint could certainly be improved block_run run; - status_t status = GetVolume()->Allocator().AllocateBlocks(transaction, - hintRun.AllocationGroup(), hintRun.Start(), 1, 1, run, true); + status_t status = GetVolume()->Allocator().AllocateBlocks(transaction, 0, 0, + 1, 1, run); if (status != B_OK) RETURN_ERROR(status); @@ -676,12 +676,5 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) } } - WriteLocker movedInodesLocker(GetVolume()->MovedInodesLock()); - status = GetVolume()->AddMovedInode(inode->ID(), newInodeID); - if (status != B_OK) { - FATAL(("_MoveInode: Could not add inode to vnodeID -> inodeID map!\n")); - return status; - } - return B_OK; } diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 42e27c7..f81e723 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -285,20 +285,15 @@ Volume::Volume(fs_volume* volume) fDirtyCachedBlocks(0), fFlags(0), fCheckingThread(-1), - fCheckVisitor(NULL), - fMovedInodes(NULL) + fCheckVisitor(NULL) { mutex_init(&fLock, "bfs volume"); mutex_init(&fQueryLock, "bfs queries"); - rw_lock_init(&fMovedInodesLock, "bfs moved inodes"); } Volume::~Volume() { - delete fMovedInodes; - - rw_lock_destroy(&fMovedInodesLock); mutex_destroy(&fQueryLock); mutex_destroy(&fLock); } @@ -549,65 +544,6 @@ Volume::CreateIndicesRoot(Transaction& transaction) status_t -Volume::AddMovedInode(ino_t oldID, ino_t newID) -{ - ASSERT_WRITE_LOCKED_RW_LOCK(&fMovedInodesLock); - - if (fMovedInodes == NULL) - fMovedInodes = new(std::nothrow) InodeMap; - - if (fMovedInodes == NULL) - return B_NO_MEMORY; - - return fMovedInodes->Put(oldID, newID); -} - - -bool -Volume::HasMovedInodes() const -{ - return fMovedInodes != NULL; -} - - -InodeMap::Iterator -Volume::MovedInodesIterator() const -{ - ASSERT(fMovedInodes != NULL); - return fMovedInodes->GetIterator(); -} - - -ino_t -Volume::ResolveVnodeID(ino_t vnodeID) -{ - ReadLocker locker(fMovedInodesLock); - - // no inodes have been moved - if (fMovedInodes == NULL) - return vnodeID; - - ino_t* inodeID; - - // has this inode been moved? - if (fMovedInodes->Get(vnodeID, inodeID)) - return *inodeID; - - return vnodeID; -} - - -bool -Volume::WasMovedInode(ino_t blockNumber) -{ - ASSERT(fMovedInodes != NULL); - ReadLocker locker(fMovedInodesLock); - - return fMovedInodes->ContainsKey(blockNumber); -} - - -status_t Volume::CreateVolumeID(Transaction& transaction) { Attribute attr(fRootNode); diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index faec36a..f27ec43 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -29,8 +29,6 @@ enum volume_initialize_flags { typedef DoublyLinkedList<Inode> InodeList; -typedef HashMap<HashKey64<ino_t>, ino_t> InodeMap; - class Volume { public: @@ -105,15 +103,6 @@ public: InodeList& RemovedInodes() { return fRemovedInodes; } // This list is guarded by the transaction lock - // moved inodes - rw_lock& MovedInodesLock() { return fMovedInodesLock; } - status_t AddMovedInode(ino_t oldID, ino_t newID); - bool HasMovedInodes() const; - InodeMap::Iterator MovedInodesIterator() const; - - ino_t ResolveVnodeID(ino_t vnodeID); - bool WasMovedInode(ino_t blockNumber); - // block bitmap BlockAllocator& Allocator(); status_t AllocateForInode(Transaction& transaction, @@ -193,9 +182,6 @@ protected: ::CheckVisitor* fCheckVisitor; InodeList fRemovedInodes; - - rw_lock fMovedInodesLock; - InodeMap* fMovedInodes; }; 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 06efc12..78a869d 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -269,20 +269,12 @@ bfs_sync(fs_volume* _volume) /*! Reads in the node from disk and creates an inode object from it. */ static status_t -bfs_get_vnode(fs_volume* _volume, ino_t _id, fs_vnode* _node, int* _type, +bfs_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, uint32* _flags, bool reenter) { //FUNCTION_START(("ino_t = %Ld\n", id)); Volume* volume = (Volume*)_volume->private_volume; - ino_t id = volume->ResolveVnodeID(_id); - if (id != _id) { - // TODO: we return an error here for now - INFORM(("Denying access to remapped inode, old ID=%" B_PRIdINO - ", new ID=%" B_PRIdINO "\n", _id, id)); - return B_ERROR; - } - // the index root node is not managed through the VFS layer, so we need // to return the correct object here to avoid having two out of sync // objects for the same inode diff --git a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h index 1b27fea..6e89896 100644 --- a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h +++ b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h @@ -16,7 +16,6 @@ #else // !BFS_SHELL #include <AutoDeleter.h> -#include <shared/HashMap.h> #include <util/AutoLock.h> #include <util/DoublyLinkedList.h> #include <util/kernel_cpp.h> ############################################################################ Commit: f29dd67d01bb591bee996cd5914e0546f559882c Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Fri Aug 17 17:17:48 2012 UTC Start preparing for vnode remapping An Inode object stores its block number, and converts it to a vnode ID when needed. Requests for the inode ID are changed depending on what they actually want: Internal operations (BPlusTree updating for instance) use the block numbers, and interactions with the outside world use the vnode ID. For now, vnode IDs and block numbers are differentiated by a simple xor operation in the translation functions. It's unlikely that all places that need to be changed have been changed, but things seem to work fine in when testing casually. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index 90972f3..0a76085 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -297,7 +297,7 @@ CachedNode::SetTo(off_t offset, const bplustree_node** _node, bool check) if (!fTree->fHeader.CheckNode(fNode)) { FATAL(("invalid node [%p] read from offset %" B_PRIdOFF " (block %" B_PRIdOFF "), inode at %" B_PRIdINO "\n", fNode, offset, - fBlockNumber, fTree->fStream->ID())); + fBlockNumber, fTree->fStream->BlockNumber())); return B_BAD_DATA; } } @@ -330,7 +330,7 @@ CachedNode::SetToWritable(Transaction& transaction, off_t offset, bool check) if (!fTree->fHeader.CheckNode(fNode)) { FATAL(("invalid node [%p] read from offset %" B_PRIdOFF " (block %" B_PRIdOFF "), inode at %" B_PRIdINO "\n", fNode, offset, - fBlockNumber, fTree->fStream->ID())); + fBlockNumber, fTree->fStream->BlockNumber())); return NULL; } } diff --git a/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp index c22d18d..ac340ee 100644 --- a/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp @@ -392,10 +392,10 @@ CheckVisitor::_RemoveInvalidNode(Inode* parent, BPlusTree* tree, parent->WriteLockInTransaction(transaction); // does the file even exist? - off_t id; - status = tree->Find((uint8*)name, (uint16)strlen(name), &id); + off_t blockNumber; + status = tree->Find((uint8*)name, (uint16)strlen(name), &blockNumber); if (status == B_OK) - status = tree->Remove(transaction, name, id); + status = tree->Remove(transaction, name, blockNumber); } if (status == B_OK) { @@ -729,22 +729,25 @@ CheckVisitor::_AddInodeToIndex(Inode* inode) if (inode->GetName(name, B_FILE_NAME_LENGTH) != B_OK) return B_ERROR; - status = tree->Insert(transaction, name, inode->ID()); + status = tree->Insert(transaction, name, inode->BlockNumber()); } } else if (!strcmp(index->name, "last_modified")) { if (inode->InLastModifiedIndex()) { status = tree->Insert(transaction, inode->OldLastModified(), - inode->ID()); + inode->BlockNumber()); } } else if (!strcmp(index->name, "size")) { - if (inode->InSizeIndex()) - status = tree->Insert(transaction, inode->Size(), inode->ID()); + if (inode->InSizeIndex()) { + status = tree->Insert(transaction, inode->Size(), + inode->BlockNumber()); + } } else { uint8 key[BPLUSTREE_MAX_KEY_LENGTH]; size_t keyLength = BPLUSTREE_MAX_KEY_LENGTH; if (inode->ReadAttribute(index->name, B_ANY_TYPE, 0, key, &keyLength) == B_OK) { - status = tree->Insert(transaction, key, keyLength, inode->ID()); + status = tree->Insert(transaction, key, keyLength, + inode->BlockNumber()); } } diff --git a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp index a2a759d..a8a3ca8 100644 --- a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp @@ -216,7 +216,7 @@ FileSystemVisitor::Start(uint32 flags) // traversing the file system anymore. InodeList::Iterator iterator = fVolume->RemovedInodes().GetIterator(); while (Inode* inode = iterator.Next()) { - Vnode vnode(fVolume, inode->ID()); + Vnode vnode(fVolume, inode->BlockNumber()); vnode.Keep(); fStack.Push(inode->BlockRun()); } diff --git a/src/add-ons/kernel/file_systems/bfs/Index.cpp b/src/add-ons/kernel/file_systems/bfs/Index.cpp index 962c6ac..f1661e1 100644 --- a/src/add-ons/kernel/file_systems/bfs/Index.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Index.cpp @@ -253,7 +253,7 @@ Index::Update(Transaction& transaction, const char* name, int32 type, if (oldKey != NULL) { status = tree->Remove(transaction, (const uint8*)oldKey, oldLength, - inode->ID()); + inode->BlockNumber()); if (status == B_ENTRY_NOT_FOUND) { // That's not nice, but no reason to let the whole thing fail INFORM(("Could not find value in index \"%s\"!\n", name)); @@ -265,7 +265,7 @@ Index::Update(Transaction& transaction, const char* name, int32 type, if (newKey != NULL) { status = tree->Insert(transaction, (const uint8*)newKey, newLength, - inode->ID()); + inode->BlockNumber()); } RETURN_ERROR(status); diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index bb1aa84..f6f44b0 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -248,7 +248,7 @@ InodeAllocator::New(block_run* parentRun, mode_t mode, block_run& run, } run = fRun; - fInode = new Inode(volume, *fTransaction, volume->ToVnode(run), mode, run); + fInode = new Inode(volume, *fTransaction, volume->ToBlock(run), mode, run); if (fInode == NULL) RETURN_ERROR(B_NO_MEMORY); @@ -282,9 +282,9 @@ InodeAllocator::CreateTree() return B_ERROR; if (fInode->IsRegularNode()) { - if (tree->Insert(*fTransaction, ".", fInode->ID()) != B_OK + if (tree->Insert(*fTransaction, ".", fInode->BlockNumber()) != B_OK || tree->Insert(*fTransaction, "..", - volume->ToVnode(fInode->Parent())) != B_OK) + volume->ToBlock(fInode->Parent())) != B_OK) return B_ERROR; } return B_OK; @@ -483,10 +483,10 @@ bfs_inode::InitCheck(Volume* volume) const // #pragma mark - Inode -Inode::Inode(Volume* volume, ino_t id) +Inode::Inode(Volume* volume, off_t blockNumber) : fVolume(volume), - fID(id), + fBlockNumber(blockNumber), fTree(NULL), fAttributes(NULL), fCache(NULL), @@ -512,11 +512,11 @@ Inode::Inode(Volume* volume, ino_t id) } -Inode::Inode(Volume* volume, Transaction& transaction, ino_t id, mode_t mode, - block_run& run) +Inode::Inode(Volume* volume, Transaction& transaction, off_t blockNumber, + mode_t mode, block_run& run) : fVolume(volume), - fID(id), + fBlockNumber(blockNumber), fTree(NULL), fAttributes(NULL), fCache(NULL), @@ -606,7 +606,7 @@ Inode::SetID(ino_t ID) if (Parent() == BlockRun()) fNode.parent = fVolume->ToBlockRun(ID); - fID = ID; + fBlockNumber = ID; fNode.inode_num = fVolume->ToBlockRun(ID); } @@ -3071,14 +3071,16 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, WriteLockInTransaction(transaction); // does the file even exist? - off_t id; - if (fTree->Find((uint8*)name, (uint16)strlen(name), &id) != B_OK) + off_t blockNumber; + if (fTree->Find((uint8*)name, (uint16)strlen(name), &blockNumber) != B_OK) return B_ENTRY_NOT_FOUND; + ino_t id = fVolume->ToVnode(blockNumber); + if (_id) *_id = id; - Vnode vnode(fVolume, id); + Vnode vnode(fVolume, blockNumber); Inode* inode; status_t status = vnode.Get(&inode); if (status != B_OK) { @@ -3108,13 +3110,13 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, if (status != B_OK) return status; - if (fTree->Remove(transaction, name, id) != B_OK && !force) { + if (fTree->Remove(transaction, name, blockNumber) != B_OK && !force) { unremove_vnode(fVolume->FSVolume(), id); RETURN_ERROR(B_ERROR); } #ifdef DEBUG - if (fTree->Find((uint8*)name, (uint16)strlen(name), &id) == B_OK) { + if (fTree->Find((uint8*)name, (uint16)strlen(name), &blockNumber) == B_OK) { DIE(("deleted entry still there")); } #endif @@ -3232,7 +3234,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, if (_created) *_created = false; if (_id) - *_id = inode->ID(); + *_id = inode->ID(); // TODO this should be create id if (_inode) *_inode = inode; @@ -3306,7 +3308,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, // (the vnode is not published yet, so it is safe to make the inode // accessable to the file system here) if (tree != NULL) { - status = tree->Insert(transaction, name, inode->ID()); + status = tree->Insert(transaction, name, inode->BlockNumber()); } else if (parent != NULL && (mode & S_ATTR_DIR) != 0) { parent->Attributes() = run; status = parent->WriteBack(transaction); @@ -3332,7 +3334,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, // because the InodeAllocator destructor can't handle this // case (and if it fails, we can't do anything about it...) if (tree) - tree->Remove(transaction, name, inode->ID()); + tree->Remove(transaction, name, inode->BlockNumber()); else if (parent != NULL && (mode & S_ATTR_DIR) != 0) parent->Node().attributes.SetTo(0, 0, 0); @@ -3370,7 +3372,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, if (_created) *_created = true; if (_id != NULL) - *_id = inode->ID(); + *_id = inode->ID(); // TODO this should be create id if (_inode != NULL) *_inode = inode; @@ -3391,7 +3393,7 @@ Inode::Copy(Transaction& transaction, off_t targetBlock) return B_IO_ERROR; CachedBlock source(fVolume); - const uint8* sourceData = source.SetTo(fID); + const uint8* sourceData = source.SetTo(fBlockNumber); if (sourceData == NULL) return B_IO_ERROR; diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index fa02dde..8cdb358 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -30,17 +30,19 @@ class Inode : public TransactionListener { typedef DoublyLinkedListLink<Inode> Link; public: - Inode(Volume* volume, ino_t id); + Inode(Volume* volume, off_t blockNumber); Inode(Volume* volume, Transaction& transaction, - ino_t id, mode_t mode, block_run& run); + off_t blockNumber, mode_t mode, + block_run& run); ~Inode(); status_t InitCheck(bool checkNode = true) const; - ino_t ID() const { return fID; } - off_t BlockNumber() const - { return fVolume->VnodeToBlock(fID); } - void SetID(ino_t ID); + //ino_t ID() const { return fID; } + ino_t ID() const + { return fVolume->ToVnode(fBlockNumber); } + off_t BlockNumber() const { return fBlockNumber; } + void SetID(ino_t ID); // TODO rename me rw_lock& Lock() { return fLock; } ReadLocker ReadLock() { return ReadLocker(fLock); } @@ -273,7 +275,7 @@ private: private: rw_lock fLock; Volume* fVolume; - ino_t fID; + off_t fBlockNumber; BPlusTree* fTree; Inode* fAttributes; void* fCache; @@ -361,14 +363,14 @@ public: NodeGetter(Volume* volume, const Inode* inode) : CachedBlock(volume) { - SetTo(volume->VnodeToBlock(inode->ID())); + SetTo(inode->BlockNumber()); } NodeGetter(Volume* volume, Transaction& transaction, const Inode* inode, bool empty = false) : CachedBlock(volume) { - SetToWritable(transaction, volume->VnodeToBlock(inode->ID()), empty); + SetToWritable(transaction, inode->BlockNumber(), empty); } ~NodeGetter() @@ -377,7 +379,7 @@ public: const bfs_inode* SetToNode(const Inode* inode) { - return (const bfs_inode*)SetTo(fVolume->VnodeToBlock(inode->ID())); + return (const bfs_inode*)SetTo(inode->BlockNumber()); } const bfs_inode* Node() const { return (const bfs_inode*)Block(); } @@ -391,11 +393,11 @@ public: class Vnode { public: - Vnode(Volume* volume, ino_t id) + Vnode(Volume* volume, off_t blockNumber) : fInode(NULL) { - SetTo(volume, id); + SetTo(volume, blockNumber); } Vnode(Volume* volume, block_run run) @@ -431,16 +433,17 @@ public: } } - status_t SetTo(Volume* volume, ino_t id) + status_t SetTo(Volume* volume, off_t blockNumber) { Unset(); - return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode); + return fStatus = get_vnode(volume->FSVolume(), + volume->ToVnode(blockNumber), (void**)&fInode); } status_t SetTo(Volume* volume, block_run run) { - return SetTo(volume, volume->ToVnode(run)); + return SetTo(volume, volume->ToBlock(run)); } status_t Get(Inode** _inode) diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index f81e723..bc2f27a 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -401,7 +401,7 @@ Volume::Mount(const char* deviceName, uint32 flags) return status; } - fRootNode = new(std::nothrow) Inode(this, ToVnode(Root())); + fRootNode = new(std::nothrow) Inode(this, ToBlock(Root())); if (fRootNode != NULL && fRootNode->InitCheck() == B_OK) { status = publish_vnode(fVolume, ToVnode(Root()), (void*)fRootNode, &gBFSVnodeOps, fRootNode->Mode(), 0); @@ -410,7 +410,7 @@ Volume::Mount(const char* deviceName, uint32 flags) if (!Indices().IsZero()) { fIndicesNode = new(std::nothrow) Inode(this, - ToVnode(Indices())); + ToBlock(Indices())); } if (fIndicesNode == NULL @@ -538,7 +538,7 @@ Volume::CreateIndicesRoot(Transaction& transaction) if (status != B_OK) RETURN_ERROR(status); - fSuperBlock.indices = ToBlockRun(id); + fSuperBlock.indices = ToBlockRun(VnodeToBlock(id)); return WriteSuperBlock(); } @@ -800,13 +800,13 @@ Volume::Initialize(int fd, const char* name, uint32 blockSize, if (fBlockAllocator.InitializeAndClearBitmap(transaction) != B_OK) RETURN_ERROR(B_ERROR); - off_t id; + ino_t id; status_t status = Inode::Create(transaction, NULL, NULL, S_DIRECTORY | 0755, 0, 0, NULL, &id, &fRootNode); if (status != B_OK) RETURN_ERROR(status); - fSuperBlock.root_dir = ToBlockRun(id); + fSuperBlock.root_dir = ToBlockRun(VnodeToBlock(id)); if ((flags & VOLUME_NO_INDICES) == 0) { // The indices root directory will be created automatically diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index f27ec43..72b838c 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -92,9 +92,12 @@ public: status_t ValidateBlockRun(block_run run); off_t ToVnode(block_run run) const - { return ToBlock(run); } - off_t ToVnode(off_t block) const { return block; } - off_t VnodeToBlock(ino_t id) const { return (off_t)id; } + { return ToVnode(ToBlock(run)); } + off_t ToVnode(off_t block) const + { return block ^ (0xff000000); } + off_t VnodeToBlock(ino_t id) const + { return (off_t)id ^ (0xff000000); } + // TODO this can fail status_t CreateIndicesRoot(Transaction& transaction); 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 78a869d..4968136 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -275,10 +275,13 @@ bfs_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, //FUNCTION_START(("ino_t = %Ld\n", id)); Volume* volume = (Volume*)_volume->private_volume; + off_t blockNumber = volume->VnodeToBlock(id); + // the index root node is not managed through the VFS layer, so we need // to return the correct object here to avoid having two out of sync // objects for the same inode - if (volume->IndicesNode() != NULL && id == volume->IndicesNode()->ID()) { + if (volume->IndicesNode() != NULL + && blockNumber == volume->IndicesNode()->BlockNumber()) { _node->private_node = volume->IndicesNode(); _node->ops = &gBFSVnodeOps; *_type = volume->IndicesNode()->Mode(); @@ -288,13 +291,13 @@ bfs_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, // first inode may be after the log area, we don't go through // the hassle and try to load an earlier block from disk - if (id < volume->ToBlock(volume->Log()) + volume->Log().Length() - || id > volume->NumBlocks()) { - INFORM(("inode at %" B_PRIdINO " requested!\n", id)); + if (blockNumber < volume->ToBlock(volume->Log()) + volume->Log().Length() + || blockNumber > volume->NumBlocks()) { + INFORM(("inode at block %" B_PRIdINO " requested!\n", blockNumber)); return B_ERROR; } - CachedBlock cached(volume, id); + CachedBlock cached(volume, blockNumber); bfs_inode* node = (bfs_inode*)cached.Block(); if (node == NULL) { FATAL(("could not read inode: %" B_PRIdINO "\n", id)); @@ -312,7 +315,7 @@ bfs_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, return status; } - Inode* inode = new(std::nothrow) Inode(volume, id); + Inode* inode = new(std::nothrow) Inode(volume, blockNumber); if (inode == NULL) return B_NO_MEMORY; @@ -599,12 +602,15 @@ bfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* file, if (tree == NULL) RETURN_ERROR(B_BAD_VALUE); - status = tree->Find((uint8*)file, (uint16)strlen(file), _vnodeID); + off_t blockNumber; + status = tree->Find((uint8*)file, (uint16)strlen(file), &blockNumber); if (status != B_OK) { //PRINT(("bfs_walk() could not find %Ld:\"%s\": %s\n", directory->BlockNumber(), file, strerror(status))); return status; } + *_vnodeID = volume->ToVnode(blockNumber); + entry_cache_add(volume->ID(), directory->ID(), file, *_vnodeID); locker.Unlock(); @@ -1039,7 +1045,7 @@ bfs_create_symlink(fs_volume* _volume, fs_vnode* _directory, const char* name, Transaction transaction(volume, directory->BlockNumber()); Inode* link; - off_t id; + ino_t id; status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777, 0, 0, NULL, &id, &link); if (status != B_OK) @@ -1110,7 +1116,7 @@ bfs_unlink(fs_volume* _volume, fs_vnode* _directory, const char* name) Transaction transaction(volume, directory->BlockNumber()); - off_t id; + ino_t id; status = directory->Remove(transaction, name, &id); if (status == B_OK) { entry_cache_remove(volume->ID(), directory->ID(), name); @@ -1159,12 +1165,12 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, if (tree == NULL) RETURN_ERROR(B_BAD_VALUE); - off_t id; - status = tree->Find((const uint8*)oldName, strlen(oldName), &id); + off_t blockNumber; + status = tree->Find((const uint8*)oldName, strlen(oldName), &blockNumber); if (status != B_OK) RETURN_ERROR(status); - Vnode vnode(volume, id); + Vnode vnode(volume, blockNumber); Inode* inode; if (vnode.Get(&inode) != B_OK) return B_IO_ERROR; @@ -1175,13 +1181,13 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, // If we meet our inode on that way, we have to bail out. if (oldDirectory != newDirectory) { - ino_t parent = newDirectory->ID(); - ino_t root = volume->RootNode()->ID(); + off_t parent = newDirectory->BlockNumber(); + off_t root = volume->RootNode()->BlockNumber(); while (true) { - if (parent == id) + if (parent == blockNumber) return B_BAD_VALUE; - else if (parent == root || parent == oldDirectory->ID()) + else if (parent == root || parent == oldDirectory->BlockNumber()) break; Vnode vnode(volume, parent); @@ -1189,7 +1195,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, if (vnode.Get(&parentNode) != B_OK) return B_ERROR; - parent = volume->ToVnode(parentNode->Parent()); + parent = volume->ToBlock(parentNode->Parent()); } } @@ -1206,7 +1212,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, } status = newTree->Insert(transaction, (const uint8*)newName, - strlen(newName), id); + strlen(newName), blockNumber); if (status == B_NAME_IN_USE) { // If there is already a file with that name, we have to remove // it, as long it's not a directory with files in it @@ -1214,7 +1220,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, if (newTree->Find((const uint8*)newName, strlen(newName), &clobber) != B_OK) return B_NAME_IN_USE; - if (clobber == id) + if (clobber == blockNumber) return B_BAD_VALUE; Vnode vnode(volume, clobber); @@ -1237,7 +1243,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, clobber); status = newTree->Insert(transaction, (const uint8*)newName, - strlen(newName), id); + strlen(newName), blockNumber); } if (status != B_OK) return status; @@ -1258,7 +1264,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, if (status == B_OK) { status = tree->Remove(transaction, (const uint8*)oldName, - strlen(oldName), id); + strlen(oldName), blockNumber); if (status == B_OK) { inode->Parent() = newDirectory->BlockRun(); @@ -1269,11 +1275,12 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, && inode->IsDirectory() && movedTree != NULL) { status = movedTree->Replace(transaction, (const uint8*)"..", - 2, newDirectory->ID()); + 2, newDirectory->BlockNumber()); if (status == B_OK) { // update/add the cache entry for the parent - entry_cache_add(volume->ID(), id, "..", newDirectory->ID()); + entry_cache_add(volume->ID(), inode->ID(), "..", + newDirectory->ID()); } } @@ -1287,17 +1294,19 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, if (status == B_OK) { entry_cache_remove(volume->ID(), oldDirectory->ID(), oldName); - entry_cache_add(volume->ID(), newDirectory->ID(), newName, id); + entry_cache_add(volume->ID(), newDirectory->ID(), newName, + inode->ID()); status = transaction.Done(); if (status == B_OK) { notify_entry_moved(volume->ID(), oldDirectory->ID(), - oldName, newDirectory->ID(), newName, id); + oldName, newDirectory->ID(), newName, inode->ID()); return B_OK; } entry_cache_remove(volume->ID(), newDirectory->ID(), newName); - entry_cache_add(volume->ID(), oldDirectory->ID(), oldName, id); + entry_cache_add(volume->ID(), oldDirectory->ID(), oldName, + inode->ID()); } } } @@ -1605,7 +1614,7 @@ bfs_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name, // Inode::Create() locks the inode if we pass the "id" parameter, but we // need it anyway - off_t id; + ino_t id; status = Inode::Create(transaction, directory, name, S_DIRECTORY | (mode & S_IUMSK), 0, 0, NULL, &id); if (status == B_OK) { @@ -1634,7 +1643,7 @@ bfs_remove_dir(fs_volume* _volume, fs_vnode* _directory, const char* name) Transaction transaction(volume, directory->BlockNumber()); - off_t id; + ino_t id; status_t status = directory->Remove(transaction, name, &id, true); if (status == B_OK) { // Remove the cache entry for the directory and potentially also @@ -1695,9 +1704,9 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, TreeIterator* iterator = (TreeIterator*)_cookie; uint16 length; - ino_t id; + off_t blockNumber; status_t status = iterator->GetNextEntry(dirent->d_name, &length, - bufferSize, &id); + bufferSize, &blockNumber); if (status == B_ENTRY_NOT_FOUND) { *_num = 0; return B_OK; @@ -1707,7 +1716,7 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, Volume* volume = (Volume*)_volume->private_volume; dirent->d_dev = volume->ID(); - dirent->d_ino = id; + dirent->d_ino = volume->ToVnode(blockNumber); dirent->d_reclen = sizeof(struct dirent) + length; @@ -2002,7 +2011,7 @@ bfs_create_special_node(fs_volume* _volume, fs_vnode* _directory, Transaction transaction(volume, directory->BlockNumber()); - off_t id; + ino_t id; Inode* inode; status = Inode::Create(transaction, directory, name, mode, O_EXCL, 0, NULL, &id, &inode, subVnode ? subVnode->ops : NULL, flags);