Пример #1
0
int allocate_directory(ino iNode, DirEntry **ppListeFichiers) {
    char iNodeDataBlock[BLOCK_SIZE];
    char directoryDataBlock[BLOCK_SIZE];

    ReadBlock(6 + iNode - 1, directoryDataBlock);
    DirEntry *directory = (DirEntry *)directoryDataBlock;

    if (iNode < 16) {
        ReadBlock(4, iNodeDataBlock);
        iNodeEntry *iNodes = (iNodeEntry *)iNodeDataBlock;
        // If it isn't a directory
        if (!(iNodes[iNode].iNodeStat.st_mode & G_IFDIR)) {
            return -1;
        }
        int directorySizeNumber = iNodes[iNode].iNodeStat.st_size;
        (*ppListeFichiers) = (DirEntry *)malloc(directorySizeNumber);
        memcpy((*ppListeFichiers), directory, directorySizeNumber);
        return NumberofDirEntry(directorySizeNumber);
    } else {
        ReadBlock(5, iNodeDataBlock);
        iNodeEntry *iNodes = (iNodeEntry *)iNodeDataBlock;
        // If it isn't a directory
        if (!(iNodes[iNode].iNodeStat.st_mode & G_IFDIR)) {
            return -1;
        }
        int directorySizeNumber = iNodes[iNode - 16].iNodeStat.st_size;
        (*ppListeFichiers) = (DirEntry *)malloc(directorySizeNumber);
        memcpy((*ppListeFichiers), directory, directorySizeNumber);
        return NumberofDirEntry(directorySizeNumber);
    }

    return -1;
}
Пример #2
0
int bd_rmdir(const char *pFilename) {

  iNodeEntry *pInodeDir = alloca(sizeof(*pInodeDir));
  if (GetINodeFromPath(pFilename, &pInodeDir) == -1)
    return -1;

  if (pInodeDir->iNodeStat.st_mode & G_IFREG)
    return -2;

  const size_t nDir = NumberofDirEntry(pInodeDir->iNodeStat.st_size);
  if (nDir == 2) {
    iNodeEntry *pInodeParent = alloca(sizeof(*pInodeParent));
    char directory[PATH_SIZE];
    if (GetDirFromPath(pFilename, directory) == 0)
      return -1;
    if (GetINodeFromPath(directory, &pInodeParent) == -1)
      return -1;
    pInodeParent->iNodeStat.st_nlink--;

    char filename[FILENAME_SIZE];
    if (GetFilenameFromPath(pFilename, filename) == 0)
      return -1;

    if (RemoveINodeFromINode(filename, pInodeDir, pInodeParent) == -1)
      return -1;

    ReleaseBlockFromDisk(pInodeDir->Block[0]);
    ReleaseINodeFromDisk(pInodeDir->iNodeStat.st_ino);
    return 0;
  }
  return -3;
}
Пример #3
0
static int RemoveINodeFromINode(const char* filename, const iNodeEntry *pSrcInode, iNodeEntry *pDstInode) {
  
  if (!(pDstInode->iNodeStat.st_mode & G_IFDIR))
    return -1;

  char dataBlock[BLOCK_SIZE];
  if (ReadBlock(pDstInode->Block[0], dataBlock) == -1)
    return -1;

  DirEntry *pDirEntry = (DirEntry*)dataBlock;
  if (pDirEntry == NULL)
    return -1;
  
  const ino inode = pSrcInode->iNodeStat.st_ino;
  const size_t nDir = NumberofDirEntry(pDstInode->iNodeStat.st_size);
  size_t i;
  for (i = 0; i < nDir; ++i) {
    if ((pDirEntry[i].iNode == inode) 
	&& (strcmp(pDirEntry[i].Filename, filename) == 0))
      break;
  }
  for (; i< nDir; ++i) {
    pDirEntry[i] = pDirEntry[i + 1];
  }
  pDstInode->iNodeStat.st_size -= sizeof(DirEntry);
  if (WriteBlock(pDstInode->Block[0], dataBlock) == -1)
    return -1;
  return WriteINodeToDisk(pDstInode);
}
Пример #4
0
int numberOfFilesInDirectory(DirEntry *directory) {
    int directoryiNode = directory[0].iNode;
    char currentINodeBlock[BLOCK_SIZE];
    // TODO: Adds condition to check for the good iNode block
    ReadBlock(4, currentINodeBlock);
    iNodeEntry *iNodes = (iNodeEntry *)currentINodeBlock;
    int sizeDir;
    if (directoryiNode >= 0 && directoryiNode < BLOCK_SIZE) {
        sizeDir = NumberofDirEntry(iNodes[directoryiNode].iNodeStat.st_size);
    } else {
        sizeDir = 0;
    }
    return sizeDir;
}
Пример #5
0
int bd_readdir(const char *pDirLocation, DirEntry **ppListeFichiers) {

  iNodeEntry *pInodeDir = alloca(sizeof(*pInodeDir));
  if (GetINodeFromPath(pDirLocation, &pInodeDir) == -1 || pInodeDir->iNodeStat.st_mode & G_IFREG)
    return -1;

  char *dataBlock = NULL;
  if ((dataBlock = malloc(BLOCK_SIZE)) == NULL)
    return -1;
  if (ReadBlock(pInodeDir->Block[0], dataBlock) == -1)
    return -1;

  *ppListeFichiers = (DirEntry *)dataBlock;

  return NumberofDirEntry(pInodeDir->iNodeStat.st_size);
}
Пример #6
0
static int AddINodeToINode(const char* filename, const iNodeEntry *pSrcInode, iNodeEntry *pDstInode) {
  if (!(pDstInode->iNodeStat.st_mode & G_IFDIR))
    return -1;

  char dataBlock[BLOCK_SIZE];
  if (ReadBlock(pDstInode->Block[0], dataBlock) == -1)
    return -1;

  DirEntry *pDirEntry = (DirEntry*)dataBlock;
  if (pDirEntry == NULL)
    return -1;

  const size_t nDir = NumberofDirEntry(pDstInode->iNodeStat.st_size);
  pDirEntry[nDir].iNode = pSrcInode->iNodeStat.st_ino;
  strcpy(pDirEntry[nDir].Filename, filename);
  if (WriteBlock(pDstInode->Block[0], dataBlock) == -1)
    return -1;
  pDstInode->iNodeStat.st_size += sizeof(DirEntry);
  return WriteINodeToDisk(pDstInode);
}
Пример #7
0
static int GetINodeFromPathAux(const char *pFilename, const ino inode, iNodeEntry **pOutInode) {

  iNodeEntry *pInode = alloca(sizeof(*pInode));
  if (GetINode(inode, &pInode) != 0)
    return -1;

  char dirEntryBlock[BLOCK_SIZE];
  if (ReadBlock(pInode->Block[0], dirEntryBlock) == -1)
    return -1;

  DirEntry *pDirEntry = (DirEntry*)dirEntryBlock;
  if (pDirEntry == NULL)
    return -1;

  char *pos = strchr(pFilename, '/');
  char path[FILENAME_SIZE];
  if (pos != NULL) {
    strncpy(path, pFilename, (pos - pFilename));
    path[(pos - pFilename)] = 0;
  } else {
    strcpy(path, pFilename);
  }

  const size_t nDir = NumberofDirEntry(pInode->iNodeStat.st_size);
  size_t i = 0;
  for (; i < nDir; ++i) {
    if (strcmp(pDirEntry[i].Filename, path) == 0) {
      if (GetINode(pDirEntry[i].iNode, pOutInode) != 0)
        return -1;
      if (pos != NULL && strcmp(pos, "/") && ((*pOutInode)->iNodeStat.st_mode & G_IFDIR)) {
        return GetINodeFromPathAux(pos + 1, pDirEntry[i].iNode, pOutInode);
      }
      return pDirEntry[i].iNode;
    }
  }
  return -1;
}
Пример #8
0
int bd_read(const char *pFilename, char *buffer, int offset, int numbytes) {

  iNodeEntry *pInode = alloca(sizeof(*pInode));
  const int inode = GetINodeFromPath(pFilename, &pInode);
  if (inode == -1) {
    printf("Le fichier %s est inexistant!\n", pFilename);
    return -1;
  }
 
  if (pInode->iNodeStat.st_mode & G_IFDIR) {
    printf("Le fichier %s est un repertoire!\n", pFilename);
    return -2;
  }

  if (pInode->iNodeStat.st_size < offset) {
    return 0;
  }

  const size_t firstBlock = offset / BLOCK_SIZE;
  const size_t offsetFirstBlock = offset % BLOCK_SIZE;
  const size_t sizeToRead = min(pInode->iNodeStat.st_size - offset, numbytes);
  const size_t lastBlock = (sizeToRead + offset) / BLOCK_SIZE;
  const size_t offsetLastBlock = (sizeToRead + offset) % BLOCK_SIZE;  

  size_t length[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = BLOCK_SIZE};
  length[lastBlock] = offsetLastBlock;
  length[firstBlock] = min(BLOCK_SIZE - offsetFirstBlock, sizeToRead);

  size_t readOffset[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = 0};
  readOffset[firstBlock] = offsetFirstBlock;

  size_t i, writeOffset = 0;
  for (i = firstBlock; (i <= lastBlock) && (i < N_BLOCK_PER_INODE); ++i) {
    char *dataBlock = alloca(BLOCK_SIZE);
    if (ReadBlock(pInode->Block[i], dataBlock) == -1)
      return -1;
    memcpy(&buffer[writeOffset], &dataBlock[readOffset[i]], length[i]);
    writeOffset += length[i];
  }
  return sizeToRead;
}

