diff --git a/sortix/mxfs.cpp b/sortix/mxfs.cpp deleted file mode 100644 index 39542a88..00000000 --- a/sortix/mxfs.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/****************************************************************************** - - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. - - This file is part of Sortix. - - Sortix is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Sortix is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . - - mxfs.cpp - A working file system. - -******************************************************************************/ - -#include "platform.h" -#include -#include "mxfs.h" -#include "mount.h" - -using namespace Maxsi; - -namespace Sortix -{ - const size_t blockSize = 4096; - - #define FAIL() Failure(); return; - #define PENDING (Error::Last() != Error::PENDING) - #define ALRIGHT ( _storageStatus == Error::SUCCESS || _storageStatus == Error::PENDING || _storageStatus == Error::NONE ) - - class MXFSNode - { - public: - MXFSNode(); - ~MXFSNode(); - - public: - const char* name; - MXFSNode* prevSibling; - MXFSNode* nextSibling; - MXFSNode* child; - MXFSNode* parent; - - public: - inline bool IsDir() { type == 2; } - - public: - inline bool MatchesNameToken(const char* actual, const char* request, size_t requestLength) - { - return ( String::CompareN(actual, request, requestLength) == 0 ) && ( actual[requestLength] == '\0' ); - } - - MXFSNode* Search(const char* path) - { - ASSERT(IsDir()); - - // Search for the end of the next name token in path. - size_t nameLen = 0; const char* postToken = path; - while ( *postToken != '/' || *postToken != '\0' ) { postToken++; nameLen++; } - // Path must already have been sanitized, where all double slashes - // have been gracefully reduced to single slashes. - ASSERT(nameLen > 0); - - // Search for the next name token in path in this directory. - for ( MXFSNode* current = child; current != NULL; current = current->nextSibling ) - { - // Check if we have a match. - if ( unlikely(MatchesNameToken(current->name, path, nameLen)) ) - { - // Was this node exactly what we requested? - if ( *postToken == '\0' ) { return current; } - - // Was a directory requested? - if ( *postToken == '/' && *(postToken+1) == '\0' ) - { - if ( current->IsDir() ) { return current; } else { Error::Set(Error::NOTDIR); return NULL; } - } - - // Get the next token. - const char* nextTokenStart = path + nameLen + 1; ASSERT(*nextTokeBegin != '\0'); - - // Alright, search the child directory. - return Search(current->child, nextTokenStart); - } - } - - Error::Set(Error::NOTFOUND); - return NULL; - } - - public: - nat type; - uint32_t type; - int32_t owner; - int32_t group; - uint32_t permissions; - uint64_t length; - uint64_t blockId; - uint64_t siblingBlockId; // should only be used for recursive travelling. - - }; - - MXFSNode::MXFSNode() - { - name = NULL; - prevSibling = NULL; - nextSibling = NULL; - parent = NULL; - child = NULL; - type = 0; - owner = 0; - group = 0; - permissions = 0; - length = 0; - blockId = 0; - siblingBlockId = 0; - } - - MXFSNode::MXFSNode() - { - // If nextSibling exists, then we are called from his destructor. - // If parent exists, then we are called from his destructor. - delete[] name; - delete child; - delete nextSibling; - } - - struct MXFSHeader - { - uint32_t magic; - uint32_t version; - uint64_t size; - uint64_t root; - uint64_t unusedBlock; - uint8_t unused[blockSize - (32 + 64 + 64 + 64) / 8]; - } SORTIX_PACKED; - - struct MXFSNodeHeader - { - const uint32_t FILE = 1; - const uint32_t DIR = 2; - - uint32_t magic; - uint32_t type; - uint64_t prevNode; - uint64_t nextNode; - int32_t owner; - int32_t group; - uint32_t permissions; - uint64_t length; - uint64_t nextBlock; - uint32_t continuous; - uint8_t nameLen; - char name[255]; - union - { - struct - { - uint64_t child; - }; - uint8_t data[blockSize - (32 + 32 +32 + 32 + 32 + 64 + 64 + 32) / 8 - 256]; - }; - } SORTIX_PACKED; - - struct MXFSBlock - { - uint64_t node; - uint64_t lastBlock; - uint32_t lastBlockContinuous; - uint64_t nextBlock; - uint32_t continuous; - uint8_t data[blockSize - (64 + 64 + 32 + 64 + 32) / 8]; - } SORTIX_PACKED; - - struct MXFSBlockContinuous - { - uint32_t data[4096]; - } SORTIX_PACKED; - - DevMXFS::DevMXFS() - { - ASSERT( sizeof(MXFSHeader) == blockSize ); - ASSERT( sizeof(MXFSNodeHeader) == blockSize ); - ASSERT( sizeof(MXFSBlock) == blockSize ); - ASSERT( sizeof(MXFSBlockContinuous) == blockSize ); - - _storage = NULL; - _children = NULL; - _mountPoint = NULL; - _block = NULL; - _state = 0; - _root = NULL; - - _storageStatus = Error::NONE; - } - - DevMXFS::~DevMXFS() - { - DevMXFSFile* child = _children; - - while ( child ) - { - child->_parent = NULL; - child = child->nextSibling; - } - - delete[] _block; - delete _root; - - Mount::OnMountFailure(_mountPoint, Error::SUCCESS); - } - - int DevMXFS::Initialize(MountPoint* mountPoint, const char* /*commandLine*/) - { - _block = new uint8_t[blockSize]; - if ( _block == NULL ) { return Error::OUTOFMEM); } - - ASSERT(_storage == NULL); - ASSERT(_mountPoint == NULL); - - _storage = mountPoint->device; - _mountPoint = mountPoint; - - ASSERT(_storage != NULL); - ASSERT(_mountPoint != NULL); - ASSERT(_mountPoint->fs == this); - - requestThink(); - - return Error::PENDING; - } - - uint8_t* DevMXFS::GetBlock(intmax_t blockId) - { - ASSERT( _storageStatus != Error::PENDING || _blockId == blockId ); - - if ( _blockId == blockId ) - { - if ( _storageStatus == Error::SUCCESS ) { return _block; } else { return NULL; } - } - - if ( !_storage->seek(blockId * blockSize) ) { Failure(Error::Last()); } - if ( _storage->read(block, blockSize) == SIZE_MAX ) - { - if ( PENDING ) { return NULL; } else { Failure(Error::Last()); } - } - - return _block; - } - - MXFSNode* DevMXFS::Search(const char* path); - { - if ( unlikely(_storage == NULL) ) { Error::Set(_storageStatus); return NULL; } - ASSERT(_root != NULL); - - // If the root was requested, return it. - if ( *path != '/' ) { Error::Set(Error::NOTFOUND); return NULL; } - if ( *(path+1) == '\0' ) { return _root; } path++; - - return _root->Search(path+1); - } - - void DevMXFS::Think() - { - if ( !_mountPoint ) { return; } - if ( !ALRIGHT ) { FAIL(); } - - // Initialize the filesystem by reading the headers. - if ( _state == 0 ) - { - if ( !ParseHeader ) { return; } - - // The super block looks good, so far. - _state++; - } - - // Load the tree of files and directories. - if ( _state == 1 ) - { - if ( !ParseBlocks() ) { return; } - - // Alright, we now got the tree of everything loaded! - if ( parsingBlock == 0 ) { _state++; } - } - - // Let the mounting system know we are up and running. - if ( _state == 2 ) - { - Mount::OnMountSuccess(_mountPoint); _state++; - } - - // Alright, now handle requests from various file devices. - if ( _state == 3) - { - - } - } - - - bool DevMXFS::ParseHeader() - { - // Get the super block and read the filesystem's headers. - MXFSHeader* fsHeader = (MXFSHeader*) getBlock(0); if ( !fsHeader ) { return false; } - - // Validate that we are dealing with a MXFS. - if ( MXFSHeader->magic != 'M' << 24 | 'X' << 16 | 'F' << 8 | 'S' ) { Failure(Error::BADINPUT); return false; } - - // Retrieve and validate the size of the file system. - if ( _storage.size() < MXFSHeader->size ) { Failure(Error::CORRUPT); return false; } - - // Validate the existence of the root directory. - if ( MXFSHeader->root == 0 ) { Failure(Error::CORRUPT); return false; } - _parsingBlock = MXFSHeader->root; - - // Validate the existence of the root directory. - if ( MXFSHeader->version != 0 ) { Failure(Error::NOSUPPORT); return false;} - - return true; - } - - bool DevMXFS::ParseBlocks() - { - while ( _parsingBlock != 0 ) - { - MXFSNodeHeader* nodeHeader = (MXFSHeader*) getBlock(_parsingBlock); if ( !nodeHeader ) { return false; } - - // Validate that we are dealing with a node header. - if ( MXFSHeader->magic != 'N' << 24 | 'O' << 16 | 'D' << 8 | 'E' ) { Failure(Error::CORRUPT); return false; } - - // Create a node we can put in your FS tree. - MXFSNode* node = new MXFSNode(); - if ( !node ) { Failure(Error::Last()); return false; } - - // Copy information from the header to our tree node. - // TODO: copy other header information. - node->type = nodeHeader->type; - - // Figure out where to insert our node. - if ( unlikely(_root == NULL) ) - { - _root = node; - - // Make sure the root is a directory without siblings. - if ( !MXFSHeader->type == MXFSNodeHeader::DIR ) { Failure(Error::CORRUPT); return false; } - if ( !MXFSHeader->nextNode != 0 ) { Failure(Error::CORRUPT); return false; } - - // Now visit its children. - _parsingBlock = MXFSHeader->child; - _parsingLastNode = NULL; - _parsingParent = node; - } - else - { - // Insert the node in our tree. - if ( _parsingLastNode ) - { - _parsingLastNode->nextSibling = node; - node->prevSibling = _parsingLastNode; - } - - if ( _parsingParent->child == NULL ) { _parsingParent->child = node; } - node->parent = _parsingParent; - - // Retrieve a copy of the new nodes name and validate it. - node->name = new char[nodeHeader->nameLen + 1]; - if ( !node->name ) { Failure(Error::Last()); return false; } - Memory::Copy(node->name, nodeHeader->name, nodeHeader->nameLen); - node->name[nodeHeader->nameLen] = 0; - if ( !legalNodeName ) { Failure(Error::CORRUPT); return false; } - - // If node is a directory, visit its children. - if ( MXFSHeader->type == MXFSNodeHeader::DIR && MXFSHeader->child != 0 ) - { - _parsingLastNode = NULL; - _parsingParent = node; - _parsingBlock = MXFSHeader->child; - node->siblingBlockId = node->nextNode; - - continue; - } - - // If it exists, visit the next node in this directory. - if ( nodeHeader->nextNode != 0 ) - { - _parsingBlock = nodeHeader->nextNode; - _parsingLastNode = node; - - continue; - } - - // If we reached the end of a directory, simply continue from - // the parent directory, until we reached the root or we found - // an unfinished directory. - while ( true ) - { - node = node->parent; - if ( unlikely(node == NULL) ) { _parsingBlock = 0; break; } - if ( node->siblingBlockId != 0 ) { _parsingBlock = siblingBlockId; _parsingParent = node->parent; _parsingLastNode = node->prevSibling; break; } - } - } - } - - return true; - } - - void DevMXFS::Failure(int cause = Error::SUCCESS) - { - if ( cause != Error::SUCCESS ) { _storageStatus = cause; } - Mount::OnMountFailure(_mountPoint, _storageStatus); - - _mountPoint = NULL; - _storage = NULL; - delete[] _block; _block = NULL; - } - - Device* DevMXFS::Open(const char* path, nat flags, nat permissions, nat* type) - { - - } -} diff --git a/sortix/mxfs.h b/sortix/mxfs.h deleted file mode 100644 index 2ea2ef59..00000000 --- a/sortix/mxfs.h +++ /dev/null @@ -1,118 +0,0 @@ -/****************************************************************************** - - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. - - This file is part of Sortix. - - Sortix is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Sortix is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . - - mxfs.h - A working file system. - -******************************************************************************/ - -#ifndef SORTIX_MXFS_H -#define SORTIX_MXFS_H - -#include "stream.h" -#include "filesystem.h" - -namespace Sortix -{ - class DevMXFS; - class DevMXFSFile; - class MXFSNode; - - class DevMXFSFile : public DevBuffer - { - friend class DevMXFS; - - private: - DevMXFSFile* _prevSibling; - DevMXFSFile* _nextSibling; - - private: - DevMXFS* _parent; - - private: - intmax_t _beginning; - intmax_t _size; - - public: - virtual size_t Write(const void* buffer, size_t bufferSize) = 0; - virtual size_t ReadSome(const void* buffer, size_t bufferSize) = 0; - - public: - virtual size_t BlockSize() = 0; - virtual intmax_t Size() = 0; - virtual intmax_t Position() = 0; - virtual bool Seek(intmax_t position) = 0; - virtual bool Resize(intmax_t size) = 0; - - }; - - class DevMXFS : public DevFileSystem - { - friend class DevMXFSFile; - - public: - DevMXFS(); - virtual ~DevMXFS(); - - public: - virtual int Initialize(MountPoint* mountPoint, const char* commandLine); - - private: - MountPoint* _mountPoint; - DevBuffer* _storage; - DevMXFSFile* _children; - MXFSNode* _root; - - private: - nat _state; - uint64_t _parsingBlock; - MXFSNode* _parsingLastNode; - MXFSNode* _parsingParent; - - private: - volatile int _storageStatus; - intmax_t _blockId; - uint8_t* _block; - intmax_t _fsSize; - - private: - uint8_t* GetBlock(intmax_t blockId); - - private: - bool ParseHeader(); - bool ParseBlocks(); - void Failure(); - - private: - MXFSNode* Search(const char* path); - - protected: - virtual void Think(); - - public: - virtual bool Sync(); - - public: - virtual Device* Open(const char* path, nat flags, nat permissions, nat* type); - - }; -} - -#endif -