Ejemplo n.º 1
0
le32 LinnCreate::createInode(char *inputFile, struct stat *st)
{
    LinnGroup *group;
    LinnInode *inode;
    BitArray inodeMap(super->inodesPerGroup);
    u32 gn, in;

    /* Loop all available LinnGroups. */
    for (gn = 0; gn < LINN_GROUP_COUNT(super); gn++)
    {
	/* Point to the correct LinnGroup. */
	group = BLOCKPTR(LinnGroup, super->groupsTable) + gn;
	
	/* Does it have any free inodes? */
	if (!group->freeInodesCount)
	{
	    group = ZERO;
	    continue;
	}
	else
	    break;
    }
    /* Did we find an appropriate group? */
    if (!group)
    {
	printf("%s: no free inode available for `%s'\n",
		prog, inputFile);
	exit(EXIT_FAILURE);
    }
    /* Find an empty inode number. */
    inodeMap.setArray(BLOCKPTR(u8, group->inodeMap),
		    super->inodesPerGroup);
    in = inodeMap.setNext();

    /* Instantiate the inode. */
    inode = createInode(in, FILETYPE_FROM_ST(st),
			    FILEMODE_FROM_ST(st), st->st_uid, st->st_gid);

    /* Insert file contents. */
    if (S_ISREG(st->st_mode))
    {
	insertFile(inputFile, inode, st);
    }
    /* Debug out. */
    if (verbose)
    {
	printf("%s inode=%u size=%u\n", inputFile, in, inode->size);
    }
    return in;
}
Ejemplo n.º 2
0
int LinnCreate::create(Size blockSize, Size blockNum, Size inodeNum)
{
    LinnGroup *group;
    BitArray map(128);

    assert(image != ZERO);
    assert(prog  != ZERO);
    assert(blockNum >= 2);
    assert(inodeNum > 0);

    /* Allocate blocks. */
    blocks = new u8[blockSize * blockNum];
    memset(blocks, 0, blockSize * blockNum);

    /* Create a superblock. */
    super = (LinnSuperBlock *) (blocks + LINN_SUPER_OFFSET);
    super->magic0 = LINN_SUPER_MAGIC0;
    super->magic1 = LINN_SUPER_MAGIC1;
    super->majorRevision    = LINN_SUPER_MAJOR;
    super->minorRevision    = LINN_SUPER_MINOR;
    super->state            = LINN_SUPER_VALID;
    super->blockSize        = blockSize;
    super->blocksPerGroup   = LINN_CREATE_BLOCKS_PER_GROUP;
    super->inodesCount      = inodeNum;
    super->blocksCount	    = blockNum;
    super->inodesPerGroup   = super->inodesCount / LINN_GROUP_COUNT(super);
    super->freeInodesCount  = super->inodesCount;
    super->freeBlocksCount  = blockNum - 3;
    super->creationTime     = time(ZERO);
    super->mountTime	    = ZERO;
    super->mountCount	    = ZERO;
    super->lastCheck	    = ZERO;
    super->groupsTable	    = 2;

    /* Allocate LinnGroups. */
    for (Size i = 0; i < LINN_GROUP_COUNT(super); i++)
    {
	/* Point to the correct LinnGroup. */
	group = BLOCKPTR(LinnGroup, 2) + i;

	/* Fill the group. */
	group->freeBlocksCount = super->blocksPerGroup;
	group->freeInodesCount = super->inodesPerGroup;
	group->blockMap        = BLOCKS(super, LINN_GROUP_NUM_BLOCKMAP(super));
	group->inodeMap        = BLOCKS(super, LINN_GROUP_NUM_INODEMAP(super));
	group->inodeTable      = BLOCKS(super, LINN_GROUP_NUM_INODETAB(super));
    }
    /* Create special inodes. */
    createInode(LINN_INODE_ROOT, DirectoryFile,
		OwnerRWX | GroupRX | OtherRX);
    createInode(LINN_INODE_LOADER, RegularFile,
		OwnerRWX | GroupRX | OtherRX);
    createInode(LINN_INODE_BAD, RegularFile,
		OwnerRW | GroupR | OtherR);
    createInode(LINN_INODE_JOURNAL, RegularFile,
		OwnerRW | GroupR | OtherR);

    /* Insert into directory contents, if set. */
    if (input)
    {
	insertDirectory(input, LINN_INODE_ROOT,
			       LINN_INODE_ROOT);
    }
    /* Mark blocks used. */
    for (le32 block = 0; block < super->freeBlocksCount; block++)
    {
	/* Point to group. */
	group = BLOCKPTR(LinnGroup, super->groupsTable) +
			(block / super->blocksPerGroup);
	group->freeBlocksCount--;
	
	/* Mark the block used. */
	map.setArray(BLOCKPTR(u8, group->blockMap),
		   super->blocksPerGroup);
	map.set(block % super->blocksPerGroup);
    }
    /* Write the final image. */
    return writeImage();
}    
Ejemplo n.º 3
0
void LinnCreate::insertDirectory(char *inputDir, le32 inodeNum, le32 parentNum)
{
    struct dirent *ent;
    struct stat st;
    DIR *dir;
    char path[255];
    le32 child;
    bool skip = false;

    /* Create '.' and '..' */
    insertEntry(inodeNum, inodeNum,  ".",  DirectoryFile);
    insertEntry(inodeNum, parentNum, "..", DirectoryFile);

    /* Open the input directory. */
    if ((dir = opendir(inputDir)) == NULL)
    {
	printf("%s: failed to opendir() `%s': %s\n",
		prog, inputDir, strerror(errno));
	exit(EXIT_FAILURE);
    }
    /* Read all it's entries. */
    while ((ent = readdir(dir)))
    {
	/* Hidden files. */
	skip = ent->d_name[0] == '.';
	
	/* Excluded files. */
	for (ListIterator<String *> e(&excludes); e.hasCurrent(); e++)
	{
            String dent = (const char *) ent->d_name;

	    if (dent.match(**e.current()))
	    {
		skip = true;
		break;
	    }
	}
	/* Skip file? */
	if (skip) continue;
	
	/* Construct local path. */
	snprintf(path, sizeof(path), "%s/%s",
		 inputDir, ent->d_name);

	/* Stat the file. */
	if (stat(path, &st) != 0)
	{
	    printf("%s: failed to stat() `%s': %s\n",
		    prog, path, strerror(errno));
	    exit(EXIT_FAILURE);
	}
	/* Create an inode for the child. */
	child = createInode(path, &st);
	
	/* Insert directory entry. */
	insertEntry(inodeNum, child, ent->d_name,
		    FILETYPE_FROM_ST(&st));
	
	/* Traverse down. */
	if (S_ISDIR(st.st_mode))
	{
	    insertDirectory(path, child, inodeNum);
	}
    }
    /* All done. */
    closedir(dir);
}
Ejemplo n.º 4
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;

}
Ejemplo n.º 5
0
//max name size = 15
//will modify block_map
Inode* writeInode(disk_t disk, int block, int * gpointers,bool directory, char * nametemp){
	int * blkmap = read_block_map(disk);
	blkmap[block] = 1;
	write_block_map(disk,blkmap);
	
	int size = arrayLength(gpointers);
	int maxsize = (disk->block_size-20-(ceil(log10(disk->size))*2)/(ceil(log10(disk->size))+1));
	int * pointers = malloc(sizeof(int) * (size+1));
	int i,j;
	int strlength = length(nametemp);
	char * name = malloc(sizeof(char)*  16);
	for(i = 0; i < 15 && nametemp[i] != '\0';i+=1){
		name[i] = nametemp[i];
	}
	name[i] = '\0';
	int * wpointers = malloc(sizeof(int) * (size + 1));
	for(i = 0; i < size; i+=1){
		pointers[i] = gpointers[i];
		wpointers[i] = gpointers[i];
	}
	wpointers[i] = '\0';
	pointers[i] = '\0';
	char * potSize;
	if(size > (maxsize)){ //-4 for 3 \n and 1 \0 - 16 for name length
		int * newpointers = malloc(sizeof(int) * (maxsize+1));
		int * extrapointers = malloc(sizeof(int) * (size-maxsize+1));
		for(i = 0; i < maxsize;i+=1){
			newpointers[i] = pointers[i];
		}
		newpointers[i] = '\0';
		free(wpointers);
		wpointers = newpointers;
		for(j = 0; j <size-maxsize;j+=1){
			extrapointers[j] = pointers[i];
			i+=1;
		}
		
		extrapointers[j] = '\0';
		int newblk;
		
		for(i = 0; i < disk->size;i+=1){
			if(blkmap[i] == 0){
				newblk = i;
				break;
			}
		}
		freeInode(writeInode(disk,newblk,extrapointers,directory,name));
	}
	unsigned char *strings[6];
	potSize = int2str(size);
	strings[0] = (directory)? "0" : potSize;

	char * list = intArray2charArray(wpointers);
	char * pntrs = malloc(sizeof(char) * (length(list)+2));
	pntrs[0] = '\n';

	pntrs[1] = '\0';
	strcat(pntrs,list);
	strings[1] = pntrs;
	strings[2] = "\n";
	strings[3] = name;
	strings[4] = "\n";
	strings[5] = NULL;
	
	unsigned char *databuf = calloc(disk->block_size, sizeof(unsigned char) );
	copy2buf(databuf,strings,0);
	writeblock(disk,block,databuf);
	free(list);
	free(pntrs);
	free(databuf);
	//free(name);
	free(blkmap);
	free(potSize);
	free(wpointers);
	return createInode(size,pointers,directory,block,name);
}
Ejemplo n.º 6
0
int serverCreate(int pinum, int type, char* name){
  //take care of error cases
  if((type != MFS_DIRECTORY && type != MFS_REGULAR_FILE) || pinum > 4095 || pinum < 0)
    return -1;
 
  //if name is too long return -1
  if(strlen(name) < 1 || strlen(name) > 28)
    return -1;
  
  //if pinum dne return -1
  if(inodeMap.inodes[pinum] == -1)
    return -1;

  //if file already exists, return success  
  if(serverLookup(pinum, name) >= 0)
    return 0;

  //get pinum address
  int pinumLocation = inodeMap.inodes[pinum];

  //lseek to this location
  lseek(diskFD, pinumLocation, 0);
  
  //we have just lseeked to the inode, we need to read the inode
  MFS_Inode pInode;
  int bytesRead = read(diskFD,&pInode, sizeof(pInode));
  
  //check if this is a directory or not
  if(pInode.stats.type != MFS_DIRECTORY){
    return -1;
  }
  
  if(pInode.stats.size >= (MFS_BLOCK_SIZE * 14*128)){
     return -1;
  }
  
  int newInum = createInode(pinum,type);
  
  //get the directoryBlockIndex in inode
  int inodeDirBlockIndex = (int) pInode.stats.size/(MFS_BLOCK_SIZE*128);
  
 
  //potential error case
  if(inodeDirBlockIndex < 0 ||inodeDirBlockIndex > 14){
    return -1;
  }
 
  //this is the last full index
  int dirBlockIndex = (int) (pInode.stats.size/(MFS_BLOCK_SIZE) %128);
  pInode.stats.size += MFS_BLOCK_SIZE;
 
 
  if(dirBlockIndex < 0){
    return -1;
  }

  //take care of case where directory index is full
  //need new directory block
  if(dirBlockIndex == 0){
    pInode.blockPtrs[inodeDirBlockIndex] = ckptregion.endLog;
    MFS_Dir_Block freshDirBlock;
    int k;
    for(k = 0; k < 128; k++){
      memcpy(freshDirBlock.dirEntries[k].name, "\0", sizeof("\0"));
      freshDirBlock.dirEntries[k].inum = -1;
    }
    lseek(diskFD, ckptregion.endLog, 0);
    write(diskFD, &freshDirBlock, sizeof(freshDirBlock));
    
    //update endlog and write out the checkpoint
    ckptregion.endLog += MFS_BLOCK_SIZE;
    lseek(diskFD, 0, 0);
    write(diskFD, &ckptregion, sizeof(ckptregion));   
  }
  
  //IMPORTANT
  //write out the inode here. Either way, inode needs to be written out since size is updated
  //do it here because if we need to update the block ptrs, that happens just before this
  lseek(diskFD, pinumLocation, 0);
  write(diskFD, &pInode, sizeof(pInode));
 
  memLoad();

  lseek(diskFD, pInode.blockPtrs[inodeDirBlockIndex], 0);
  MFS_Dir_Block dirBlock;
  bytesRead = read(diskFD,&dirBlock, sizeof(dirBlock));
  
  //set the name etc
  int newIndex = dirBlockIndex;
  memcpy(dirBlock.dirEntries[newIndex].name, "\0", sizeof("\0"));
  memcpy(dirBlock.dirEntries[newIndex].name, name, 28);
  dirBlock.dirEntries[newIndex].inum = newInum;
 
  //write out updated directory block to disk
  lseek(diskFD, pInode.blockPtrs[inodeDirBlockIndex], 0);
  write(diskFD, &dirBlock, sizeof(dirBlock));
  
  /************************************************************************/
  //fsync(diskFD); 
  /************************************************************************/
  memLoad();
  return 0;
}