int bd_write(const char *pFilename, const char *buffer, int offset, int numbytes) {

  iNodeEntry *pInode = alloca(sizeof(*pInode));
  const int inode = GetINodeFromPath(pFilename, &pInode);
  if (inode == -1) {
    printf("Le fichier %s est inexistant!\n", pFilename);
    return -1;
  }
 
  if (pInode->iNodeStat.st_mode & G_IFDIR) {
    printf("Le fichier %s est un repertoire!\n", pFilename);
    return -2;
  }

  if (offset > pInode->iNodeStat.st_size) {
    printf("L'offset demande est trop grand!\n");
    return -3;
  }

  const size_t maxFileSize = N_BLOCK_PER_INODE * BLOCK_SIZE;
  if (offset >= maxFileSize) {
    printf("Taille trop grande (offset=%ld) pour le fichier %s!\n", maxFileSize, pFilename);
    return -4;
  }
  if ((numbytes + offset) > maxFileSize) {
    printf("Le fichier %s deviendra trop gros!\n", pFilename);
  }

  const size_t firstBlock = offset / BLOCK_SIZE;
  const size_t offsetFirstBlock = offset % BLOCK_SIZE;
  const size_t sizeToWrite = min(numbytes, maxFileSize - offset);
  const size_t lastBlock = (sizeToWrite + offset) / BLOCK_SIZE;
  const size_t offsetLastBlock = (sizeToWrite + offset) % BLOCK_SIZE;
  
  size_t length[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = BLOCK_SIZE};
  length[lastBlock] = offsetLastBlock;
  length[firstBlock] = min(BLOCK_SIZE - offsetFirstBlock, sizeToWrite);

  size_t writeOffset[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = 0};
  writeOffset[firstBlock] = offsetFirstBlock;

  size_t i, readOffset = 0;
  for (i = firstBlock; (i <= lastBlock) && (i < N_BLOCK_PER_INODE); ++i) {
    if (i >= pInode->iNodeStat.st_blocks) {
      int block = 0;
      if ((block = GetFreeBlock()) == -1)
        return -1;
      pInode->Block[i] = block;
      pInode->iNodeStat.st_blocks++;
    }

    char *dataBlock = alloca(BLOCK_SIZE);
    if (ReadBlock(pInode->Block[i], dataBlock) == -1)
      return -1;

    memcpy(&dataBlock[writeOffset[i]], &buffer[readOffset], length[i]);

    if (WriteBlock(pInode->Block[i], dataBlock) == -1)
      return -1;
    readOffset += length[i];
  }

  pInode->iNodeStat.st_size = max(pInode->iNodeStat.st_size, offset + sizeToWrite);
  if (WriteINodeToDisk(pInode) == -1)
    return -1;

  return sizeToWrite;
}

