Пример #1
0
void FileSystem::writeInodeEntry(PartitionEntry *partition,
                                 unsigned int inodeNumber) {
  InodeData inode = readInode(partition, lostFoundInode);
  InodeData inode_cur = readInode(partition, inodeNumber);
  int blockNumber = readDataBlocks(partition, lostFoundInode,
                                   (blockSize / SECTOR_SIZE_BYTES),
                                   inode.dataBlocksPointers, 0, 0, 2);
  if (blockNumber == -1)
    return;
  unsigned int blockSector = getBlockSector(partition, blockNumber);
  unsigned char buf[blockSize];
  unsigned int i = 0;
  readSectors(blockSector, (blockSize / SECTOR_SIZE_BYTES), buf);
  while (i < blockSize - 1) {
    struct ext2_dir_entry_2 *fileEntry = (struct ext2_dir_entry_2 *) (buf + i);
    if (fileEntry->rec_len
        > ((((__u16 ) 8 + fileEntry->name_len) + 3) & ~0x03)) {
      fileEntry->rec_len = (((__u16 ) 8 + fileEntry->name_len) + 3) & ~0x03;
      i = i + fileEntry->rec_len;
      fileEntry = (struct ext2_dir_entry_2*) (buf + i);
      fileEntry->inode = inodeNumber;
      sprintf(fileEntry->name, "%d", inodeNumber);
      fileEntry->rec_len = (__u16)(blockSize - i);
      fileEntry->name_len = (__u8)(strlen(fileEntry->name));
      if (!(inode_cur.fileType & EXT2_S_IFREG) == 0)
        fileEntry->file_type = 1;
      else if (!(inode_cur.fileType & EXT2_S_IFDIR) == 0)
        fileEntry->file_type = 2;
      writeSectors(blockSector, (blockSize / SECTOR_SIZE_BYTES), buf);
      return;
    } else {
      i = i + fileEntry->rec_len;
    }
  }
}
Пример #2
0
struct ext2_inode getInode(int fd, int inode_num, struct ext2_group_desc *gds, int p_start, int inodes_per_group)
{
  int x;
  int y;
  int remainder;

  int byte_offset;
  int group_num;
  int sector;
  int sector_offset;

  struct ext2_inode myinode;

  x = inode_num;
  y = inodes_per_group;
  group_num = x / y;
  remainder = fmod(x, y);

  x = remainder;
  y = 4;
  sector_offset = x / y;
  remainder = fmod(x, y);

  sector = gds[group_num].bg_inode_table * 2 + p_start + sector_offset;

  if (remainder > 0)
  {
    byte_offset = (remainder - 1) * 128;
  }
  else { byte_offset = 0; }

  myinode = readInode(fd, sector, byte_offset);
  return myinode;
}
Пример #3
0
void Ext2FS::initFsRoot()
{
    readSuperBlock();

    _blockSize = 1024 << _sb->log_block_size;

    int i = (_sb->block_count / _sb->blocks_per_group) +
            ((_sb->block_count % _sb->blocks_per_group) ? 1 : 0);

    int j = (_sb->inodes_count / _sb->inodes_per_group) +
            ((_sb->inodes_count % _sb->inodes_per_group) ? 1 : 0);

    _groupNumber = (i > j) ? i : j;

    readGroupBlock();

    struct file *rootFile = getRoot();

    struct filePrivateData *data = (struct filePrivateData*)kmalloc(sizeof(struct filePrivateData));

    rootFile->name = (char*)kmalloc(strlen("/") + 1);
    strcpy(rootFile->name, "/");

    data->inum = EXT2_INUM_ROOT;
    data->inode = readInode(EXT2_INUM_ROOT);

    rootFile->content = 0;
    rootFile->privateData = (void*)data;
    rootFile->parent = rootFile;
    rootFile->leaf = getDirEntries(rootFile);
    rootFile->next = 0;
    rootFile->prev = 0;
}
Пример #4
0
/**
 * Opens a binary file on the disk for storing data.
 */
