On 09.08.2012 21:49, ahenriksson-github.production wrote:
added 9 changesets to branch 'refs/remotes/ahenriksson-github/production' old head: f111ce9ecde50daba2af6186c7c606aa4f08a9ca new head: 86611e9a7098570ddafc97c278341dc39e65e8d6 ---------------------------------------------------------------------------- af39cec: Switch to util/OpenHashTable.h for the moved inodes table 9c3924b: Revert "Added HashMap to fs_shell" This reverts commit f111ce9ecde50daba2af6186c7c606aa4f08a9ca. 99c8c01: Update vnid in entry_cache (needs work) This is probably a temporary solution so I don't have to worry about bugs introduced by the vnode remapping. 51347bb: The index root requires some special handling d6eb1f4: Fix bugs when moving deleted inodes 92f44a3: Change locking of moved inode to prevent deadlocks 317e139: Pointer star style cleanup in devfs.h No functional change. f3c952c: Change devfs device size 86611e9: Change size of the KPartition [ ahenriksson <sausageboy@xxxxxxxxx> ] ---------------------------------------------------------------------------- 18 files changed, 265 insertions(+), 959 deletions(-) headers/os/drivers/fs_interface.h | 3 +- headers/private/fs_shell/HashMap.h | 403 ------------ headers/private/fs_shell/OpenHashTable.h | 514 ---------------- headers/private/fs_shell/fssh_api_wrapper.h | 1 - .../kernel/disk_device_manager/KPartition.h | 1 + headers/private/kernel/fs/devfs.h | 25 +- .../kernel/file_systems/bfs/FileSystemVisitor.cpp | 28 + src/add-ons/kernel/file_systems/bfs/Inode.h | 2 + .../kernel/file_systems/bfs/ResizeVisitor.cpp | 51 +- src/add-ons/kernel/file_systems/bfs/Utility.h | 7 + src/add-ons/kernel/file_systems/bfs/Volume.cpp | 90 ++- src/add-ons/kernel/file_systems/bfs/Volume.h | 6 +- .../kernel/file_systems/bfs/system_dependencies.h | 2 +- src/system/kernel/device_manager/devfs.cpp | 15 + .../kernel/disk_device_manager/KFileSystem.cpp | 3 + .../kernel/disk_device_manager/KPartition.cpp | 26 + .../disk_device_manager/KPartitioningSystem.cpp | 35 +- src/system/kernel/fs/vfs.cpp | 12 +- ############################################################################ Commit: af39cec0fb102f343b1dbaa7699bea7cd252ac59 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Aug 8 11:06:35 2012 UTC 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 48a6b5f..0bb810b 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -60,6 +60,27 @@ 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) @@ -191,6 +212,45 @@ 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 { @@ -296,6 +356,7 @@ Volume::Volume(fs_volume* volume) Volume::~Volume() { + FreeMovedInodes(); delete fMovedInodes; rw_lock_destroy(&fMovedInodesLock); @@ -559,7 +620,11 @@ Volume::AddMovedInode(ino_t oldID, ino_t newID) if (fMovedInodes == NULL) return B_NO_MEMORY; - return fMovedInodes->Put(oldID, newID); + InodeMapValue* newMapping = new(std::nothrow) InodeMapValue(oldID, newID); + if (newMapping == NULL) + return B_NO_MEMORY; + + return fMovedInodes->Insert(newMapping); } @@ -570,11 +635,17 @@ Volume::HasMovedInodes() const } -InodeMap::Iterator -Volume::MovedInodesIterator() const +void +Volume::FreeMovedInodes() { - ASSERT(fMovedInodes != NULL); - return fMovedInodes->GetIterator(); + WriteLocker locker(fMovedInodesLock); + + if (fMovedInodes != NULL) { + InodeMap::Iterator iterator = fMovedInodes->GetIterator(); + + while (iterator.HasNext()) + delete iterator.Next(); + } } @@ -587,11 +658,10 @@ Volume::ResolveVnodeID(ino_t vnodeID) if (fMovedInodes == NULL) return vnodeID; - ino_t* inodeID; - // has this inode been moved? - if (fMovedInodes->Get(vnodeID, inodeID)) - return *inodeID; + InodeMapValue* entry = fMovedInodes->Lookup(vnodeID); + if (entry != NULL) + return entry->fNewID; return vnodeID; } @@ -603,7 +673,7 @@ Volume::WasMovedInode(ino_t blockNumber) ASSERT(fMovedInodes != NULL); ReadLocker locker(fMovedInodesLock); - return fMovedInodes->ContainsKey(blockNumber); + return fMovedInodes->Lookup(blockNumber) != NULL; } diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index faec36a..0d07b57 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -18,6 +18,8 @@ class Inode; class Query; class ResizeVisitor; +struct InodeMapDefinitions; + enum volume_flags { VOLUME_READ_ONLY = 0x0001 @@ -29,7 +31,7 @@ enum volume_initialize_flags { typedef DoublyLinkedList<Inode> InodeList; -typedef HashMap<HashKey64<ino_t>, ino_t> InodeMap; +typedef BOpenHashTable<InodeMapDefinitions> InodeMap; class Volume { @@ -109,7 +111,7 @@ public: rw_lock& MovedInodesLock() { return fMovedInodesLock; } status_t AddMovedInode(ino_t oldID, ino_t newID); bool HasMovedInodes() const; - InodeMap::Iterator MovedInodesIterator() const; + void FreeMovedInodes(); 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 1b27fea..68c415d 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: 9c3924bf4e1cd488d02ad4771a96f9007d6280a8 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Aug 8 12:44:06 2012 UTC Revert "Added HashMap to fs_shell" This reverts commit f111ce9ecde50daba2af6186c7c606aa4f08a9ca. ---------------------------------------------------------------------------- diff --git a/headers/private/fs_shell/HashMap.h b/headers/private/fs_shell/HashMap.h deleted file mode 100644 index 3660705..0000000 --- a/headers/private/fs_shell/HashMap.h +++ /dev/null @@ -1,403 +0,0 @@ -// HashMap.h -// -// Copyright (c) 2004-2007, Ingo Weinhold (bonefish@xxxxxxxxxxxxxxx) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// Except as contained in this notice, the name of a copyright holder shall -// not be used in advertising or otherwise to promote the sale, use or other -// dealings in this Software without prior written authorization of the -// copyright holder. - -#ifndef HASH_MAP_H -#define HASH_MAP_H - - -#include "fssh_types.h" - -#include "OpenHashTable.h" - - -namespace FSShell { - -// HashMapElement -template<typename Key, typename Value> -class HashMapElement : public OpenHashElement { -private: - typedef HashMapElement<Key, Value> Element; -public: - - HashMapElement() : OpenHashElement(), fKey(), fValue() - { - fNext = -1; - } - - inline uint32_t Hash() const - { - return fKey.GetHashCode(); - } - - inline bool operator==(const OpenHashElement &_element) const - { - const Element &element = static_cast<const Element&>(_element); - return (fKey == element.fKey); - } - - inline void Adopt(Element &element) - { - fKey = element.fKey; - fValue = element.fValue; - } - - Key fKey; - Value fValue; -}; - -// HashMap -template<typename Key, typename Value> -class HashMap { -public: - class Entry { - public: - Entry() {} - Entry(const Key& key, Value value) : key(key), value(value) {} - - Key key; - Value value; - }; - - class Iterator { - private: - typedef HashMapElement<Key, Value> Element; - public: - Iterator(const Iterator& other) - : - fMap(other.fMap), - fIndex(other.fIndex), - fElement(other.fElement), - fLastElement(other.fElement) - { - } - - bool HasNext() const - { - return fElement; - } - - Entry Next() - { - if (!fElement) - return Entry(); - Entry result(fElement->fKey, fElement->fValue); - _FindNext(); - return result; - } - - Value* NextValue() - { - if (fElement == NULL) - return NULL; - - Value* value = &fElement->fValue; - _FindNext(); - return value; - } - - Entry Remove() - { - if (!fLastElement) - return Entry(); - Entry result(fLastElement->fKey, fLastElement->fValue); - fMap->fTable.Remove(fLastElement, true); - fLastElement = NULL; - return result; - } - - Iterator& operator=(const Iterator& other) - { - fMap = other.fMap; - fIndex = other.fIndex; - fElement = other.fElement; - fLastElement = other.fLastElement; - return *this; - } - - private: - Iterator(const HashMap<Key, Value>* map) - : - fMap(const_cast<HashMap<Key, Value>*>(map)), - fIndex(0), - fElement(NULL), - fLastElement(NULL) - { - // find first - _FindNext(); - } - - void _FindNext() - { - fLastElement = fElement; - if (fElement && fElement->fNext >= 0) { - fElement = fMap->fTable.ElementAt(fElement->fNext); - return; - } - fElement = NULL; - int32_t arraySize = fMap->fTable.ArraySize(); - for (; !fElement && fIndex < arraySize; fIndex++) - fElement = fMap->fTable.FindFirst(fIndex); - } - - private: - friend class HashMap<Key, Value>; - - HashMap<Key, Value>* fMap; - int32_t fIndex; - Element* fElement; - Element* fLastElement; - }; - - HashMap(); - ~HashMap(); - - fssh_status_t InitCheck() const; - - fssh_status_t Put(const Key& key, Value value); - Value Remove(const Key& key); - void Clear(); - Value Get(const Key& key) const; - bool Get(const Key& key, Value*& _value) const; - - bool ContainsKey(const Key& key) const; - - int32_t Size() const; - - Iterator GetIterator() const; - -protected: - typedef HashMapElement<Key, Value> Element; - friend class Iterator; - -private: - Element *_FindElement(const Key& key) const; - -protected: - OpenHashElementArray<Element> fElementArray; - OpenHashTable<Element, OpenHashElementArray<Element> > fTable; -}; - - -// HashKey32 -template<typename Value> -struct HashKey32 { - HashKey32() {} - HashKey32(const Value& value) : value(value) {} - - uint32_t GetHashCode() const - { - return (uint32_t)value; - } - - HashKey32<Value> operator=(const HashKey32<Value>& other) - { - value = other.value; - return *this; - } - - bool operator==(const HashKey32<Value>& other) const - { - return (value == other.value); - } - - bool operator!=(const HashKey32<Value>& other) const - { - return (value != other.value); - } - - Value value; -}; - - -// HashKey64 -template<typename Value> -struct HashKey64 { - HashKey64() {} - HashKey64(const Value& value) : value(value) {} - - uint32_t GetHashCode() const - { - uint64_t v = (uint64_t)value; - return (uint32_t)(v >> 32) ^ (uint32_t)v; - } - - HashKey64<Value> operator=(const HashKey64<Value>& other) - { - value = other.value; - return *this; - } - - bool operator==(const HashKey64<Value>& other) const - { - return (value == other.value); - } - - bool operator!=(const HashKey64<Value>& other) const - { - return (value != other.value); - } - - Value value; -}; - - -// HashMap - -// constructor -template<typename Key, typename Value> -HashMap<Key, Value>::HashMap() - : - fElementArray(1000), - fTable(1000, &fElementArray) -{ -} - -// destructor -template<typename Key, typename Value> -HashMap<Key, Value>::~HashMap() -{ -} - -// InitCheck -template<typename Key, typename Value> -fssh_status_t -HashMap<Key, Value>::InitCheck() const -{ - return (fTable.InitCheck() && fElementArray.InitCheck() - ? FSSH_B_OK : FSSH_B_NO_MEMORY); -} - -// Put -template<typename Key, typename Value> -fssh_status_t -HashMap<Key, Value>::Put(const Key& key, Value value) -{ - Element* element = _FindElement(key); - if (element) { - // already contains the key: just set the new value - element->fValue = value; - return FSSH_B_OK; - } - // does not contain the key yet: add an element - element = fTable.Add(key.GetHashCode()); - if (!element) - return FSSH_B_NO_MEMORY; - element->fKey = key; - element->fValue = value; - return FSSH_B_OK; -} - -// Remove -template<typename Key, typename Value> -Value -HashMap<Key, Value>::Remove(const Key& key) -{ - Value value = Value(); - if (Element* element = _FindElement(key)) { - value = element->fValue; - fTable.Remove(element); - } - return value; -} - -// Clear -template<typename Key, typename Value> -void -HashMap<Key, Value>::Clear() -{ - fTable.RemoveAll(); -} - -// Get -template<typename Key, typename Value> -Value -HashMap<Key, Value>::Get(const Key& key) const -{ - if (Element* element = _FindElement(key)) - return element->fValue; - return Value(); -} - -// Get -template<typename Key, typename Value> -bool -HashMap<Key, Value>::Get(const Key& key, Value*& _value) const -{ - if (Element* element = _FindElement(key)) { - _value = &element->fValue; - return true; - } - - return false; -} - -// ContainsKey -template<typename Key, typename Value> -bool -HashMap<Key, Value>::ContainsKey(const Key& key) const -{ - return _FindElement(key); -} - -// Size -template<typename Key, typename Value> -int32_t -HashMap<Key, Value>::Size() const -{ - return fTable.CountElements(); -} - -// GetIterator -template<typename Key, typename Value> -struct HashMap<Key, Value>::Iterator -HashMap<Key, Value>::GetIterator() const -{ - return Iterator(this); -} - -// _FindElement -template<typename Key, typename Value> -typename HashMap<Key, Value>::Element * -HashMap<Key, Value>::_FindElement(const Key& key) const -{ - Element* element = fTable.FindFirst(key.GetHashCode()); - while (element && element->fKey != key) { - if (element->fNext >= 0) - element = fTable.ElementAt(element->fNext); - else - element = NULL; - } - return element; -} - -} // namespace FSShell - -using FSShell::HashMap; -using FSShell::HashKey32; -using FSShell::HashKey64; - -#endif // HASH_MAP_H diff --git a/headers/private/fs_shell/OpenHashTable.h b/headers/private/fs_shell/OpenHashTable.h deleted file mode 100644 index daa178e..0000000 --- a/headers/private/fs_shell/OpenHashTable.h +++ /dev/null @@ -1,514 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -// bonefish: -// * removed need for exceptions -// * fixed warnings -// * implemented rehashing -// * added RemoveAll() -// TODO: -// * shrinking of element vectors - -// Hash table with open addresssing - -#ifndef __OPEN_HASH_TABLE__ -#define __OPEN_HASH_TABLE__ - -#include <stdlib.h> -#include <new> - -// don't include <Debug.h> -#ifndef _OPEN_HASH_TABLE_ASSERT -# define _OPEN_HASH_TABLE_ASSERT(E) (void)0 -#endif -#ifndef _OPEN_HASH_TABLE_TRESPASS -# define _OPEN_HASH_TABLE_TRESPASS() (void)0 -#endif - -namespace FSShell { - -template <class Element> -class ElementVector { - // element vector for OpenHashTable needs to implement this - // interface -public: - Element &At(int32_t index); - Element *Add(); - int32_t IndexOf(const Element &) const; - void Remove(int32_t index); -}; - -class OpenHashElement { -public: - uint32_t Hash() const; - bool operator==(const OpenHashElement &) const; - void Adopt(OpenHashElement &); - // low overhead copy, original element is in undefined state - // after call (calls Adopt on BString members, etc.) - int32_t fNext; -}; - -const uint32_t kPrimes [] = { - 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, - 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, - 134217689, 268435399, 536870909, 1073741789, 2147483647, 0 -}; - -template <class Element, class ElementVec = ElementVector<Element> > -class OpenHashTable { -public: - OpenHashTable(int32_t minSize, ElementVec *elementVector = 0, - float maxLoadFactor = 0.8); - // it is up to the subclass of OpenHashTable to supply - // elementVector - ~OpenHashTable(); - - bool InitCheck() const; - - void SetElementVector(ElementVec *elementVector); - - Element *FindFirst(uint32_t elementHash) const; - Element *Add(uint32_t elementHash); - - void Remove(Element *element, bool dontRehash = false); - void RemoveAll(); - - // when calling Add, any outstanding element pointer may become - // invalid; to deal with this, get the element index and restore - // it after the add - int32_t ElementIndex(const Element *) const; - Element *ElementAt(int32_t index) const; - - int32_t ArraySize() const; - int32_t VectorSize() const; - int32_t CountElements() const; - -protected: - static int32_t OptimalSize(int32_t minSize); - -private: - bool _RehashIfNeeded(); - bool _Rehash(); - - int32_t fArraySize; - int32_t fInitialSize; - int32_t fElementCount; - int32_t *fHashArray; - ElementVec *fElementVector; - float fMaxLoadFactor; -}; - -template <class Element> -class OpenHashElementArray : public ElementVector<Element> { - // this is a straightforward implementation of an element vector - // deleting is handled by linking deleted elements into a free list - // the vector never shrinks -public: - OpenHashElementArray(int32_t initialSize); - ~OpenHashElementArray(); - - bool InitCheck() const; - - Element &At(int32_t index); - const Element &At(int32_t index) const; - Element *Add(const Element &); - Element *Add(); - void Remove(int32_t index); - int32_t IndexOf(const Element &) const; - int32_t Size() const; - -private: - Element *fData; - int32_t fSize; - int32_t fNextFree; - int32_t fNextDeleted; -}; - - -//----------------------------------- - -template<class Element, class ElementVec> -OpenHashTable<Element, ElementVec>::OpenHashTable(int32_t minSize, - ElementVec *elementVector, float maxLoadFactor) - : fArraySize(OptimalSize(minSize)), - fInitialSize(fArraySize), - fElementCount(0), - fElementVector(elementVector), - fMaxLoadFactor(maxLoadFactor) -{ - // sanity check the maximal load factor - if (fMaxLoadFactor < 0.5) - fMaxLoadFactor = 0.5; - // allocate and init the array - fHashArray = (int32_t*)calloc(fArraySize, sizeof(int32_t)); - if (fHashArray) { - for (int32_t index = 0; index < fArraySize; index++) - fHashArray[index] = -1; - } -} - -template<class Element, class ElementVec> -OpenHashTable<Element, ElementVec>::~OpenHashTable() -{ - RemoveAll(); - free(fHashArray); -} - -template<class Element, class ElementVec> -bool -OpenHashTable<Element, ElementVec>::InitCheck() const -{ - return (fHashArray && fElementVector); -} - -template<class Element, class ElementVec> -int32_t -OpenHashTable<Element, ElementVec>::OptimalSize(int32_t minSize) -{ - for (int32_t index = 0; ; index++) - if (!kPrimes[index] || kPrimes[index] >= (uint32_t)minSize) - return (int32_t)kPrimes[index]; - - return 0; -} - -template<class Element, class ElementVec> -Element * -OpenHashTable<Element, ElementVec>::FindFirst(uint32_t hash) const -{ - _OPEN_HASH_TABLE_ASSERT(fElementVector); - hash %= fArraySize; - if (fHashArray[hash] < 0) - return 0; - - return &fElementVector->At(fHashArray[hash]); -} - -template<class Element, class ElementVec> -int32_t -OpenHashTable<Element, ElementVec>::ElementIndex(const Element *element) const -{ - return fElementVector->IndexOf(*element); -} - -template<class Element, class ElementVec> -Element * -OpenHashTable<Element, ElementVec>::ElementAt(int32_t index) const -{ - return &fElementVector->At(index); -} - -template<class Element, class ElementVec> -int32_t -OpenHashTable<Element, ElementVec>::ArraySize() const -{ - return fArraySize; -} - -template<class Element, class ElementVec> -int32_t -OpenHashTable<Element, ElementVec>::VectorSize() const -{ - return fElementVector->Size(); -} - -template<class Element, class ElementVec> -int32_t -OpenHashTable<Element, ElementVec>::CountElements() const -{ - return fElementCount; -} - - -template<class Element, class ElementVec> -Element * -OpenHashTable<Element, ElementVec>::Add(uint32_t hash) -{ - _OPEN_HASH_TABLE_ASSERT(fElementVector); - _RehashIfNeeded(); - hash %= fArraySize; - Element *result = fElementVector->Add(); - if (result) { - result->fNext = fHashArray[hash]; - fHashArray[hash] = fElementVector->IndexOf(*result); - fElementCount++; - } - return result; -} - -template<class Element, class ElementVec> -void -OpenHashTable<Element, ElementVec>::Remove(Element *element, bool dontRehash) -{ - if (!dontRehash) - _RehashIfNeeded(); - uint32_t hash = element->Hash() % fArraySize; - int32_t next = fHashArray[hash]; - _OPEN_HASH_TABLE_ASSERT(next >= 0); - - if (&fElementVector->At(next) == element) { - fHashArray[hash] = element->fNext; - fElementVector->Remove(next); - fElementCount--; - return; - } - - for (int32_t index = next; index >= 0; ) { - // look for an existing match in table - next = fElementVector->At(index).fNext; - if (next < 0) { - _OPEN_HASH_TABLE_TRESPASS(); - return; - } - - if (&fElementVector->At(next) == element) { - fElementVector->At(index).fNext = element->fNext; - fElementVector->Remove(next); - fElementCount--; - return; - } - index = next; - } -} - -template<class Element, class ElementVec> -void -OpenHashTable<Element, ElementVec>::RemoveAll() -{ - for (int32_t i = 0; fElementCount > 0 && i < fArraySize; i++) { - int32_t index = fHashArray[i]; - while (index >= 0) { - Element* element = &fElementVector->At(index); - int32_t next = element->fNext; - fElementVector->Remove(index); - fElementCount--; - index = next; - } - fHashArray[i] = -1; - } - _RehashIfNeeded(); -} - -template<class Element, class ElementVec> -void -OpenHashTable<Element, ElementVec>::SetElementVector(ElementVec *elementVector) -{ - fElementVector = elementVector; -} - -// _RehashIfNeeded -template<class Element, class ElementVec> -bool -OpenHashTable<Element, ElementVec>::_RehashIfNeeded() -{ - // The load factor range [fMaxLoadFactor / 3, fMaxLoadFactor] is fine, - // I think. After rehashing the load factor will be about - // fMaxLoadFactor * 2 / 3, respectively fMaxLoadFactor / 2. - float loadFactor = (float)fElementCount / (float)fArraySize; - if (loadFactor > fMaxLoadFactor - || (fArraySize > fInitialSize && loadFactor < fMaxLoadFactor / 3)) { - return _Rehash(); - } - return true; -} - -// _Rehash -template<class Element, class ElementVec> -bool -OpenHashTable<Element, ElementVec>::_Rehash() -{ - bool result = true; - int32_t newSize = int32_t(fElementCount * 1.73 * fMaxLoadFactor); - newSize = (fInitialSize > newSize ? fInitialSize : newSize); - if (newSize != fArraySize) { - // allocate a new array - int32_t *newHashArray = (int32_t*)calloc(newSize, sizeof(int32_t)); - if (newHashArray) { - // init the new hash array - for (int32_t index = 0; index < newSize; index++) - newHashArray[index] = -1; - // iterate through all elements and put them into the new - // hash array - for (int i = 0; i < fArraySize; i++) { - int32_t index = fHashArray[i]; - while (index >= 0) { - // insert the element in the new array - Element &element = fElementVector->At(index); - int32_t next = element.fNext; - uint32_t hash = (element.Hash() % newSize); - element.fNext = newHashArray[hash]; - newHashArray[hash] = index; - // next element in old list - index = next; - } - } - // delete the old array and set the new one - free(fHashArray); - fHashArray = newHashArray; - fArraySize = newSize; - } else - result = false; - } - return result; -} - - -template<class Element> -OpenHashElementArray<Element>::OpenHashElementArray(int32_t initialSize) - : fSize(initialSize), - fNextFree(0), - fNextDeleted(-1) -{ - fData = (Element*)calloc((size_t)initialSize, sizeof(Element)); -} - -template<class Element> -OpenHashElementArray<Element>::~OpenHashElementArray() -{ - free(fData); -} - -template<class Element> -bool -OpenHashElementArray<Element>::InitCheck() const -{ - return fData; -} - -template<class Element> -Element & -OpenHashElementArray<Element>::At(int32_t index) -{ - _OPEN_HASH_TABLE_ASSERT(index < fSize); - return fData[index]; -} - -template<class Element> -const Element & -OpenHashElementArray<Element>::At(int32_t index) const -{ - _OPEN_HASH_TABLE_ASSERT(index < fSize); - return fData[index]; -} - -template<class Element> -int32_t -OpenHashElementArray<Element>::IndexOf(const Element &element) const -{ - int32_t result = &element - fData; - if (result < 0 || result > fSize) - return -1; - - return result; -} - -template<class Element> -int32_t -OpenHashElementArray<Element>::Size() const -{ - return fSize; -} - - -template<class Element> -Element * -OpenHashElementArray<Element>::Add(const Element &newElement) -{ - Element *element = Add(); - if (element) - element->Adopt(newElement); - return element; -} - -#if DEBUG -const int32_t kGrowChunk = 10; -#else -const int32_t kGrowChunk = 1024; -#endif - -template<class Element> -Element * -OpenHashElementArray<Element>::Add() -{ - int32_t index = fNextFree; - if (fNextDeleted >= 0) { - index = fNextDeleted; - fNextDeleted = At(index).fNext; - } else if (fNextFree >= fSize - 1) { - int32_t newSize = fSize + kGrowChunk; -/* - Element *newData = (Element *)calloc((size_t)newSize , sizeof(Element)); - if (!newData) - return NULL; - memcpy(newData, fData, fSize * sizeof(Element)); - free(fData); -*/ - Element *newData = (Element*)realloc(fData, - (size_t)newSize * sizeof(Element)); - if (!newData) - return NULL; - - fData = newData; - fSize = newSize; - index = fNextFree; - fNextFree++; - } else - fNextFree++; - - new (&At(index)) Element; - // call placement new to initialize the element properly - _OPEN_HASH_TABLE_ASSERT(At(index).fNext == -1); - - return &At(index); -} - -template<class Element> -void -OpenHashElementArray<Element>::Remove(int32_t index) -{ - // delete by chaining empty elements in a single linked - // list, reusing the next field - _OPEN_HASH_TABLE_ASSERT(index < fSize); - At(index).~Element(); - // call the destructor explicitly to destroy the element - // properly - At(index).fNext = fNextDeleted; - fNextDeleted = index; -} - -} // namespace FSShell - -using FSShell::OpenHashTable; - -#endif // __OPEN_HASH_TABLE__ diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h index 92c6240..2338ba7 100644 --- a/headers/private/fs_shell/fssh_api_wrapper.h +++ b/headers/private/fs_shell/fssh_api_wrapper.h @@ -42,7 +42,6 @@ #include "fssh_types.h" #include "DoublyLinkedList.h" -#include "HashMap.h" #include "SinglyLinkedList.h" #include "Stack.h" ############################################################################ Commit: 99c8c01df9c32586ba7b8c2b98e5cd29690c3adc Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Aug 8 15:27:29 2012 UTC Update vnid in entry_cache (needs work) This is probably a temporary solution so I don't have to worry about bugs introduced by the vnode remapping. ---------------------------------------------------------------------------- diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index 4e756e9..430e4fc 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -322,7 +322,8 @@ extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID); extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID, bool* _removed); extern status_t mark_vnode_busy(fs_volume* volume, ino_t vnodeID, bool busy); -extern status_t change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID); +extern status_t change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID, + ino_t dirID, const char* name); extern fs_volume* volume_for_vnode(fs_vnode* vnode); extern status_t read_pages(int fd, off_t pos, const struct iovec* vecs, diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index cb9483f..dcd7e01 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -143,8 +143,17 @@ ResizeVisitor::VisitInode(Inode* inode, const char* treeName) return status; } + // temporary ugliness + char realNameBuffer[B_FILE_NAME_LENGTH]; + const char* realName = realNameBuffer; + if (inode->GetName(realNameBuffer) < B_OK) + realName = NULL; + + ino_t parentDir = GetVolume()->ToBlock(inode->Parent()); + // will be ignored if realName == NULL + status = change_vnode_id(GetVolume()->FSVolume(), oldInodeID, - newInodeID); + newInodeID, parentDir, realName); if (status != B_OK) { mark_vnode_busy(GetVolume()->FSVolume(), inode->ID(), false); FATAL(("Resize: Failed to change ID in vnode, inode %" B_PRIdINO diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 3a6295c..9a2db61 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -3890,7 +3890,8 @@ mark_vnode_busy(fs_volume* volume, ino_t vnodeID, bool busy) extern "C" status_t -change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID) +change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID, ino_t dirID, + const char* name) { WriteLocker locker(sVnodeLock); @@ -3898,6 +3899,15 @@ change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID) if (vnode == NULL) return B_ENTRY_NOT_FOUND; + if (name != NULL) { + status_t status = vnode->mount->entry_cache.Remove(dirID, name); + if (status == B_OK) + status = vnode->mount->entry_cache.Add(dirID, name, newID); + + if (status != B_OK && status != B_ENTRY_NOT_FOUND) + return status; + } + hash_remove(sVnodeTable, vnode); vnode->id = newID; hash_insert(sVnodeTable, vnode); ############################################################################ Commit: 51347bb6d4accd65af18c8ccba287239bf5eb7d0 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 9 20:10:33 2012 UTC The index root requires some special handling ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp index a2a759d..dbf5acf 100644 --- a/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/FileSystemVisitor.cpp @@ -165,6 +165,34 @@ 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 fa02dde..abb4ac0 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -57,6 +57,8 @@ 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 dcd7e01..dc8999b 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -361,11 +361,28 @@ ResizeVisitor::_UpdateParent(Transaction& transaction, Inode* inode, off_t newInodeID, const char* treeName) { // get Inode of parent - Vnode parentVnode(GetVolume(), inode->Parent()); + Vnode parentVnode; Inode* parent; - status_t status = parentVnode.Get(&parent); - if (status != B_OK) - return status; + 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; + } 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 9a06eed..1198457 100644 --- a/src/add-ons/kernel/file_systems/bfs/Utility.h +++ b/src/add-ons/kernel/file_systems/bfs/Utility.h @@ -125,6 +125,13 @@ 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: d6eb1f409f21c20898ae1db77da408e89304ac26 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 9 20:12:25 2012 UTC Fix bugs when moving deleted inodes ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index dc8999b..56a3891 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -641,7 +641,7 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) if (status != B_OK) RETURN_ERROR(status); - if (!rootOrIndexDir) { + if (!rootOrIndexDir && !inode->IsDeleted()) { status = _UpdateParent(transaction, inode, newInodeID, treeName); if (status != B_OK) RETURN_ERROR(status); @@ -654,10 +654,12 @@ ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) RETURN_ERROR(status); } - status = _UpdateIndexReferences(transaction, inode, newInodeID, - rootOrIndexDir); - if (status != B_OK) - RETURN_ERROR(status); + if (!inode->IsDeleted()) { + status = _UpdateIndexReferences(transaction, inode, newInodeID, + rootOrIndexDir); + if (status != B_OK) + RETURN_ERROR(status); + } // update "." and ".." tree entries if we are a directory if (inode->IsDirectory()) { ############################################################################ Commit: 92f44a35f1d902a27a9d3351acffbc41b1f276bc Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 9 20:12:51 2012 UTC Change locking of moved inode to prevent deadlocks ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp index 56a3891..263df0e 100644 --- a/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/ResizeVisitor.cpp @@ -121,8 +121,6 @@ ResizeVisitor::VisitInode(Inode* inode, const char* treeName) } else strcpy(name, treeName); - WriteLocker writeLocker(inode->Lock()); - status_t status; off_t inodeBlock = inode->BlockNumber(); @@ -623,6 +621,7 @@ status_t ResizeVisitor::_MoveInode(Inode* inode, off_t& newInodeID, const char* treeName) { Transaction transaction(GetVolume(), 0); + inode->WriteLockInTransaction(transaction); bool rootOrIndexDir = inode->BlockRun() == inode->Parent(); ############################################################################ Commit: 317e139b1f6c7a73022bda9cd744e3e131884168 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Wed Aug 8 19:13:50 2012 UTC Pointer star style cleanup in devfs.h No functional change. ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/fs/devfs.h b/headers/private/kernel/fs/devfs.h index 6968da2..7349466 100644 --- a/headers/private/kernel/fs/devfs.h +++ b/headers/private/kernel/fs/devfs.h @@ -16,18 +16,18 @@ extern "C" { #endif -status_t devfs_unpublish_file_device(const char *path); -status_t devfs_publish_file_device(const char *path, const char *filePath); - -status_t devfs_unpublish_partition(const char *path); -status_t devfs_publish_partition(const char *name, const partition_info *info); -status_t devfs_rename_partition(const char *devicePath, const char *oldName, - const char *newName); - -status_t devfs_unpublish_device(const char *path, bool disconnect); -status_t devfs_publish_device(const char *path, device_hooks *calls); -status_t devfs_publish_directory(const char *path); -status_t devfs_rescan_driver(const char *driverName); +status_t devfs_unpublish_file_device(const char* path); +status_t devfs_publish_file_device(const char* path, const char* filePath); + +status_t devfs_unpublish_partition(const char* path); +status_t devfs_publish_partition(const char* name, const partition_info* info); +status_t devfs_rename_partition(const char* devicePath, const char* oldName, + const char* newName); + +status_t devfs_unpublish_device(const char* path, bool disconnect); +status_t devfs_publish_device(const char* path, device_hooks* calls); +status_t devfs_publish_directory(const char* path); +status_t devfs_rescan_driver(const char* driverName); #ifdef __cplusplus } ############################################################################ Commit: f3c952c6ec1ebad68fbce1f4b0f0e3fc2d7475b3 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 9 20:18:54 2012 UTC Change devfs device size ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/disk_device_manager/KPartition.h b/headers/private/kernel/disk_device_manager/KPartition.h index 7ff04da..282d4aa 100644 --- a/headers/private/kernel/disk_device_manager/KPartition.h +++ b/headers/private/kernel/disk_device_manager/KPartition.h @@ -49,6 +49,7 @@ public: virtual status_t PublishDevice(); virtual status_t UnpublishDevice(); virtual status_t RepublishDevice(); + virtual status_t ResizeDevice(off_t size); bool IsPublished() const; void SetBusy(bool busy); diff --git a/headers/private/kernel/fs/devfs.h b/headers/private/kernel/fs/devfs.h index 7349466..f741fa8 100644 --- a/headers/private/kernel/fs/devfs.h +++ b/headers/private/kernel/fs/devfs.h @@ -23,6 +23,7 @@ status_t devfs_unpublish_partition(const char* path); status_t devfs_publish_partition(const char* name, const partition_info* info); status_t devfs_rename_partition(const char* devicePath, const char* oldName, const char* newName); +status_t devfs_resize_partition(const char* path, off_t size); status_t devfs_unpublish_device(const char* path, bool disconnect); status_t devfs_publish_device(const char* path, device_hooks* calls); diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index a1e0411..225ce7f 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -2152,6 +2152,21 @@ devfs_rename_partition(const char* devicePath, const char* oldName, extern "C" status_t +devfs_resize_partition(const char* path, off_t size) +{ + devfs_vnode* device; + status_t status = get_node_for_path(sDeviceFileSystem, path, &device); + if (status != B_OK) + return status; + + device->stream.u.dev.partition->info.size = size; + notify_stat_changed(sDeviceFileSystem->id, device->parent->id, B_STAT_SIZE); + + return B_OK; +} + + +extern "C" status_t devfs_publish_directory(const char* path) { RecursiveLocker locker(&sDeviceFileSystem->lock); diff --git a/src/system/kernel/disk_device_manager/KPartition.cpp b/src/system/kernel/disk_device_manager/KPartition.cpp index aa60d95..6982bd6 100644 --- a/src/system/kernel/disk_device_manager/KPartition.cpp +++ b/src/system/kernel/disk_device_manager/KPartition.cpp @@ -296,6 +296,32 @@ KPartition::RepublishDevice() } +status_t +KPartition::ResizeDevice(off_t size) +{ + if (!fPublishedName) + return B_OK; + + // get the path + KPath path; + status_t error = GetPath(&path); + if (error != B_OK) { + dprintf("KPartition::ResizeDevice(): Failed to get path for " + "partition %ld: %s\n", ID(), strerror(error)); + return error; + } + + error = devfs_resize_partition(path.Path(), size); + if (error != B_OK) { + dprintf("KPartition::ResizeDevice(): Failed to resize partition " + "%ld: %s\n", ID(), strerror(error)); + return error; + } + + return B_OK; +} + + bool KPartition::IsPublished() const { diff --git a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp index 790028e..7bab0cb 100644 --- a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp +++ b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp @@ -152,15 +152,29 @@ KPartitioningSystem::Resize(KPartition* partition, off_t size, disk_job_id job) if (!fModule->resize) return B_NOT_SUPPORTED; + status_t result; + bool growing = size > partition->Size(); + + // resize device first if growing + if (growing) { + result = partition->ResizeDevice(size); + if (result != B_OK) + return result; + } + // open partition device int fd = -1; - status_t result = partition->Open(O_RDWR, &fd); + result = partition->Open(O_RDWR, &fd); if (result != B_OK) return result; // let the module do its job result = fModule->resize(fd, partition->ID(), size, job); + // resize device last if shrinking + if (result == B_OK && !growing) + result = partition->ResizeDevice(size); + // cleanup and return close(fd); return result; @@ -178,15 +192,29 @@ KPartitioningSystem::ResizeChild(KPartition* child, off_t size, disk_job_id job) if (!fModule->resize_child) return B_NOT_SUPPORTED; + status_t result; + bool growing = size > child->Size(); + + // resize device first if growing + if (growing) { + result = child->ResizeDevice(size); + if (result != B_OK) + return result; + } + // open partition device int fd = -1; - status_t result = child->Parent()->Open(O_RDWR, &fd); + result = child->Parent()->Open(O_RDWR, &fd); if (result != B_OK) return result; // let the module do its job result = fModule->resize_child(fd, child->ID(), size, job); + // resize device last if shrinking + if (result == B_OK && !growing) + result = child->ResizeDevice(size); + // cleanup and return close(fd); return result; ############################################################################ Commit: 86611e9a7098570ddafc97c278341dc39e65e8d6 Author: ahenriksson <sausageboy@xxxxxxxxx> Date: Thu Aug 9 20:20:06 2012 UTC Change size of the KPartition ---------------------------------------------------------------------------- diff --git a/src/system/kernel/disk_device_manager/KFileSystem.cpp b/src/system/kernel/disk_device_manager/KFileSystem.cpp index cba020c..252753f 100644 --- a/src/system/kernel/disk_device_manager/KFileSystem.cpp +++ b/src/system/kernel/disk_device_manager/KFileSystem.cpp @@ -139,6 +139,9 @@ KFileSystem::Resize(KPartition* partition, off_t size, disk_job_id job) result = fModule->resize(fd, partition->ID(), size, job); + if (result == B_OK) + partition->SetContentSize(size); + close(fd); return result; } diff --git a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp index 7bab0cb..6755dea 100644 --- a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp +++ b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp @@ -211,6 +211,9 @@ KPartitioningSystem::ResizeChild(KPartition* child, off_t size, disk_job_id job) // let the module do its job result = fModule->resize_child(fd, child->ID(), size, job); + if (result == B_OK) + child->SetSize(size); + // resize device last if shrinking if (result == B_OK && !growing) result = child->ResizeDevice(size);