struct unixfilesystem *
unixfilesystem_format(int dfd) 
{
    uint16_t bootblock[256];
    bootblock[0] = BOOTBLOCK_MAGIC_NUM;
    diskimg_writesector(dfd, BOOTBLOCK_SECTOR, bootblock);
    
    struct unixfilesystem *fs = malloc(sizeof(struct unixfilesystem));
    if (fs == NULL) {
      fprintf(stderr,"Out of memory.\n");
      return NULL;
    }
    fs->dfd = dfd;
    
    // 144 inodes in total, so we have 8 blocks 
    // to store inodes, plus 2 start blocks, 
    // we have 10 blocks in use, and we allocate the entire volume 110 blocks
    // so the rest 100 blocks is file blocks, and all blocks formats to free.
    fs->superblock.s_isize = 144;  
    fs->superblock.s_fsize = 110; // 110 blocks of entire volume 
    
    fs->superblock.s_ninode = fs->superblock.s_isize; // at begining, free inodes number = total inodes number
    
    int i;
    // consider s_inode as bitmap
    for (i = 0;i < 100;i++)
        fs->superblock.s_inode[i] = 0;
    
    fs->superblock.s_nfree = fs->superblock.s_fsize ; // at begining, free blocks number = total blocks number
    // consider s_free as bitmap
    for (i = 0;i < 100;i++)
        fs->superblock.s_free[i] = 0;

    diskimg_writesector(dfd, SUPERBLOCK_SECTOR, &fs->superblock);
    
    
    int inumber = filsys_allocInode(fs);
    if (inumber != ROOT_INUMBER) {
        fprintf(stderr, "ROOT_INUMBER is not 1, format failed\n");
        return -1;
    }
    
    struct inode in;
    inode_iget(fs, inumber, &in);
    // format the root dir, and set the i_mode field to DIR
    inode_format(&in);
    //in.i_mode &= (0xffff - IFMT);
    in.i_mode |= IFDIR;
    inode_iwrite(fs, ROOT_INUMBER, &in);
    
    fs->workDirInumber = ROOT_INUMBER;
    strcpy(fs->workDirName, "/");
    return fs;
}
Exemplo n.º 2
0
int remove_file(struct unixfilesystem *fs, int inumber)
{
  struct inode in;
  int err = inode_iget(fs, inumber, &in);
  if (err < 0) return -1;
  
  if (!(in.i_mode & IALLOC) || ((in.i_mode & IFMT) == IFDIR))
  {
    /* Not allocated or is a directory */
    fprintf(stderr, "The input path is not a file and cannot be removed");
    return -1;
  }
  
  if (in.i_nlink == 1) // only one link, so overwrite the file
  {
    char zeros[DISKIMG_SECTOR_SIZE] = {0};
    int size = inode_getsize(&in);
    int blockNum = 0;
    
    // overwrite the file with zeros
    for (blockNum = 0; blockNum < size / DISKIMG_SECTOR_SIZE; blockNum++)
    {
      char buf[DISKIMG_SECTOR_SIZE];
      
      int blockAddress = inode_indexlookup(fs, &in, blockNum);
      
      if (blockAddress == -1) {
        fprintf(stderr, "Error looking up block number %d in inode %d", blockNum, inumber);
        return -1;
      }
      
      if (diskimg_writesector(fs->dfd, blockAddress, &zeros) == -1)
      {
        fprintf(stderr, "Error overwriting file");
        return -1;
      }
    }
  }
  else  // multiple links to file, so only remove this link
  {
    in.i_nlink--;
    
  }
  
  return 0;
}