int32 FileSystemMinix::link(File* file, Directory* parent, const char* name) { if(file->getReferenceCount() >= MINIX_LINK_MAX) { debug(FS_MINIX, "link - ERROR max link (%d) is already reached, no more links to this file!\n", MINIX_LINK_MAX); return -1; } // create a new hard-link to an existing file (inode) if(!addDirectoryEntry(parent, name, file->getID())) { debug(FS_MINIX, "link - ERROR failed establish a new link.\n"); return -1; } // increment reference counter of file file->incrReferenceCount(); return 0; }
int addDirectory(int pinum, char *name){ //Variables MFS_InodeMap_t *tempMap, *tempMap2; MFS_Inode_t *tempInode; MFS_Dir_t *tempDir; int inodeNumber, mapNumber; int mapPos = 0; int inodePos = 0; int dirPos = 0; int dirEntPos = 0; int i; //Create the inode temp = position; inodeNumber = findFreeInode(); inodePos = temp - image; tempInode = (MFS_Inode_t *)temp; tempInode->size = sizeof(MFS_Dir_t) + (2 * sizeof(MFS_DirEnt_t)); tempInode->type = MFS_DIRECTORY; inodes[inodeNumber] = tempInode; position += sizeof(MFS_Inode_t); //Create the map piece mapNumber = findMapPiece(inodeNumber); if(inodeMap[mapNumber] == NULL){ temp = position; mapPos = temp - image; tempMap = (MFS_InodeMap_t *)temp; tempMap->inodes[(inodeNumber%16)] = inodePos; inodeMap[mapNumber] = tempMap; position += sizeof(MFS_InodeMap_t); } else{ temp = position; tempMap2 = inodeMap[mapNumber]; mapPos = temp - image; tempMap = (MFS_InodeMap_t *)temp; for(i = 0; i < 16; i++) tempMap->inodes[i] = tempMap2->inodes[i]; tempMap->inodes[(inodeNumber%16)] = inodePos; inodeMap[mapNumber] = tempMap; checkpoint->mapPieces[mapNumber] = mapPos; position += sizeof(MFS_InodeMap_t); } //Create the directory temp = position; dirPos = temp - image; tempInode->addrs[0] = dirPos; tempDir = (MFS_Dir_t *)temp; strcpy(tempDir->name, name); tempDir->inum = inodeNumber; for(i = 0; i < 128; i++){ tempDir->entries[i] = -1; } position += sizeof(MFS_Dir_t); //Create the directory entries tempDir->entries[0] = addDirectoryEntry(inodeNumber, "."); tempDir->entries[1] = addDirectoryEntry(pinum, ".."); //Update the parent directory if(strcmp(name, "/") == 1){ tempInode = inodes[pinum]; tempDir = image + tempInode->addrs[0]; for(i = 0; i < 128; i++){ if(tempDir->entries[i] == -1){ dirEntPos = i; break; } } tempDir->entries[dirEntPos] = addDirectoryEntry(inodeNumber, name); } //Update end end = position; return 0; }
int createFile(int pinum, char *name){ //Variables MFS_InodeMap_t *tempMap, *tempMap2; MFS_Inode_t *tempInode; MFS_Dir_t *tempDir; int inodeNumber, mapNumber; int mapPos = 0; int inodePos = 0; int pos = 0; int i; //Create the inode temp = position; inodeNumber = findFreeInode(); inodePos = temp - image; tempInode = (MFS_Inode_t *)temp; tempInode->size = 0; tempInode->type = MFS_REGULAR_FILE; for(i = 0; i < 14; i++) tempInode->addrs[i] = -1; inodes[inodeNumber] = tempInode; position += sizeof(MFS_Inode_t); //Create the map piece mapNumber = findMapPiece(inodeNumber); if(inodeMap[mapNumber] == NULL){ temp = position; mapPos = temp - image; tempMap = (MFS_InodeMap_t *)temp; tempMap->inodes[(inodeNumber%16)] = inodePos; inodeMap[mapNumber] = tempMap; position += sizeof(MFS_InodeMap_t); } else{ temp = position; tempMap2 = inodeMap[mapNumber]; mapPos = temp - image; tempMap = (MFS_InodeMap_t *)temp; for(i = 0; i < 16; i++) tempMap->inodes[i] = tempMap2->inodes[i]; tempMap->inodes[(inodeNumber%16)] = inodePos; inodeMap[mapNumber] = tempMap; checkpoint->mapPieces[mapNumber] = mapPos; position += sizeof(MFS_InodeMap_t); } //Update the parent directory tempInode = inodes[pinum]; tempDir = image + tempInode->addrs[0]; for(i = 0; i < 128; i++){ if(tempDir->entries[i] == -1){ pos = i; break; } } printf("INODESSS: %d\n", inodeNumber); tempDir->entries[pos] = addDirectoryEntry(inodeNumber, name); tempInode->size += 4096; //Update end end = position; return 0; }
int32 FileSystemMinix::mkdir(Directory* parent, const char* name, unix_time_stamp current_time, mode_t permissions, uid_t uid, gid_t gid, inode_id_t& new_dir_id) { debug(FS_MINIX, "mkdir - CALL parent ID=%d name=\"%s\"\n", parent->getID(), name); // check argument if(strlen(name) > FILENAME_LEN_) { debug(FS_MINIX, "mkdir - ERROR filename too long; max %d chars allowed!\n", FILENAME_LEN_); return -1; } // 1. create a new Directory in the given parent directory inode_id_t id = inode_table_->occupyAndReturnNextFreeInode(); if(id == -1U) { debug(FS_MINIX, "mkdir - ERROR no more free i-nodes, FS is full!\n"); return -1; // TODO error-code } debug(FS_MINIX, "mkdir - Inode ID for new Directory (%d).\n", id); // 2. create the i-node instance; // * id is the just obtained one // * sector and offset in the sector can be calculated from the id // * times are set to current time Directory* new_directory = new Directory(id, inode_table_->getInodeSectorAddr(id), inode_table_->getInodeSectorOffset(id), this, current_time, current_time, current_time); if(new_directory == NULL) { debug(FS_MINIX, "mkdir - ERROR failed to create new Directory instance.\n"); return -1; } // apply default values for GID, UID und permissions inode_table_->initInode(new_directory, gid, uid, permissions); // add the self reference "." and the parent reference ".." if(!addDirectoryEntry(new_directory, ".", id) || !addDirectoryEntry(new_directory, "..", parent->getID())) { debug(FS_MINIX, "mkdir - ERROR failed to create \".\" or \"..\".\n"); inode_table_->freeInode(id); delete new_directory; return -1; } new_directory->addChild(".", id); new_directory->addChild("..", parent->getID()); new_directory->allChildrenLoaded(); // 3. add a hard-link reference in the parent directory to the new file if(!addDirectoryEntry(parent, name, id)) { debug(FS_MINIX, "mkdir - ERROR failed to create the hard-link reference in the parent directory.\n"); inode_table_->freeInode(id); delete new_directory; return -1; } // store the new File in the I-Node cache and in the table: UnixInodeIdent ident(id); UnixInodeCacheItem* item = new UnixInodeCacheItem(new_directory); debug(FS_MINIX, "mkdir - creating CacheItem holding the Inode %x.\n", item); inode_cache_->addItem(ident, item); if( !inode_cache_->writeItem(ident, item) ) { debug(FS_MINIX, "mkdir - ERROR failed to write item to table!\n"); inode_table_->freeInode(id); delete new_directory; return false; } debug(FS_MINIX, "mkdir - DONE new empty directory successfully created.\n"); //debug(FS_MINIX, "mkdir - File-id=%d Sector=%x Offset=%d.\n", id, inode_sector, inode_offset); new_dir_id = id; return 0; }
File* FileSystemMinix::creat(Directory* parent, const char* name, mode_t permissions, uid_t uid, gid_t gid) { // create a new file in the given parent directory debug(FS_MINIX, "creat - CALL parent ID=%d filename \"%s\"\n", parent->getID(), name); // check arguments if(strlen(name) > FILENAME_LEN_) { debug(FS_MINIX, "creat - ERROR filename too long; max %d chars allowed!\n", FILENAME_LEN_); return NULL; } // 1. obtain a free InodeID for the new File inode_id_t id = inode_table_->occupyAndReturnNextFreeInode(); if(id == -1U) { debug(FS_MINIX, "creat - ERROR failed no more free i-nodes...\n"); return NULL; } // current time-stamp unix_time_stamp current_time = VfsSyscall::getCurrentTimeStamp(); // 2. create the i-node instance; // * id is the just obtained one // * sector and offset in the sector can be calculated from the id // * times are set to current time // * reference count is 1 // * file-size is 0 (empty new file) RegularFile* new_file = new RegularFile(id, inode_table_->getInodeSectorAddr(id), inode_table_->getInodeSectorOffset(id), this, getVolumeManager(), current_time, current_time, current_time, 1, 0); if(new_file == NULL) { debug(FS_MINIX, "creat - ERROR failed to create new file instance.\n"); return NULL; } // apply default values for GID, UID und permissions inode_table_->initInode(new_file, gid, uid, permissions); // add a hard-link reference in the parent directory to the new file if(!addDirectoryEntry(parent, name, id)) { debug(FS_MINIX, "creat - ERROR failed to create a hard link to the new file.\n"); delete new_file; return NULL; } // store the new File in the I-Node cache and in the table: UnixInodeIdent ident(id); UnixInodeCacheItem* item = new UnixInodeCacheItem(new_file); inode_cache_->addItem(ident, item); inode_cache_->writeItem(ident, item); // perform a "dummy"-acquire to increase the reference counter of the new // created file if( inode_cache_->getItem(ident) != item ) { debug(FS_MINIX, "creat - ERROR failed to add I-Node correctly to Cache!\n"); delete new_file; return NULL; } debug(FS_MINIX, "creat - DONE new file successfully created.\n"); //debug(FS_MINIX, "creat - File-id=%d Sector=%x Offset=%d.\n", id, inode_sector, inode_offset); return new_file; }