fd_t* openf(char* name)
{
	fd_t * temp = NULL;
	superBlock_t* spB;
	inode_t* nodep;
	readSuperBlock(spB);
	int i=0, j=0;
	while (i<(spB->_numberOfInodes))
	{
	//printSupBlock(spB);
	readInode(nodep, j);
	if (name == nodep->_filename)
		//Exist !! open it!!
	{
		temp->inodeBlockNum = j;
		temp->fileptr = nodep;
		//returns file descriptor
	return 	temp;
	}
	else
	{
		i++;
		j++;
	}
	}
	//printInodesTest(nodep);
	// file not found, create one
	writeSuperBlock(spB);
	writeInode(nodep,spB->_firstBlockOfFreeList);
	return temp;
}
Пример #5
0
bool Ext2FS::isDirectory(struct file *f)
{
    struct filePrivateData *data = (struct filePrivateData*)f->privateData;

    if(!data->inode)
        data->inode = readInode(data->inum);

    return (data->inode->mode & EXT2_DIR);
}
Пример #6
0
char* Ext2FS::readFile(const char *path)
{
	struct file *f = 0;

    if((f = getFile(path)))
	{
        struct filePrivateData *data = (struct filePrivateData*)f->privateData;
        if(!data->inode)
            readInode(data->inum);
        f->size = data->inode->size;
        return readFile(f);
	}
	else
		return 0;
}
/*-----------------------------------------------------------------
Function: scanMinixSubDirectories

Parameters: char *path - name of the subdirectory (with no prefix)
            struct dentry *tbl - pointer to a directory 
	                         table (array of entries)
            struct minix_inode *inoPtr - pointer to memory to store inode
            int parentInoNum  - for passing parent inode number to next iteration
            int *parentInoNum  - for returning the parent inode number of 
	                         leaf directory

Returns: inode number where directory is stored and the parent inode number
         in *parentInoNum.

Description: Recursive function that scans directory to find inode and contents
             of a directory.  Fills in the memory pointed by dirTablePtr
	     with the directory table named "path".  Returns the
	     inode number where the directory table is stored.
-----------------------------------------------------------------*/
int scanMinixSubDirectories(char *path, struct dentry *tbl, 
		            int numrecords, struct minix_inode *inoPtr,
			    int parentInoNum, int *retParentInoNum)
{
   char subDirName[BUFSIZ]; // for loading in the subdirectory name
   char *pt=subDirName; // pointer to copy name
   int ix; // index for seaching through table
   int retcd = ERR1;  // for return code
   struct minix_inode ino;
   struct dentry *nextTbl;

   // Get name to search in directory table (and remove from head of path)
   while(*path!='/' && *path!='\0') *pt++=*path++;
   *pt='\0';  // terminates string
   if(*path == '/') path++; // skips the '/'
   
   // Search for sub directory
   for(ix = 0 ; ix < numrecords ; ix++)
   {
      if((strncmp(subDirName, tbl[ix].name, strlen(subDirName)) == 0)) // found it
      {
         readInode(tbl[ix].ino, &ino); // get inode
         if(*path == '\0') // if at end of path, then found directory 
	 {
            memcpy(inoPtr, &ino, sizeof(struct minix_inode));  // Copy root inode
	    *retParentInoNum = parentInoNum;
	    retcd = tbl[ix].ino;
	 }
	 else // otherwise need to find next subdirectory in path
	 {
            nextTbl = getMinixDirTable(&ino, &numrecords);
            // the following is a recursive function
            retcd = scanMinixSubDirectories(path, nextTbl, numrecords, inoPtr, 
	                                    tbl[ix].ino, retParentInoNum);
            free(nextTbl);  // frees allocated memory
	 }
         break;  // leave the loop
      }
   }
   if(ix == numrecords) // did not find the name in the table
   {
      printf("Could not find subdirectory %s\n", subDirName);
      retcd = ERR1;
   }
   return(retcd);
}
Пример #8
0
void deleteInode(disk_t disk, Inode* inode){
	char * databuf = malloc(sizeof(char) * disk->block_size);
	readblock(disk,inode->block,databuf);
	int i;
	bool gotsize = false;
	bool gotpointers = false;
	bool gotlink = false;
	bool gotname = false;
	int numberbufIndex = 0;
	char * numberbuf = malloc(sizeof(char) * 16);
	for(i = 0; databuf[i] != '\0' && i < disk->block_size;i+=1){
		if(!gotsize){
			if(databuf[i] == '\n'){
				gotsize = true;
			}
		}else if(!gotpointers){
			if(databuf[i] == '\n'){
				gotpointers = true; 
			}
		}else if(!gotname){
			if(databuf[i] == '\n'){
				gotname = true; 
			}
		}else{
			gotlink = true;
			numberbuf[numberbufIndex] = databuf[i];
			numberbufIndex +=1;
		}
	}
	int link;
	if(gotlink){
		numberbuf[numberbufIndex] = '\0';
		link = str2int(numberbuf);
		Inode * newinode = readInode(disk,link);
		deleteInode(disk,newinode);
		freeInode(newinode);
	}
	int * blockmap = read_block_map(disk);
	blockmap[inode->block] = 0;
	write_block_map(disk,blockmap);
	free(blockmap);
	free(databuf);
	free(numberbuf);
}
/*-----------------------------------------------------------------
Function: findInodeFromPath

Parameters: char *path  - full path name of directory/file
	    struct minix_inode *inoPtr - pointer to location for loading inode
	    int *parentInoNum - the inode number of the parent.

Returns:  Inode number or ERR1 when and error occurs. and sets *parentInoNum to
          the value of the parent inode number.

Description: Finds the inode of dir/file and loads it into the struct minix_inode
             referenced by inoPtr.  Retures OK if all went well and ERR1 upon
	     detection of an error. If the directory is not the
	     root directory, the recursive function scanMinixSubDirectories
	     is called to find it.
-----------------------------------------------------------------*/
int findInodeFromPath(char *path, struct minix_inode *inoPtr, int *parentInodeNum)
{
   struct minix_inode ino;
   int inodeNum = 1;  // set do root directory inode number
   int numrecords;
   struct dentry *rootdir;
   readInode(inodeNum, &ino); // get root inode
   if(strcmp(path, "/") == 0)
   {
      memcpy(inoPtr, &ino, sizeof(struct minix_inode));  // Copy root inode
      *parentInodeNum = 1;  // root parent
   }
   else
   {
      if(*path == '/') path++; // skip over the initial /
      rootdir = getMinixDirTable(&ino, &numrecords);
      // the following is a recursive function
      inodeNum = scanMinixSubDirectories(path, rootdir, numrecords, inoPtr, 1, parentInodeNum);
      free(rootdir);  // frees allocated memory
   }
   return(inodeNum);
}
Пример #10
0
/**
 * A test program for testing file system operations.
 *
 * @param args - a list of arguments
*/
int main(int argc, char* argv[])
{
	int error;
	superBlock_t superBlock;
	superBlock_t* spB = &superBlock;
	inode_t node;
	inode_t* nodep = &node;
	initializeInode(nodep);
	char path[25] = "storageDisk";
	if((error = format( 100000, path)))
	{
		printf("There was an error formatting the disk\n");
	}
	printf("\nHello World\n");
	//openDiskFile(path);
	readSuperBlock(spB);
	printSupBlock(spB);
	readInode(nodep, 1);
	printInodesTest(nodep);
	//closeDiskFile();
	return 0;
}
Пример #11
0
void FileSystem::readRootInode(PartitionEntry *partition) {
  unsigned int i;
  InodeData inode = readInode(partition, 2);
  blockSize = 1024 << super_block.s_log_block_size;
  firstRootBataBlock = inode.dataBlocksPointers[0];
  readDataBlocks(partition, 2, 2, inode.dataBlocksPointers, 1, 1, 2);
  readDataBlocks(partition, 2, 2, inode.dataBlocksPointers, 2, 1, 2);
  for (i = 11; i <= super_block.s_inodes_count; i++) {
    InodeData in = readInode(partition, i);
    if (!(in.fileType & EXT2_S_IFDIR) == 0
        && checkInodeBitmap(partition, i) == 1) {
      readDataBlocks(partition, i, -1, in.dataBlocksPointers, 0, 2, 2);
    }
  }
  for (i = 11; i <= super_block.s_inodes_count; i++) {
    unsigned int bitmapValue = checkInodeBitmap(partition, i);
    if (bitmapValue == 1 && inodeMap[i] == 0) {
      InodeData in = readInode(partition, i);
      if (in.fileType != 0) {
        QString tmpStr = QString("Inode ") + QString::number(i)
            + QString(" has invalid entry in inode bitmap. Bitmap value: ")
            + QString::number(bitmapValue) + QString(", collected value:")
            + QString::number(inodeMap[i]) + QString(".\n");
        textBrowser->append(tmpStr);
        errorQt++;
        if (performRepair) {
          writeInodeEntry(partition, i);
        }
      }
    }
  }
  readDataBlocks(partition, 2, 2, inode.dataBlocksPointers, 1, 1, 2);
  readDataBlocks(partition, 2, 2, inode.dataBlocksPointers, 3, 1, 2);
  for (i = 1; i <= super_block.s_inodes_count; i++) {
    InodeData in = readInode(partition, i);
    if (inodeLinkCount[i] != in.hardLinksQt) {
      if (in.fileType != 0) {
        QString tmpStr = QString("Inode ") + QString::number(i)
            + QString(
                " has invalid inode count in inode entry. Current value : ")
            + QString::number(in.hardLinksQt) + QString(", collected value:")
            + QString::number(inodeLinkCount[i]) + QString(".\n");
        textBrowser->append(tmpStr);
        errorQt++;
      }
      if (performRepair) {
        UpdateHardLinkCounter(partition, i, inodeLinkCount[i]);
      }
    }
  }
  readDataBlocks(partition, 2, 2, inode.dataBlocksPointers, 4, 1, 2);
  for (i = 1; i <= super_block.s_blocks_count; i++) {
    unsigned int bitmapValue = checkBlockBitmap(partition, i);
    if (i < firstRootBataBlock && checkBlockBitmap(partition, i) == 0) {
      QString tmpStr =
          QString("Block ") + i
              + QString(
                  " has invalid entry in block bitmap. Bitmap value: 0, collected value: 1.\n");
      textBrowser->append(tmpStr);
      errorQt++;
      if (performRepair) {
        setBlockBitmap(partition, i);
      }
    }
    if (blockMap[i] == 1 && bitmapValue != blockMap[i]) {
      QString tmpStr = QString("Block ") + QString::number(i)
          + QString(" has invalid entry in block bitmap. Bitmap value: ")
          + QString::number(bitmapValue) + QString(", collected value: ")
          + QString::number(blockMap[i]) + QString(".\n");
      textBrowser->append(tmpStr);
      errorQt++;
      if (performRepair) {
        setBlockBitmap(partition, i);
      }
    }
  }
}
Пример #12
0
unsigned int FileSystem::parseFilesystem(PartitionEntry *partition,
                                         unsigned int blockNumber,
                                         unsigned int passNumber,
                                         unsigned int currentInode,
                                         unsigned int parentInode,
                                         int performCheck) {
  unsigned char buf[blockSize];
  unsigned int i = 0;
  struct ext2_dir_entry_2 *fileEntry;
  unsigned int blockSector = getBlockSector(partition, blockNumber);
  readSectors(blockSector, (blockSize / SECTOR_SIZE_BYTES), buf);
  while (i < blockSize - 1) {

    fileEntry = (struct ext2_dir_entry_2 *) (buf + i);

    if (fileEntry->inode == 0)
      return -1;

    if (currentInode == 2 && parentInode == 2
        && (strcmp(fileEntry->name, "lost+found") == 0)) {
      lostFoundInode = fileEntry->inode;
    }

    if (passNumber == 1 && performCheck == 1) {
      if (fileEntry->inode != currentInode
          && (strcmp(fileEntry->name, ".") == 0)) {
        QString tmpStr = QString("Entry '.' has inode ")
            + QString::number(fileEntry->inode) + QString(" instead of ")
            + QString::number(currentInode) + QString(".\n");
        textBrowser->append(tmpStr);
        errorQt++;
        fileEntry->inode = currentInode;
        writeSectors(blockSector, (blockSize / SECTOR_SIZE_BYTES), buf);
      }
      if (fileEntry->inode != parentInode && (!strcmp(fileEntry->name, ".."))) {
        QString tmpStr = QString("Entry '..' has inode ")
            + QString::number(fileEntry->inode) + QString(" instead of ")
            + QString::number(parentInode) + QString(".\n");
        textBrowser->append(tmpStr);
        errorQt++;
        fileEntry->inode = parentInode;
        writeSectors(blockSector, (blockSize / SECTOR_SIZE_BYTES), buf);
      }
    } else if (passNumber == 2 && performCheck == 1) {
      inodeMap[fileEntry->inode] = 1;
    } else if (passNumber == 3 && performCheck == 1) {
      inodeLinkCount[fileEntry->inode] += 1;
    } else if (passNumber == 4 && performCheck == 1) {
      blockMap[blockNumber] = 1;
    }

    if (strcmp(fileEntry->name, ".") && strcmp(fileEntry->name, "..")
        && performCheck != 0) {
      if (performCheck == 2) {
        inodeMap[fileEntry->inode] = 1;
      }
      InodeData inode = readInode(partition, fileEntry->inode);
      if ((inode.fileType & 0xF000) == EXT2_S_IFREG && passNumber == 4) {
        readDataBlocks(partition, fileEntry->inode, currentInode,
                       inode.dataBlocksPointers, passNumber, performCheck, 1);
      } else if (!(inode.fileType & EXT2_S_IFDIR) == 0) {
        readDataBlocks(partition, fileEntry->inode, currentInode,
                       inode.dataBlocksPointers, passNumber, performCheck, 2);
      }
    }
    i = i + fileEntry->rec_len;
  }
  if (fileEntry != NULL && fileEntry->rec_len > 8 + fileEntry->name_len
      && (fileEntry->rec_len - 8 - fileEntry->name_len) > 16 && !performCheck)
    return blockNumber;
  return -1;
}
Пример #13
0
struct file* Ext2FS::getFile(const char *filename)
{
    char *name;
    const char *beg_p, *end_p;
    struct file *file;
    struct filePrivateData *data;

