Author: nieklinnenbank Date: Sat Jul 4 09:38:42 2009 New Revision: 194 Added: trunk/srv/filesystem/linn/ trunk/srv/filesystem/linn/LinnCreate.cpp trunk/srv/filesystem/linn/LinnCreate.h trunk/srv/filesystem/linn/LinnDump.cpp trunk/srv/filesystem/linn/LinnSuperBlock.h trunk/srv/filesystem/linn/SConscript Modified: trunk/srv/filesystem/SConscript Log: Added initial implementation of LinnFS. Two utilities are available: LinnCreate and LinnDump, to create and dump the filesystem, respectively. The initial LinnSuperBlock has also been added, but may change during development. Modified: trunk/srv/filesystem/SConscript ============================================================================== --- trunk/srv/filesystem/SConscript (original) +++ trunk/srv/filesystem/SConscript Sat Jul 4 09:38:42 2009 @@ -15,4 +15,4 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -SConscript(dirs = [ 'ext2', 'proc', 'tmp', 'virtual' ]) +SConscript(dirs = [ 'ext2', 'linn', 'proc', 'tmp', 'virtual' ]) Added: trunk/srv/filesystem/linn/LinnCreate.cpp ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnCreate.cpp Sat Jul 4 09:38:42 2009 @@ -0,0 +1,172 @@ +/* + * 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 <BitMap.h> +#include <List.h> +#include <ListIterator.h> +#include <String.h> +#include <Types.h> +#include <Macros.h> +#include "LinnCreate.h" +#include "LinnSuperBlock.h" +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <time.h> +#include <string.h> +#include <errno.h> +#include <libgen.h> +#include <sys/types.h> +#include <sys/stat.h> + +LinnCreate::LinnCreate() +{ + prog = ZERO; + image = ZERO; + super = ZERO; + verbose = false; +} + +int LinnCreate::create(Size blocksize) +{ + assert(image != ZERO); + assert(prog != ZERO); + + /* Allocate blocks. */ + blocks = new u8[blocksize * LINNCREATE_BLOCK_NUM]; + memset(blocks, 0, blocksize * LINNCREATE_BLOCK_NUM); + + /* Create a superblock. */ + super = (LinnSuperBlock *) (blocks + LINN_SUPER_OFFSET); + super->magic0 = LINN_SUPER_MAGIC0; + super->magic1 = LINN_SUPER_MAGIC1; + super->majorRevision = LINN_SUPER_MAJOR; + super->minorRevision = LINN_SUPER_MINOR; + super->state = LINN_SUPER_VALID; + super->blockSize = LINNCREATE_BLOCK_SIZE; + super->blockAddrSize = LINNCREATE_BLOCK_ADDR_SIZE; + super->blocksPerGroup = LINNCREATE_BLOCKS_PER_GROUP; + super->inodesPerGroup = LINNCREATE_INODES_PER_GROUP; + super->inodesCount = ZERO; + super->blocksCount = 2; + super->groupsCount = ZERO; + super->freeInodesCount = ZERO; + super->freeBlocksCount = ZERO; + super->freeGroupsCount = ZERO; + super->creationTime = time(NULL); + super->mountTime = ZERO; + super->mountCount = ZERO; + super->lastCheck = ZERO; + super->groupsTable = 2; + + /* Write the final image. */ + return writeImage(); +} + +int LinnCreate::writeImage() +{ + FILE *fp; + + /* Open output image. */ + if ((fp = fopen(image, "w")) == NULL) + { + printf("%s: failed to fopen() `%s' for writing: %s\r\n", + prog, image, strerror(errno)); + return EXIT_FAILURE; + } + /* Write all blocks at once. */ + if (fwrite(blocks, super->blockSize * super->blocksCount, 1, fp) != 1) + { + printf("%s: failed to fwrite() `%s': %s\r\n", + prog, image, strerror(errno)); + fclose(fp); + return EXIT_FAILURE; + } + /* All done. */ + fclose(fp); + return EXIT_SUCCESS; +} + +void LinnCreate::setProgram(char *progName) +{ + this->prog = progName; +} + +void LinnCreate::setImage(char *imageName) +{ + this->image = imageName; +} + +void LinnCreate::setInput(char *inputName) +{ + this->input = inputName; +} + +void LinnCreate::setExclude(char *pattern) +{ + this->excludes.insertTail(new String(pattern)); +} + +void LinnCreate::setVerbose(bool newVerbose) +{ + this->verbose = newVerbose; +} + +int main(int argc, char **argv) +{ + LinnCreate fs; + Size blocksize = LINNCREATE_BLOCK_SIZE; + + /* Verify command-line arguments. */ + if (argc < 3) + { + printf("usage: %s IMAGE DIRECTORY [OPTIONS...]\r\n" + "Creates a new Linnenbank FileSystem\r\n" + "\r\n" + "-h Show this help message.\r\n" + "-v Output verbose messages.\r\n"+ "-e PATTERN Exclude matching files from the created filesystem\r\n",
+ argv[0]); + return EXIT_FAILURE; + } + /* Process command-line arguments. */ + fs.setProgram(argv[0]); + fs.setImage(argv[1]); + fs.setInput(argv[2]); + + /* Process command-line options. */ + for (int i = 0; i < argc - 3; i++) + { + /* Exclude files matching the given pattern. */ + if (!strcmp(argv[i + 3], "-e") && i < argc - 4) + { + fs.setExclude(argv[i + 4]); + i++; + } + /* Verbose output. */ + else if (!strcmp(argv[i + 3], "-v")) + { + fs.setVerbose(true); + } + /* Unknown argument. */ + else + printf("%s: unknown option `%s'\r\n", + argv[0], argv[i + 3]); + } + /* Create a new Linnenbank FileSystem. */ + return fs.create(blocksize); +} Added: trunk/srv/filesystem/linn/LinnCreate.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnCreate.h Sat Jul 4 09:38:42 2009 @@ -0,0 +1,131 @@ +/* + * 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_LINNCREATE_H +#define __FILESYSTEM_LINNCREATE_H + +#include <BitMap.h> +#include <List.h> +#include <String.h> +#include "LinnSuperBlock.h" + +/** Default block size. */ +#define LINNCREATE_BLOCK_SIZE 2048 + +/** Default block address size. */ +#define LINNCREATE_BLOCK_ADDR_SIZE 8 + +/** Default number of blocks to allocate. */ +#define LINNCREATE_BLOCK_NUM 8192 + +/** Default number of data blocks per group descriptor. */ +#define LINNCREATE_BLOCKS_PER_GROUP 8192 + +/** Default number of inodes per group descriptor. */ +#define LINNCREATE_INODES_PER_GROUP 1024 + +/** + * @brief Returns a pointer to the correct in-memory block. + * @param type Data type to return a pointer for. + * @param nr Block number. + * @return A pointer of the given type. + */ +#define BLOCKPTR(type,nr) (type *)(blocks + (blockSize * (nr))) + +/** + * Class for creating new Linnenbank FileSystems. + */ +class LinnCreate +{ + public: + + /** + * Class constructor. + */ + LinnCreate(); + + /** + * Creates the LinnFS FileSystem. + * @param blocksize The size of each block in the new filesystem. + * @return EXIT_SUCCESS if successfull and EXIT_FAILURE otherwise. + */ + int create(Size blocksize = LINNCREATE_BLOCK_SIZE); + + /** + * Set the program name we are invoked with. + * @param progName program name. + */ + void setProgram(char *progName); + + /** + * Set the output image file name. + * @param imageName Image name to use. + */ + void setImage(char *imageName); + + /** + * Set the input directory name. + * @param inputName Input directory to use. + */ + void setInput(char *inputName); + + /** + * Exclude files matching the given pattern from the image. + * @param pattern Pattern to match against. + */ + void setExclude(char *pattern); + + /** + * Output verbose messages during the construction. + * @param newVerbose True to turn on, false to turn off verbose messages. + */ + void setVerbose(bool newVerbose); + + private: + + /** + * Writes the final image to disk. + * @return EXIT_SUCCESS if successfull and EXIT_FAILURE otherwise. + */ + int writeImage(); + + /** Program name we are invoked with. */ + char *prog; + + /** Path to the output image. */ + char *image; + + /** Path to the input directory. */ + char *input; + + /** Output verbose messages. */ + bool verbose; + + /** List of file patterns to ignore. */ + List<String> excludes; + + /** Pointer to the superblock. */ + LinnSuperBlock *super; + + /** Block and Inode bitmaps. */ + BitMap *blockMap, *inodeMap; + + /** Array of blocks available in the filesystem. */ + u8 *blocks; +}; + +#endif /* __FILESYSTEM_LINNCREATE_H */ Added: trunk/srv/filesystem/linn/LinnDump.cpp ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnDump.cpp Sat Jul 4 09:38:42 2009 @@ -0,0 +1,144 @@ +/* + * 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 "LinnSuperBlock.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <time.h> + +char * timeString(u64 timestamp) +{ + char *buff = (char *) malloc(128); + struct tm *tm; + + /* Fill in the time struct. */ + tm = gmtime((const time_t *) ×tamp); + + /* Format time. */ + if (!strftime(buff, 128, "%F %T", tm)) + { + return strdup("???"); + } + /* Done. */ + else + return buff; +} + +void usage(char *prog) +{ + printf("usage: %s FILE [OPTIONS...]\r\n" + "Displays information of a Linnenbank Filesystem\r\n" + "\r\n" + "-h Show this help message.\r\n" + "-v Output verbose messages.\r\n", + prog); +} + +int main(int argc, char **argv) +{ + LinnSuperBlock super; + bool verbose = false; + FILE *fp; + + /* Verify command-line arguments. */ + if (argc < 2) + { + usage(argv[0]); + return EXIT_FAILURE; + } + /* Process command-line options. */ + for (int i = 0; i < argc - 2; i++) + { + /* Show help. */ + if (!strcmp(argv[i + 2], "-h")) + { + usage(argv[0]); + return EXIT_SUCCESS; + } + /* Verbose output. */ + else if (!strcmp(argv[i + 2], "-v")) + { + verbose = true; + } + /* Unknown argument. */ + else + printf("%s: unknown option `%s'\r\n", + argv[0], argv[i + 2]); + } + /* Attempt to open the given file. */ + if ((fp = fopen(argv[1], "r")) == NULL) + { + printf("%s: failed to fopen() `%s': %s\n", + argv[0], argv[1], strerror(errno)); + return EXIT_FAILURE; + } + /* Seek to correct offset. */ + if (fseek(fp, LINN_SUPER_OFFSET, SEEK_SET) == -1) + { + printf("%s: failed to fseek() to %x in `%s': %s\n", + argv[0], LINN_SUPER_OFFSET, argv[1], strerror(errno)); + return EXIT_FAILURE; + } + /* Read the superblock. */ + if (fread(&super, sizeof(super), 1, fp) != 1) + { + printf("%s: failed to fread() superblock from `%s': %s\n", + argv[0], argv[1], strerror(errno)); + return EXIT_FAILURE; + } + /* Dump filesystem information. */ + printf( "LinnSuperBlock\n" + "[\n" + " magic0 = %x\n" + " magic1 = %x\n" + " majorRevision = %u\n" + " minorRevision = %u\n" + " state = %x\n" + " blockSize = %u\n" + " blockAddrSize = %u (%d bit)\n" + " blocksPerGroup = %u\n" + " inodesPerGroup = %u\n" + " inodesCount = %llu\n" + " blocksCount = %llu\n" + " groupsCount = %llu\n" + " freeBlocksCount = %llu\n" + " freeInodesCount = %llu\n" + " freeGroupsCount = %llu\n" + " creationTime = %s\n" + " mountTime = %s\n" + " mountCount = %u\n" + " lastCheck = %s\n" + " groupsTable = %llu\n" + "]\n", + super.magic0, super.magic1, + super.majorRevision, super.minorRevision, + super.state, super.blockSize, + super.blockAddrSize, super.blockAddrSize * 8, + super.blocksPerGroup, super.inodesPerGroup, super.inodesCount, + super.blocksCount, super.groupsCount, + super.freeBlocksCount, super.freeInodesCount, + super.freeGroupsCount, timeString(super.creationTime), + timeString(super.mountTime), super.mountCount, + timeString(super.lastCheck), super.groupsTable); + + /* Cleanup and terminate. */ + fclose(fp); + return EXIT_FAILURE; +} Added: trunk/srv/filesystem/linn/LinnSuperBlock.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnSuperBlock.h Sat Jul 4 09:38:42 2009 @@ -0,0 +1,120 @@ +/* + * 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_LINNSUPERBLOCK_H +#define __FILESYSTEM_LINNSUPERBLOCK_H + +#include <Types.h> + +/** + * @defgroup linn Linnenbank Filesystem (LinnFS) + * @{ + */ + +/** + * @brief Filesystem Magic Numbers. + * @{ + */ + +/** First magic number ('Linn'). Used to detect a valid superblock. */ +#define LINN_SUPER_MAGIC0 0x4c696e6e + +/** Second magic number (randomly chosen bytes). */ +#define LINN_SUPER_MAGIC1 0x512ea9b0 + +/** + * @} + */ + +/** + * @brief Filesystem Revision Numbers. + * @{ + */ + +/** Current major revision number. */ +#define LINN_SUPER_MAJOR 1 + +/** Current minor revision number. */ +#define LINN_SUPER_MINOR 0 + +/** + * @} + */ + +/** + * @brief Filesystem States. + * @{ + */ + +/** Filesystem is consistent. */ +#define LINN_SUPER_VALID 0 + +/** The filesystem has not been properly unmounted. */ +#define LINN_SUPER_UNCLEAN 1 + +/** Serious corruption has been detected. */ +#define LINN_SUPER_CORRUPT 2 + +/** + * @} + */ + +/** + * @brief Filesystem Constants. + * @{ + */ + +/** Fixed offset in storage of the superblock. */ +#define LINN_SUPER_OFFSET 1024 + +/** + * Linnenbank Filesystem (LinnFS) super block. + */ +typedef struct LinnSuperBlock +{ + le32 magic0; /**< Allows detection of valid superblocks. */ + le32 magic1; /**< Allows detection of valid superblocks. */ + le16 majorRevision; /**< Filesystem major revision level. */ + le16 minorRevision; /**< Filesystem minor revision level. */ + le16 state; /**< Describes the current status. */ + + le32 blockSize; /**< Size of each data block. */ + le16 blockAddrSize; /**< Size in bytes of block addresses. */ + le32 blocksPerGroup; /**< Number of blocks per group. */ + le32 inodesPerGroup; /**< Number of inodes per group. */ + + le64 inodesCount; /**< Total number of inodes. */ + le64 blocksCount; /**< Total number of data blocks. */ + le64 groupsCount; /**< Total number of groups. */ + le64 freeBlocksCount; /**< Number of free data blocks. */ + le64 freeInodesCount; /**< Free inodes remaining. */ + le64 freeGroupsCount; /**< Free groups remaining. */ + + le64 creationTime; /**< Time when the filesystem was created. */+ le64 mountTime; /**< Last time we where mounted (seconds since 1970). */
+ le16 mountCount; /**< Number of times we where mounted. */ + le64 lastCheck; /**< Timestamp of the last check. */ + + le64 groupsTable; /**< Block address of the LinnGroup table. */ +} +LinnSuperBlock; + +/** + * @} + */ + +#endif /* __FILESYSTEM_LINNSUPERBLOCK_H */ Added: trunk/srv/filesystem/linn/SConscript ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/SConscript Sat Jul 4 09:38:42 2009 @@ -0,0 +1,41 @@ +# +# 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/>. +# + +from build import * + +# +# Target system environment. +#+targetEnv = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ],
+ [ 'filesystem', 'process', 'log' ]) + +# +# Host system environment. +# +hostEnv = Prepare(host, [ 'libexec' ], [ 'filesystem' ]) + +# +# Linnenbank FileSystem creation utility. +# +hostEnv.Program('host/create', [ 'host/LinnCreate.cpp' ], + LIBS = hostEnv['LIBS'], LIBPATH = hostEnv['LIBPATH']) + +# +# Linnenbank FileSystem dump utility. +# +hostEnv.Program('host/dump', [ 'host/LinnDump.cpp' ], + LIBS = hostEnv['LIBS'], LIBPATH = hostEnv['LIBPATH'])