Exemple #1
0
/*
 * Remove an existing empty directory and return 0 on success.
 * If the dir does not exist or still contains files, return -1.
 */
int sfs_rmdir(char *dirname)
{
	sfs_dirblock_t currentDir, prevDir, nextDir;
	blkid bid, prevBlkid, nextBlkid;

	/* TODO: check if the dir exists */
	bid = sfs_find_dir(dirname);
	if (bid != 0) {
		// Directory exists
		sfs_read_block((char*)&currentDir, bid);

		/* TODO: check if no files */
		int i;
		for (i = 0; i < SFS_DB_NINODES; i++) 
		{
			if (currentDir.inodes[i] != 0) {
				// directory is not empty
				printf("ERROR: inodes not empty = %d\n", currentDir.inodes[i]);
				return -1;
			}
		}

		/* TODO: go thru the linked list to delete the dir*/
		// Need to change the next_dir pointer of the previous dir and dir to be deleted
		nextBlkid = sb.first_dir;
		if (nextBlkid == bid) {
			// Deleting the root directory
			sb.first_dir = 0;
			sfs_read_block((char*)&currentDir, nextBlkid);						
			currentDir.next_dir = 0;
			memset(currentDir.dir_name, 0, sizeof(currentDir.dir_name));
			return 0;
		} 
		else 
		{
			while (nextBlkid != bid)
			{
				prevBlkid = nextBlkid;
				sfs_read_block((char*)&prevDir, nextBlkid);			
				nextBlkid = prevDir.next_dir;
			}
			nextBlkid = currentDir.next_dir;
		}

		// Remove the directory: update the linked list next_dir variable
		prevDir.next_dir = nextBlkid;
		currentDir.next_dir = 0;
		// Remove the dir_name of the dir to be deleted
		memset(currentDir.dir_name, 0, sizeof(currentDir.dir_name));

		// Flush the removed directory and prevDir
		sfs_write_block((char*)&currentDir, bid);
		sfs_write_block((char*)&prevDir, prevBlkid);
		// Update the freemap so that deleted dir is empty
		sfs_free_block(bid);

		return 0;
	}
	return -1;
}
Exemple #2
0
/*
 * Create a new directory and return 0 on success.
 * If the dir already exists, return -1.
 */
int sfs_mkdir(char *dirname)
{
	/* TODO: test if the dir exists */
	/* TODO: insert a new dir to the linked list */
	blkid nextBlkid;
	sfs_dirblock_t dir, new_dir;

	// Try finding the directory if it exists
	blkid bid = sfs_find_dir(dirname);

	if (bid == 0)
	{
		// Directory does not exists, create a new one
		bid = sfs_alloc_block();
		// Add the new directory to the directory linked list
		nextBlkid = sb.first_dir;

		if (nextBlkid == 0) {
			sb.first_dir = bid;
			sfs_write_block((char*)&sb, 0);
		} 
		else 
		{
			sfs_read_block((char*)&dir, nextBlkid);

			while (dir.next_dir != 0) 
			{
				nextBlkid = dir.next_dir;
				sfs_read_block((char*)&dir, nextBlkid);
			}

			dir.next_dir = bid;
			sfs_write_block((char*)&dir, nextBlkid);
		}
		// Create new directory with next_dir=0 and dir_name
		new_dir.next_dir = 0;
		memset(new_dir.dir_name, 0, sizeof(new_dir.dir_name));	// Empty dir_name
		memset(new_dir.inodes, 0, sizeof(new_dir.inodes));	// Empty inodes
		strcpy(new_dir.dir_name, dirname);	// Copy new dir_name
		sfs_write_block((char*)&new_dir, bid);
		
		return 0;
	}	

	// Directory already exists
	return -1;
}
Exemple #3
0
/*
 * Open a file. If it does not exist, create a new one.
 * Allocate a file desriptor for the opened file and return the fd.
 */
