示例#1
0
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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
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;
}