	// TODO: Faire le reste !
	/*if(path[O] != '/')
		fp = current->pwd;
	else*/
        file = getRoot();

	beg_p = filename;

	while(*beg_p == '/')
		beg_p++;
    end_p = beg_p + 1;

	while(*beg_p != 0)
	{
        data = (struct filePrivateData*)file->privateData;

        if(!data->inode)
            data->inode = readInode(data->inum);

		if(!isDirectory(file))
			return 0;

		while(*end_p != 0 && *end_p != '/')
			end_p++;

		name = (char*)kmalloc(end_p - beg_p + 1);
		memcpy(name, beg_p, end_p - beg_p);
		name[end_p - beg_p] = 0;

		if(strcmp("..", name) == 0)
			file = file->parent;
		else if(strcmp(".", name) == 0)
			{}
		else
        {
            //Screen::getScreen().printError("Filename : %s, dir : %s, inum %u", name, file->name, data->inum);
            //Screen::getScreen().printError("Data inode size : %u", data->inode->size);
            getDirEntries(file);

            //Screen::getScreen().printError("Filename : %s, dir : %s", name, file->name);

			if(!(file = isCachedLeaf(file, name)))
            {
                kfree(name);
				return 0;
            }
		}

		beg_p = end_p;

		while(*beg_p == '/')
			beg_p++;

        end_p = beg_p + 1;

        kfree(name);
	}

