Author: nieklinnenbank Date: Wed Jul 8 15:47:03 2009 New Revision: 216 Added: trunk/srv/filesystem/linn/LinnDirectory.cpp trunk/srv/filesystem/linn/LinnDirectory.h trunk/srv/filesystem/linn/LinnFile.cpp trunk/srv/filesystem/linn/LinnFile.h trunk/srv/filesystem/linn/LinnFileSystem.cpp trunk/srv/filesystem/linn/LinnFileSystem.h Modified: trunk/srv/filesystem/linn/LinnCreate.cpp trunk/srv/filesystem/linn/LinnDirectoryEntry.h trunk/srv/filesystem/linn/SConscript Log: Added initial implementation of the LinnFS filesystem server. Modified: trunk/srv/filesystem/linn/LinnCreate.cpp ============================================================================== --- trunk/srv/filesystem/linn/LinnCreate.cpp (original) +++ trunk/srv/filesystem/linn/LinnCreate.cpp Wed Jul 8 15:47:03 2009 @@ -287,9 +287,8 @@ /* Fill it. */ entry->inode = entryInode; entry->type = type; - memcpy(entry->name, name, - strlen(name) < LINN_DIRENT_NAME_LEN ? - strlen(name) : LINN_DIRENT_NAME_LEN); + strncpy(entry->name, name, LINN_DIRENT_NAME_LEN); + entry->name[LINN_DIRENT_NAME_LEN - 1] = ZERO; } /* Indirect block. */ else Added: trunk/srv/filesystem/linn/LinnDirectory.cpp ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnDirectory.cpp Wed Jul 8 15:47:03 2009 @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <API/VMCopy.h> +#include "LinnDirectory.h" + +LinnDirectory::LinnDirectory(LinnFileSystem *f, + LinnInode *i) + : fs(f), inode(i) +{ + size = inode->size; +} + +Error LinnDirectory::read(FileSystemMessage *msg) +{ + LinnSuperBlock *sb = fs->getSuperBlock(); + LinnDirectoryEntry dent; + LinnInode *dInode; + Size bytes = ZERO; + Dirent tmp, *buf = (Dirent *) msg->buffer; + Error e; + + /* Loop all direct blocks. */ + for (u64 blk = 0; blk < LINN_INODE_DIR_BLOCKS; blk++) + { + /* Read directory entries. */ + for (u64 ent = 0; ent < LINN_DIRENT_PER_BLOCK(sb); ent++) + { + /* Calculate offset to read. */ + u64 offset = (inode->block[blk] * sb->blockSize) + + (ent * sizeof(LinnDirectoryEntry)); + + /* Get the next entry. */ + if (fs->getStorage()->read(offset, (u8 *) &dent, + sizeof(LinnDirectoryEntry)) < 0) + { + return EACCES; + } + /* Can we read another entry? */ + if (bytes + sizeof(Dirent) <= msg->size) + { + /* Fill in the Dirent. */ + if (!(dInode = fs->getInode(dent.inode))) + { + return EINVAL; + } + strlcpy(tmp.name, dent.name, LINN_DIRENT_NAME_LEN); + tmp.type = (FileType) dInode->type; + + /* Copy to the remote process. */ + if ((e = VMCopy(msg->procID, Write, (Address) &tmp, + (Address) (buf++), sizeof(Dirent))) < 0) + { + return e; + } + bytes += e; + } + /* No more buffer space left. */ + else return EFAULT; + } + } + /* All done. */ + msg->size = bytes; + return ESUCCESS; +} + +Error LinnDirectory::getEntry(LinnDirectoryEntry *dent, char *name) +{ + LinnSuperBlock *sb = fs->getSuperBlock(); + u64 offset; + + /* Loop all blocks. */ + for (u64 blk = 0; blk < LINN_INODE_NUM_BLOCKS(sb, inode); blk++) + { + /* Read directory entries. */ + for (u64 ent = 0; ent < LINN_DIRENT_PER_BLOCK(sb); ent++) + { + /* Calculate offset to read. */ + offset = (inode->block[blk] * sb->blockSize) + + (sizeof(LinnDirectoryEntry) * ent); + + /* Get the next entry. */ + if (fs->getStorage()->read(offset, (u8 *) dent, + sizeof(LinnDirectoryEntry)) < 0) + { + return EACCES; + } + /* Is it the entry we are looking for? */ + if (strcmp(name, dent->name) == 0) + { + return ESUCCESS; + } + } + } + /* Not found. */ + return ENOENT; +} Added: trunk/srv/filesystem/linn/LinnDirectory.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnDirectory.h Wed Jul 8 15:47:03 2009 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __FILESYSTEM_LINN_DIRECTORY_H +#define __FILESYSTEM_LINN_DIRECTORY_H +#ifndef __HOST__ + +#include <FileSystemMessage.h> +#include <Directory.h> +#include <Types.h> +#include <Error.h> +#include "LinnDirectoryEntry.h" +#include "LinnFileSystem.h" +#include "LinnInode.h" + +/** + * @defgroup linn Linnenbank Filesystem (LinnFS) + * @{ + */ + +/** + * Represents an directory on a LinnFS filesystem. + * @see Directory + * @see LinnDirectoryEntry + * @see LinnFileSystem + */ +class LinnDirectory : public Directory +{ + public: + + /** + * Constructor function. + * @param fs Filesystem pointer. + * @param inode Inode pointer. + * @see LinnFileSystem + * @see LinnInode + */ + LinnDirectory(LinnFileSystem *fs, LinnInode *inode); + + /** + * Read directory entries. + * @param msg Read request. + * @return Number of bytes read on success, Error on failure. + */ + Error read(FileSystemMessage *msg); + + /** + * Retrieve a directory entry. + * @param dent LinnDirectoryEntry buffer pointer. + * @param name Unique name of the entry. + * @return ESUCCESS if found, or an error code otherwise. + */ + Error getEntry(LinnDirectoryEntry *dent, char *name); + + private: + + /** Filesystem pointer. */ + LinnFileSystem *fs; + + /** Inode which describes the directory. */ + LinnInode *inode; +}; + +/** + * @} + */ + +#endif /* __HOST__ */ +#endif /* __FILESYSTEM_EXT2DIRECTORY_H */ Modified: trunk/srv/filesystem/linn/LinnDirectoryEntry.h ============================================================================== --- trunk/srv/filesystem/linn/LinnDirectoryEntry.h (original) +++ trunk/srv/filesystem/linn/LinnDirectoryEntry.h Wed Jul 8 15:47:03 2009 @@ -20,6 +20,18 @@ #include <Types.h> +/** + * @defgroup linn Linnenbank Filesystem (LinnFS) + * @{ + */ + +/** + * Calculates the number of LinnDirectoryEntry's fitting in one block. + * @return Number of entries. + */ +#define LINN_DIRENT_PER_BLOCK(sb) \ + ((sb)->blockSize / sizeof(LinnDirectoryEntry)) + /** Length of the name field in an directory entry. */ #define LINN_DIRENT_NAME_LEN 55 @@ -34,7 +46,7 @@ /** Type of file, as an FileType. */ u8 type; - /** File name. */ + /** File name. Null terminated. */ char name[LINN_DIRENT_NAME_LEN]; } LinnDirectoryEntry; Added: trunk/srv/filesystem/linn/LinnFile.cpp ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnFile.cpp Wed Jul 8 15:47:03 2009 @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <API/VMCopy.h> +#include "LinnFile.h" +#include <string.h> + +LinnFile::LinnFile(LinnFileSystem *f, LinnInode *i) + : fs(f), inode(i) +{ + size = inode->size; +} + +LinnFile::~LinnFile() +{ +} + +Error LinnFile::read(FileSystemMessage *msg) +{ + LinnSuperBlock *sb; + u8 *block, *buffer; + Size bytes = 0, total = 0, blockNr = 0; + u64 storageOffset, copyOffset = msg->offset; + Error e = ESUCCESS; + + /* Initialize variables. */ + sb = fs->getSuperBlock(); + block = new u8[sb->blockSize]; + buffer = (u8 *) msg->buffer; + + /* Skip ahead blocks. */ + while ((sb->blockSize * (blockNr + 1)) <= copyOffset) + { + blockNr++; + } + /* Adjust the copy offset within this block. */ + copyOffset -= sb->blockSize * blockNr; + + /* Loop all blocks. */ + while (blockNr < LINN_INODE_NUM_BLOCKS(sb, inode) - 1 && + total < msg->size && + inode->size - (msg->offset + total)) + { + /* Calculate the offset in storage for this block. */ + storageOffset = fs->getOffset(inode, blockNr); + + /* Fetch the next block. */+ if (fs->getStorage()->read(storageOffset, block, sb->blockSize) < 0)
+ { + e = EACCES; + break; + } + /* Calculate the number of bytes to copy. */ + bytes = sb->blockSize - copyOffset; + + /* Respect the inode size. */ + if (bytes > inode->size - (msg->offset + total)) + { + bytes = inode->size - (msg->offset + total); + } + /* Respect the remote process buffer. */ + if (bytes > msg->size - total) + { + bytes = msg->size - total; + } + /* Copy to the remote process. */ + if ((e = VMCopy(msg->procID, Write, + ((Address) (block)) + copyOffset, + (Address) (buffer), bytes)) < 0) + { + break; + } + /* Update state. */ + buffer += bytes; + total += bytes; + copyOffset = 0; + e = ESUCCESS; + blockNr++; + } + /* Success. */ + msg->size = total; + delete block; + return e; +} + +Error LinnFile::write(FileSystemMessage *msg) +{ + return ENOTSUP; +} Added: trunk/srv/filesystem/linn/LinnFile.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnFile.h Wed Jul 8 15:47:03 2009 @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __FILESYSTEM_LINN_FILE_H +#define __FILESYSTEM_LINN_FILE_H +#ifndef __HOST__ + +#include <File.h> +#include <FileSystemMessage.h> +#include <Types.h> +#include <Error.h> +#include "LinnFileSystem.h" +#include "LinnInode.h" + +/** + * @defgroup linn Linnenbank Filesystem (LinnFS) + * @{ + */ + +/** + * Represents a file on a mounted LinnFS filesystem. + */ +class LinnFile : public File +{ + public: + + /** + * Constructor function. + * @param fs LinnFS filesystem pointer. + * @param inode Inode pointer. + */ + LinnFile(LinnFileSystem *fs, LinnInode *inode); + + /** + * Destructor function. + */ + ~LinnFile(); + + /** + * Read out the file. + * @param msg Read request. + * @return Number of bytes read, or Error number. + */ + Error read(FileSystemMessage *msg); + + /** + * Write bytes to the file. + * @param msg Write request. + * @return Number of bytes written on success, Error on failure. + */ + Error write(FileSystemMessage *msg); + + private: + + /** Filesystem pointer. */ + LinnFileSystem *fs; + + /** Inode pointer. */ + LinnInode *inode; +}; + +/** + * @} + */ + +#endif /* __HOST__ */ +#endif /* __FILESYSTEM_LINN_FILE_H */ Added: trunk/srv/filesystem/linn/LinnFileSystem.cpp ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnFileSystem.cpp Wed Jul 8 15:47:03 2009 @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <Types.h> +#include <BootModule.h> +#include <Storage.h> +#include <LogMessage.h> +#include "LinnFileSystem.h" +#include "LinnInode.h" +#include "LinnFile.h" +#include "LinnDirectory.h" +#include <stdlib.h> + +int main(int argc, char **argv) +{ + BootModule module("/boot/boot.linn"); + + if (module.load()) + { + LinnFileSystem server("/mnt", &module); + return server.run(); + } + return EXIT_FAILURE; +} + +LinnFileSystem::LinnFileSystem(const char *p, Storage *s) + : FileSystem(p), storage(s), groups(ZERO) +{ + FileSystemPath slash("/"); + LinnInode *rootInode; + LinnGroup *group; + Size offset; + Error e; + + /* Read out the superblock. */ + if ((e = s->read(LINN_SUPER_OFFSET, (u8 *) &super, + sizeof(super))) <= 0) + { + log("LinnFS: reading superblock failed: %s", + strerror(e)); + exit(EXIT_FAILURE); + } + /* Verify magic. */ + if (super.magic0 != LINN_SUPER_MAGIC0 || + super.magic1 != LINN_SUPER_MAGIC1) + { + log("LinnFS: magic mismatch"); + exit(EXIT_FAILURE); + } + /* Create groups vector. */ + Size cnt = LINN_GROUP_COUNT(&super); + groups = new Array<LinnGroup>(cnt); + + /* Read out group descriptors. */ + for (le64 i = 0; i < LINN_GROUP_COUNT(&super); i++) + { + /* Allocate buffer. */ + group = new LinnGroup; + offset = (super.groupsTable * super.blockSize) + + (sizeof(LinnGroup) * i); + + /* Read from storage. */ + if ((e = s->read(offset, (u8 *) group, sizeof(LinnGroup))) <= 0) + { + log("LinnFS: reading group descriptor failed: %s", + strerror(e)); + exit(EXIT_FAILURE); + } + /* Insert in the groups vector. */ + groups->insert(i, group); + } + log("LinnFS: %d group descriptors", + LINN_GROUP_COUNT(&super)); + + /* Debug out superblock information. */ + log("LinnFS: %d inodes, %d blocks", + super.inodesCount - super.freeInodesCount, + super.blocksCount - super.freeBlocksCount); + + /* Read out the root directory. */ + rootInode = getInode(LINN_INODE_ROOT); + root = new FileCache(&slash, new LinnDirectory(this, rootInode), ZERO); + + /* Done. */ + log("LinnFS: mounted '%s'", p); +} + +Error LinnFileSystem::createFile(FileSystemMessage *msg, + FileSystemPath *path) +{ + return ENOTSUP; +} + +LinnInode * LinnFileSystem::getInode(u64 inodeNum) +{ + LinnGroup *group; + LinnInode *inode; + Size offset; + Error e; + Integer<u64> inodeInt = inodeNum; + + /* Validate the inode number. */ + if (inodeNum >= super.inodesCount) + { + return ZERO; + } + /* Do we have this Inode cached already? */ + if ((inode = inodes[&inodeInt])) + { + return inode; + } + /* Get the group descriptor. */ + if (!(group = getGroupByInode(inodeNum))) + { + return ZERO; + } + /* Allocate inode buffer. */ + inode = new LinnInode; + offset = (group->inodeTable * super.blockSize) + + (inodeNum % super.inodesPerGroup); + + /* Read inode from storage. */ + if ((e = storage->read(offset, (u8 *) inode, sizeof(LinnInode))) <= 0) + { + log("LinnFS: reading inode failed: %s", + strerror(e)); + return ZERO; + } + /* Insert into the cache. */ + inodes.insert(new Integer<u64>(inodeNum), inode); + return inode; +} + +LinnGroup * LinnFileSystem::getGroup(u64 groupNum) +{ + return (*groups)[groupNum]; +} + +LinnGroup * LinnFileSystem::getGroupByInode(u64 inodeNum) +{ + return getGroup((inodeNum - 1) / super.inodesPerGroup); +} + +u64 LinnFileSystem::getOffset(LinnInode *inode, u64 blk) +{ + u64 numPerBlock = LINN_SUPER_NUM_PTRS(&super), offset; + u64 *block = ZERO; + Size depth = ZERO; + + /* Direct blocks. */ + if (blk < LINN_INODE_DIR_BLOCKS) + { + return inode->block[blk] * super.blockSize; + } + /* Indirect blocks. */ + if (blk - LINN_INODE_DIR_BLOCKS < numPerBlock) + { + depth = 1; + } + /* Double indirect blocks. */ + else if (blk - LINN_INODE_DIR_BLOCKS < numPerBlock * numPerBlock) + { + depth = 2; + } + /* Tripple indirect blocks. */ + else + depth = 3; + + /* Allocate temporary block. */ + block = new u64[LINN_SUPER_NUM_PTRS(&super)]; + offset = inode->block[(LINN_INODE_DIR_BLOCKS + depth - 1)]; + offset *= super.blockSize; + + /* Lookup the block number. */ + while (depth > 0) + { + /* Fetch block. */ + if (storage->read(offset, (u8 *) block, super.blockSize) < 0) + { + delete block; + return 0; + } + /* Calculate the number of blocks remaining per entry. */ + Size remain = LINN_SUPER_NUM_PTRS(&super); + + /* Effectively the pow() function. */ + for (Size i = 0; i < depth - 1; i++) + { + remain *= remain; + } + /* Calculate the next offset. */ + offset = block[ remain / (blk - LINN_INODE_DIR_BLOCKS + 1) ]; + offset *= super.blockSize; + depth--; + } + /* Calculate the final offset. */ + offset = block[ (blk - LINN_INODE_DIR_BLOCKS) % + LINN_SUPER_NUM_PTRS(&super) ]; + offset *= super.blockSize; + + /* All done. */ + delete block; + return offset; +} + +FileCache * LinnFileSystem::lookupFile(FileSystemPath *path) +{ + List<String> *entries = path->split(); + FileCache *c = root; + LinnInode *inode; + LinnDirectoryEntry entry; + LinnDirectory *dir; + + /* Loop the entire path. */ + for (ListIterator<String> i(entries); i.hasNext(); i++) + { + /* Do we have this entry? */ + if (!c->entries[i.current()]) + { + /* If this isn't a directory, we cannot perform a lookup. */ + if (c->file->getType() != DirectoryFile) + { + return ZERO; + } + dir = (LinnDirectory *) c->file; + + /* Then retrieve it, if possible. */ + if (dir->getEntry(&entry, **i.current()) != ESUCCESS) + { + return ZERO; + } + /* Lookup corresponding inode. */ + if (!(inode = getInode(entry.inode))) + { + return ZERO; + } + /* Create the appropriate in-memory file. */ + switch ((FileType)inode->type) + { + case DirectoryFile: + c = insertFileCache(new LinnDirectory(this, inode), + **i.current()); + break; + + case RegularFile: + c = insertFileCache(new LinnFile(this, inode), + **i.current()); + break; + + default: + return ZERO; + } + } + /* Move to the next entry. */ + else + c = c->entries[i.current()]; + } + return c; +} Added: trunk/srv/filesystem/linn/LinnFileSystem.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnFileSystem.h Wed Jul 8 15:47:03 2009 @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __FILESYSTEM_LINN_FILESYSTEM_H +#define __FILESYSTEM_LINN_FILESYSTEM_H + +#include <FileSystem.h> +#include <FileSystemPath.h> +#include <FileSystemMessage.h> +#include <Storage.h> +#include <Types.h> +#include <Array.h> +#include <HashTable.h> +#include <Integer.h> +#include "LinnSuperBlock.h" +#include "LinnInode.h" +#include "LinnGroup.h" + +/** + * @defgroup linn Linnenbank Filesystem (LinnFS) + * @{ + */ + +/** + * @name Filesystem limits. + * @{ + */ + +/** Minimum blocksize. */ +#define LINN_MIN_BLOCK_SIZE 1024 + +/** Maximum blocksize. */ +#define LINN_MAX_BLOCK_SIZE 8192 + +/** + * @} + */ + +#ifndef __HOST__ + +/** + * Linnenbank FileSystem (LinnFS). + */ +class LinnFileSystem : public FileSystem +{ + public: + + /** + * Class constructor function. + * @param path Path to which we are mounted. + * @param storage Storage provider. + */ + LinnFileSystem(const char *path, Storage *storage); + + /** + * Retrieve the superblock pointer. + * @return Pointer to the superblock for this filesystem. + * @see LinnSuperBlock + */ + LinnSuperBlock * getSuperBlock() + { + return &super; + } + + /** + * Get the underlying Storage object. + * @return Storage pointer. + * @see Storage + */ + Storage * getStorage() + { + return storage; + } + + /** + * Read an inode from the filesystem. + * @param inodeNum Inode number. + * @return Pointer to an LinnInode on success, ZERO on failure. + * @see LinnInode + */ + LinnInode * getInode(u64 inodeNum); + + /** + * Read a group descriptor from the filesystem. + * @param groupNum Group descriptor number. + * @return Pointer to an LinnGroup on success, ZERO on failure. + * @see LinnGroup + */ + LinnGroup * getGroup(u64 groupNum); + + /** + * Read a group descriptor from the filesystem, given an inode number. + * @param inodeNum Find the corresponding group via this inode number. + * @return Pointer to an LinnGroup on success, ZERO on failure. + * @see LinnGroup + * @see LinnInode + */ + LinnGroup * getGroupByInode(u64 inodeNum); + + /** + * Calculates the offset inside storage for a given block. + * @param inode LinnInode pointer. + * @param blk Calculate the offset for this block. + * @return Offset in bytes in storage. + * @see LinnInode + */ + u64 getOffset(LinnInode *inode, u64 blk); + + /**+ * Load a file corresponding to the given path from underlying storage.
+ * @param path Full path to the file to load.+ * @return Pointer to FileCache object if the file exists, or ZERO otherwise.
+ */ + FileCache * lookupFile(FileSystemPath *path); + + private: + + /** + * Creates a new LinnFile. + * @param msg Describes the file creation request. + * @param path Full path to the file to create. + */ + Error createFile(FileSystemMessage *msg, + FileSystemPath *path); + + /** Provides storage. */ + Storage *storage; + + /** Describes the filesystem. */ + LinnSuperBlock super; + + /** Group descriptors. */ + Array<LinnGroup> *groups; + + /** Inode cache. */ + HashTable<Integer<u64>,LinnInode> inodes; +}; + +#endif /* __HOST__ */ + +/** + * @} + */ + +#endif /* __FILESYSTEM_LINN_FILESYSTEM_H */ Modified: trunk/srv/filesystem/linn/SConscript ============================================================================== --- trunk/srv/filesystem/linn/SConscript (original) +++ trunk/srv/filesystem/linn/SConscript Wed Jul 8 15:47:03 2009 @@ -20,7 +20,7 @@ # # Target system environment. #-targetEnv = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ], +targetEnv = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc', 'libgcc' ],
[ 'filesystem', 'process', 'log' ]) # @@ -39,3 +39,10 @@ # hostEnv.Program('host/dump', [ 'host/LinnDump.cpp' ], LIBS = hostEnv['LIBS'], LIBPATH = hostEnv['LIBPATH']) + +# +# Linnenbank FileSystem server. +# +targetEnv.Program('server', [ 'LinnFileSystem.cpp', 'LinnFile.cpp', + 'LinnDirectory.cpp' ], + LIBS = targetEnv['LIBS'], LIBPATH = targetEnv['LIBPATH'])