int sfs_open(char *dirname, char *name)
{
	blkid dir_bid = 0, inode_bid = 0;
	char inode_ptr[BLOCK_SIZE];
	sfs_inode_t inode;
	sfs_dirblock_t dir;

	fd_struct_t *fd_ptr;
	fd_struct_t fd;

	//Finds a free file descriptor number
	int fd_num = 0;	

	while(fd_num < SFS_MAX_OPENED_FILES){
		fd = fdtable[fd_num];

		if(fd.valid == 0){
			fd.valid = 1;
			fd.cur = 0;
			
			break;

		} else if(fd_num == SFS_MAX_OPENED_FILES - 1){ 
			printf("The maximum number of files are already in use\n");
			return -1;

		} else{
			fd_num++;	
		}
	}

	
	//Find the directory in which the specified file is contained
	dir_bid = sfs_find_dir(dirname);
	sfs_read_block(&dir, dir_bid);
	fd.dir_bid = dir_bid;

	//Iterate through all the indices of the inodes to find the file
	int count = 0;
	int fd_set = 0;
	int free_inode = -1;
	char *file_name;
	
	while(count < SFS_DB_NINODES){
	
		inode_bid = dir.inodes[count];

		if(inode_bid == 0){
			if(free_inode == -1){
				free_inode = count;
			}
			count++;
			continue;
		}

		//Read the inode at the specified index
		sfs_read_block(inode_ptr, inode_bid);
		inode = *(sfs_inode_t*)inode_ptr;

		file_name = inode.file_name;

		if(strcmp(file_name, name) == 0){
			fd.inode = inode;
			fd.inode_bid = inode_bid;
			fd_set = 1;

			break;
		}
		count++;
	}

	//Create a new file
	if(fd_set == 0){

		//Allocate a block for the inode
		blkid new_inode_bid = sfs_alloc_block();
		
		//Put the inode bid into the directory inode array
		dir.inodes[free_inode] = new_inode_bid;
		sfs_write_block(&dir, dir_bid);

		strcpy(inode.file_name, name);
	
		//Allocate a block for the first frame	
		blkid new_frame_bid = sfs_alloc_block();
		inode.first_frame = new_frame_bid;
		inode.size = 0;

		//Place the inode in the file descriptor array
		fd.inode = inode;
		
		fd.inode_bid = new_inode_bid;

		sfs_write_block(&inode, new_inode_bid);

		sfs_read_block(&inode, new_inode_bid);

		//Allocate a block for the first content block of the frame
		char tmp[BLOCK_SIZE];
		sfs_read_block(tmp, new_frame_bid);
		sfs_inode_frame_t new_frame = *(sfs_inode_frame_t*)tmp;
		
		blkid new_content_bid = sfs_alloc_block();
		new_frame.content[0] = new_content_bid;

		sfs_write_block(&new_frame, new_frame_bid);
	}

	//Set the file descriptor in the file descriptor table	
	fdtable[fd_num] = fd;

	return fd_num;
}
Exemple #4
0
/*
 * Remove an existing empty directory and return 0 on success.
 * If the dir does not exist or still contains files, return -1.
 */
int sfs_rmdir(char *dirname)
{
	/* TODO: check if the dir exists */
	blkid dir_bid = sfs_find_dir(dirname);

	if(dir_bid == 0){
		printf("ERROR sfs_rmdir: Specified directory does not exist\n");
		return -1;
	}

	if(sb.first_dir == 0 || dir_bid == 0){
		//The directory does not exist
		return -1;
	} else{
		//Unset the corresponding bit in the freemap
		sfs_free_block(dir_bid);
	}

	//Find the directories that come before and after the 
	//directory we want to delete
	blkid next_dir = sb.first_dir;		//First block 
	blkid current_dir;					//Current block is sb
	blkid previous_dir = 0;				//No previous blocks
	char block_ptr[BLOCK_SIZE];
	sfs_dirblock_t dir;

	if(next_dir == dir_bid){
		sfs_read_block(block_ptr, next_dir);
		dir = *(sfs_dirblock_t*)block_ptr;

		blkid block_to_copy = dir.next_dir;

		sfs_read_block(&sb, 0);
		sb.first_dir = block_to_copy;
		sfs_write_block(&sb, 0);		
	}

	//General case
	while(next_dir != dir_bid){
		
		previous_dir = current_dir;	
		
		current_dir = next_dir;
		
		sfs_read_block(block_ptr, next_dir);
		dir = *(sfs_dirblock_t*)block_ptr;

		next_dir = dir.next_dir;

		//The next block is what we want to remove
		if(next_dir == dir_bid){
			//Set the next dir of the current block to the next+1 block
			sfs_read_block(block_ptr, next_dir);
			dir = *(sfs_dirblock_t*)block_ptr;
			blkid block_to_copy = dir.next_dir;

			sfs_read_block(block_ptr, current_dir);
			dir = *(sfs_dirblock_t*)block_ptr;
			dir.next_dir = block_to_copy;

			sfs_write_block(&dir, current_dir);				
		}
	}

	return 0;
}
Exemple #5
0
/*
 * Create a new directory and return 0 on success.
 * If the dir already exists, return -1.
 */