	return file;
}
Пример #14
0
struct file* Ext2FS::getDirEntries(struct file *dir)
{
    struct directory_entry *dentry;
    struct filePrivateData *data = (struct filePrivateData*)dir->privateData;
    struct file *firstLeaf, *leaf, *prevLeaf;

	u32 dsize;

    char *filename;

	bool fileToClose;

    if(!data->inode)
        data->inode = readInode(data->inum);


    //Screen::getScreen().printError("DirData : %d, %d", data->inode->size, data->inum);

	if(!isDirectory(dir))
	{
        Screen::getScreen().printError("%s isn't a directory !", dir->name);
		return 0;
	}

    if(!dir->content)
	{
        dir->content = readFile(dir);
		fileToClose = true;
	}
	else
		fileToClose = false;

    dsize = data->inode->size;
    dentry = (struct directory_entry*) dir->content;

	firstLeaf = prevLeaf = dir->leaf;

	while(dentry->inode && dsize)
	{
		filename = (char*)kmalloc(dentry->name_len + 1);
        memcpy(filename, &(dentry->name), dentry->name_len);
        filename[dentry->name_len] = 0;

		if(strcmp(".", filename) && strcmp("..", filename))
		{
			if(!(leaf = isCachedLeaf(dir, filename)))
			{
                struct filePrivateData *privData = (struct filePrivateData*)kmalloc(sizeof(struct filePrivateData));

				leaf = (struct file*)kmalloc(sizeof(struct file));
				leaf->name = (char*)kmalloc(dentry->name_len + 1);
                strcpy(leaf->name, filename);

                //Screen::getScreen().printDebug("Name : %s", filename);
                //Screen::getScreen().printDebug("Dentry : %x, %u, %c, %u, %u", dentry->file_type, dentry->inode, 'c', dentry->name_len, dentry->record_entry);

                privData->inum = dentry->inode;
                privData->inode = readInode(dentry->inode);

                leaf->size = privData->inode->size;
                leaf->content = 0;
				leaf->parent = dir;
				leaf->leaf = 0;
                leaf->privateData = privData;

				if(prevLeaf)
				{
					leaf->next = prevLeaf->next;

					if(prevLeaf->next)
						prevLeaf->next->prev = leaf;

					prevLeaf->next = leaf;
					leaf->prev = prevLeaf;
				}
				else
				{
					leaf->next = 0;
					leaf->prev = 0;
					firstLeaf = leaf;
				}
			}

			prevLeaf = leaf;
		}


        kfree(filename);

		dsize -= dentry->record_entry;
		dentry = (struct directory_entry*) ((char*) dentry + dentry->record_entry);
	}

