Author: nieklinnenbank Date: Wed Jul 8 05:16:49 2009 New Revision: 208 Added: trunk/srv/filesystem/linn/LinnDirectoryEntry.h Modified: trunk/srv/filesystem/linn/LinnCreate.cpp trunk/srv/filesystem/linn/LinnCreate.h trunk/srv/filesystem/linn/LinnSuperBlock.h Log: LinnCreate is now capable of writing LinnDirectoryEntry's. Modified: trunk/srv/filesystem/linn/LinnCreate.cpp ============================================================================== --- trunk/srv/filesystem/linn/LinnCreate.cpp (original) +++ trunk/srv/filesystem/linn/LinnCreate.cpp Wed Jul 8 05:16:49 2009 @@ -27,6 +27,7 @@ #include "LinnSuperBlock.h" #include "LinnGroup.h" #include "LinnInode.h" +#include "LinnDirectoryEntry.h" #include <stdio.h> #include <stdlib.h> #include <dirent.h> @@ -51,6 +52,7 @@ { LinnGroup *group; LinnInode *inode; + BitMap inodeMap; /* Point to the correct group. */ group = BLOCKPTR(LinnGroup, super->groupsTable); @@ -72,6 +74,11 @@ inode->changeTime = inode->createTime; inode->links = 1; + /* Update inode bitmap, if needed. */ + inodeMap.setMap(BLOCKPTR(u8, group->inodeMap), + super->inodesPerGroup); + inodeMap.mark(inodeNum % super->inodesPerGroup); + /* Update superblock. */ super->freeInodesCount--; group->freeInodesCount--; @@ -84,7 +91,7 @@ { LinnGroup *group; LinnInode *inode; - BitMap *map; + BitMap inodeMap; u64 gn, in; /* Loop all available LinnGroups. */ @@ -110,9 +117,9 @@ exit(EXIT_FAILURE); } /* Find an empty inode number. */ - map = new BitMap(super->inodesPerGroup, - BLOCKPTR(u8, group->inodeMap)); - in = map->markNext(); + inodeMap.setMap(BLOCKPTR(u8, group->inodeMap), + super->inodesPerGroup); + in = inodeMap.markNext(); /* Instantiate the inode. */ inode = createInode(in, FILETYPE_FROM_ST(st), @@ -242,6 +249,59 @@ fclose(fp); } +void LinnCreate::insertEntry(le64 dirInode, le64 entryInode, + char *name, FileType type) +{ + LinnGroup *group; + LinnInode *inode; + LinnDirectoryEntry *entry; + le64 entryNum, blockNum; + + /* Point to the correct group. */ + group = BLOCKPTR(LinnGroup, super->groupsTable); + if (dirInode != ZERO) + { + group += (super->inodesPerGroup / dirInode); + } + /* Fetch inode. */ + inode = BLOCKPTR(LinnInode, group->inodeTable) + + (dirInode % super->inodesPerGroup); + + /* Calculate entry and block number. */ + entryNum = inode->size / sizeof(LinnDirectoryEntry); + blockNum = (entryNum * sizeof(LinnDirectoryEntry)) / + super->blockSize; + + /* Direct block. */ + if (blockNum < LINN_INODE_DIR_BLOCKS) + { + /* Allocate a new block, if needed. */ + if (!inode->block[blockNum]) + { + inode->block[blockNum] = BLOCK(super); + } + /* Point to the fresh entry. */ + entry = BLOCKPTR(LinnDirectoryEntry, inode->block[blockNum]) + + ((entryNum * sizeof(LinnDirectoryEntry)) % + super->blockSize); + /* Fill it. */ + entry->inode = entryInode; + entry->type = type; + memcpy(entry->name, name, + strlen(name) < LINN_DIRENT_NAME_LEN ? + strlen(name) : LINN_DIRENT_NAME_LEN); + } + /* Indirect block. */ + else + { + printf("%s: indirect blocks not (yet) supported for directories\n", + prog); + exit(EXIT_FAILURE); + } + /* Increment directory size. */ + inode->size += sizeof(LinnDirectoryEntry); +} +void LinnCreate::insertDirectory(char *inputDir, le64 inodeNum, le64 parentNum)
{ struct dirent *ent; @@ -251,6 +311,10 @@ le64 child; bool skip = false; + /* Create '.' and '..' */ + insertEntry(inodeNum, inodeNum, ".", DirectoryFile); + insertEntry(inodeNum, parentNum, "..", DirectoryFile); + /* Open the input directory. */ if ((dir = opendir(inputDir)) == NULL) { @@ -261,10 +325,10 @@ /* Read all it's entries. */ while ((ent = readdir(dir))) { - /* Skip hidden. */ + /* Hidden files. */ skip = ent->d_name[0] == '.'; - /* Skip excluded. */ + /* Excluded files. */ for (ListIterator<String> e(&excludes); e.hasNext(); e++) { if (e.current()->match(ent->d_name, **e.current())) @@ -273,6 +337,7 @@ break; } } + /* Skip file? */ if (skip) continue; /* Construct local path. */ @@ -348,7 +413,7 @@ LINN_GROUP_NUM_INODEMAP(super) + LINN_GROUP_NUM_INODETAB(super); } - /* Create the root inode. */ + /* Create special inodes. */ createInode(LINN_INODE_ROOT, DirectoryFile, OwnerRWX | GroupRX | OtherRX); Modified: trunk/srv/filesystem/linn/LinnCreate.h ============================================================================== --- trunk/srv/filesystem/linn/LinnCreate.h (original) +++ trunk/srv/filesystem/linn/LinnCreate.h Wed Jul 8 05:16:49 2009 @@ -146,6 +146,16 @@ le64 createInode(char *inputFile, struct stat *st); /** + * Inserts an LinnDirectoryEntry to the given directory inode. + * @param dirInode Inode number of the directory. + * @param entryInode Inode number of the entry to create. + * @param name Unique name (inside this directory) for the entry. + * @param type FileType for the entry to insert. + */ + void insertEntry(le64 dirInode, le64 entryInode, + char *name, FileType type); + + /** * Inserts the given directory and it's childs to the filesystem image. * @param inputFile Path to a local directory. * @param inodeNum Inode number for the input directory. Added: trunk/srv/filesystem/linn/LinnDirectoryEntry.h ============================================================================== --- (empty file) +++ trunk/srv/filesystem/linn/LinnDirectoryEntry.h Wed Jul 8 05:16:49 2009 @@ -0,0 +1,46 @@ +/* + * 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_ENTRY_H +#define __FILESYSTEM_LINN_DIRECTORY_ENTRY_H + +#include <Types.h> + +/** Length of the name field in an directory entry. */ +#define LINN_DIRENT_NAME_LEN 55 + +/** + * Struct of an directory entry in LinnFS. + */ +typedef struct LinnDirectoryEntry +{ + /** Inode number. */ + le64 inode; + + /** Type of file, as an FileType. */ + u8 type; + + /** File name. */ + char name[LINN_DIRENT_NAME_LEN]; +} +LinnDirectoryEntry; + +/** + * @} + */ + +#endif /* __FILESYSTEM_LINN_DIRECTORY_ENTRY_H */ Modified: trunk/srv/filesystem/linn/LinnSuperBlock.h ============================================================================== --- trunk/srv/filesystem/linn/LinnSuperBlock.h (original) +++ trunk/srv/filesystem/linn/LinnSuperBlock.h Wed Jul 8 05:16:49 2009 @@ -26,7 +26,7 @@ */ /** - * @brief Filesystem Magic Numbers. + * @brief Magic Numbers. * @{ */ @@ -41,7 +41,7 @@ */ /** - * @brief Filesystem Revision Numbers. + * @brief Revision Numbers. * @{ */ @@ -74,7 +74,7 @@ */ /** - * @brief Filesystem Constants. + * @brief Superblock Constants. * @{ */