int bd_mkdir(const char *pDirName) {

  char pathOfDir[PATH_SIZE];
  if (GetDirFromPath(pDirName, pathOfDir) == 0)
    return -1;

  char dirName[PATH_SIZE];
  if (GetFilenameFromPath(pDirName, dirName) == 0 || strlen(dirName) > FILENAME_SIZE)
    return -1;

  iNodeEntry *pDirInode = alloca(sizeof(*pDirInode));
  if (GetINodeFromPath(pathOfDir, &pDirInode) == -1 || pDirInode->iNodeStat.st_mode & G_IFREG)
    return -1;
  const size_t nDir = NumberofDirEntry(pDirInode->iNodeStat.st_size);
  if (((nDir + 1) * sizeof(DirEntry)) > BLOCK_SIZE)
    return -1;
  iNodeEntry *pChildInode = alloca(sizeof(*pChildInode));
  if (GetINodeFromPath(pDirName, &pChildInode) != -1)
    return -2;

  if (GetFreeINode(&pChildInode) == -1)
    return -1;

  char dataBlock[BLOCK_SIZE];
  DirEntry *pDirEntry = (DirEntry*)dataBlock;
  strcpy(pDirEntry[0].Filename, ".");
  strcpy(pDirEntry[1].Filename, "..");
  pDirEntry[0].iNode = pChildInode->iNodeStat.st_ino;
  pDirEntry[1].iNode = pDirInode->iNodeStat.st_ino;
  const int idBlocDir = GetFreeBlock();
  if (idBlocDir == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    return -1;
  }
  if (WriteBlock(idBlocDir, dataBlock) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }

  pChildInode->iNodeStat.st_mode |= G_IFDIR | G_IRWXU | G_IRWXG;
  pChildInode->iNodeStat.st_nlink = 2;
  pChildInode->iNodeStat.st_size = 2 * sizeof(DirEntry);
  pChildInode->iNodeStat.st_blocks = 1;
  pChildInode->Block[0] = idBlocDir;
  if (WriteINodeToDisk(pChildInode) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }

  pDirInode->iNodeStat.st_nlink++;

  if (AddINodeToINode(dirName, pChildInode, pDirInode) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }
  return 0;
}