	dir->leaf = firstLeaf;

	if(fileToClose)
	{
        kfree(dir->content);
        dir->content = 0;
	}

	return firstLeaf;
}
Пример #15
0
Inode* readInode(disk_t disk, int block){
	char * databuf = malloc(sizeof(char) * disk->block_size);
	readblock(disk,block,databuf);
	int size;
	int i,j;
	char * name;
	bool gotsize = false;
	bool gotpointers = false;
	bool gotlink = false;
	bool gotname = false;
	int numberbufIndex = 0;
	char * numberbuf = malloc(sizeof(char) * 16);
	int * pointers = malloc(sizeof(int) * disk->size);
	int pointersIndex = 0;
	for(i = 0; databuf[i] != '\0' && i < disk->block_size;i+=1){
		if(!gotsize){
			if(databuf[i] == '\n'){
				numberbuf[numberbufIndex] = '\0';
				size = str2int(numberbuf);
				numberbufIndex = 0;
				gotsize = true;
			}else{
				numberbuf[numberbufIndex] = databuf[i];
				numberbufIndex +=1;
			}
		}else if(!gotpointers){
			if(databuf[i] == '\n'){
				gotpointers = true; 
				numberbuf[0] = '\0';
				numberbufIndex = 0;
			}else{
				if(databuf[i] == ','){
					numberbuf[numberbufIndex] = '\0';
					pointers[pointersIndex] = str2int(numberbuf);
					numberbufIndex = 0;
					pointersIndex +=1;
				}else{
					numberbuf[numberbufIndex] = databuf[i];
					numberbufIndex +=1;
				}
			}
		}else if(!gotname){
			if(databuf[i] == '\n'){
				name = malloc(sizeof(char) * (numberbufIndex+1));
				for(j = 0; j < numberbufIndex; j+=1){
					name[j] = numberbuf[j];
				}
				name[j] = '\0';
				gotname = true;
				numberbufIndex = 0;
			}else{
				numberbuf[numberbufIndex]= databuf[i];
				numberbufIndex +=1;
			}
		}
		else{
			gotlink = true;
			numberbuf[numberbufIndex] = databuf[i];
			numberbufIndex +=1;
		}
	}
	int link;
	if(gotlink){
		numberbuf[numberbufIndex] = '\0';
		link = str2int(numberbuf);
		Inode * newinode = readInode(disk,link);
		for(i = 0; newinode->pointers[i] != '\0';i+=1){
			pointers[pointersIndex] = newinode->pointers[i];
			pointersIndex+=1;
		}
		freeInode(newinode);
	}
	int * pointersSmall = malloc(sizeof(int) * (pointersIndex+1));
	for(i = 0; i < pointersIndex;i+=1){
		pointersSmall[i] = pointers[i];
	}
	pointersSmall[i] = '\0';
	Inode * node = createInode(size,pointersSmall,(size ==0)? true : false, block,name);
	free(numberbuf);
	free(databuf);
	free(pointers);
	//free(pointersSmall);
	return node;

}