int sfs_mkdir(char *dirname)
{
	//Check if the directory has a valid name
	if(sizeof(dirname) > 120){
		printf("Dir name exceeds max allowed characters.\n");
		return -1;
	}

	//Test if the dir exists
	if(sfs_find_dir(dirname) != 0){
		return -1;
	} else{	
		//Initialize variables
		blkid next_dir_id;
		char block_ptr[BLOCK_SIZE];
		sfs_dirblock_t dir;
	
		//Allocate space for a new block
		blkid new_bid = sfs_alloc_block();

		//Set the next_dir in the last directory block
		next_dir_id = sb.first_dir;
		sfs_read_block(block_ptr, next_dir_id);
		dir = *(sfs_dirblock_t*)block_ptr;

		if(next_dir_id == 0){
			sb.first_dir = new_bid;
			sfs_write_block(&sb, 0);
		} else{
			while(next_dir_id != 0){	
				sfs_read_block(block_ptr, next_dir_id);
				dir = *(sfs_dirblock_t*)block_ptr;

				//Next dir is zero, set it to the next available block
				if(dir.next_dir == 0){
					blkid modified_dir_id = next_dir_id;

					sfs_read_block(block_ptr, modified_dir_id);
					dir = *(sfs_dirblock_t*)block_ptr;
										
					dir.next_dir = new_bid;

					//A value was changed, so this must be flushed to disk
					sfs_write_block(&dir, modified_dir_id);
					next_dir_id = 0;

				} else{
					next_dir_id = dir.next_dir;	
				}
			}
		}

		//Create a temporary directory and initialize its members
		//Set the next dir, name, and set all its inodes to zero
		sfs_dirblock_t temp_dir;
		temp_dir.next_dir = 0;
		strcpy(temp_dir.dir_name, dirname);
		memset(&temp_dir.inodes[0], 0, SFS_DB_NINODES * sizeof(blkid));

		//Write the temporary block into the disk
		sfs_write_block(&temp_dir, new_bid);
	}
	return 0;
}
Exemple #6
0
/*
 * Open a file. If it does not exist, create a new one.
 * Allocate a file desriptor for the opened file and return the fd.
 */
int sfs_open(char *dirname, char *name)
{
	blkid dir_bid = 0, inode_bid = 0;
	sfs_inode_t *inode, new_inode;
	sfs_dirblock_t dir;
	int fd;
	int i;

	/* TODO: find a free fd number */
	for (i = 0; i < SFS_MAX_OPENED_FILES; i++)
	{
		if (fdtable[i].valid == 0) 
		{
			// Found a free fd
			fd = i;
			break;
		}
	}

	/* TODO: find the dir first */
	dir_bid = sfs_find_dir(dirname);
	if (dir_bid == 0)
	{
		printf("ERROR: the directory does not exists\n");
		return -1;
	}
	sfs_read_block((char*)&dir, dir_bid);

	/* TODO: traverse the inodes to see if the file exists.
	   If it exists, load its inode. Otherwise, create a new file.
	*/
	for (i = 0; i < SFS_DB_NINODES; i++) 
	{
		if (dir.inodes[i] != 0)
		{
			sfs_read_block((char*)&new_inode, dir.inodes[i]);
			
			if (strcmp(new_inode.file_name, name) == 0) {
				inode_bid = dir.inodes[i];
				break;
			}
		}
	}

	if (inode_bid == 0)
	{
		// Allocate a block to store new inode
		inode_bid = sfs_alloc_block();
		// Find empty space in dir.inodes[] and set inode_bid
		for (i=0; i<SFS_DB_NINODES; i++)
		{
			if (dir.inodes[i] == 0) 
			{
				dir.inodes[i] = inode_bid;
				break;
			}
		}
		// Did not find the inode, create a new one
		new_inode.first_frame = 0;
		new_inode.size = 0;
		memset(new_inode.file_name, 0, sizeof(new_inode.file_name));
		strcpy(new_inode.file_name, name);
		sfs_write_block((char*)&new_inode, inode_bid);
		sfs_write_block((char*)&dir, dir_bid);
	}

	/* TODO: create a new file */
	fdtable[fd].dir_bid = dir_bid;
	fdtable[fd].inode_bid = inode_bid;
	fdtable[fd].inode = new_inode;
	fdtable[fd].cur = 0;
	fdtable[fd].valid = 1;

	return fd;
}