Пример #1
0
int remove_file(struct inode *dir, const char *name){
	/*判断目录是否有效*/
	if(dir->ext2_inode.i_block[0] != UINT_MAX){
		perror("inode_operations.c: remove_file error! current dir is a file!\n");
		return -1;
	}
	/*判断名字是否有效*/
	if(checkname(name) == -1){
		perror("inode_operations.c: remove_file error! filename is illegal!\n");
		return -1;
	}
	char buf[BLOCK_SIZE];
	struct ext2_dir_entry_2 *pentry;
	int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/
	int i = 1;
	int j = 0;
	int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2);
	while(i <= dir_datablocks){
		/*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/
		get_block_data(dir->ext2_inode.i_block[i],buf);
		pentry = (struct ext2_dir_entry_2 *)buf;
		//printf("inode_operations.c: check : dir_datablocks: %d\n",i);
		/*比较每一项*/
		while(j<num){
			//printf("inode_operations.c: check : entry: %d\n",j);
			/*比较pentry->inode不为0的每一项*/
			if(pentry->inode && !strcmp(pentry->name,name)){
				if(free_inode(pentry->inode) == -1){
					perror("节点释放失败!\n");
					return -1;
				};
				/*清空该目录项*/
				memset(pentry,'\0',sizeof(struct ext2_dir_entry_2));
				/*写回磁盘,更新数据*/
				write_block_data(dir->ext2_inode.i_block[i],buf);
				return 1;
			}
			j++;
			pentry++;
		}
		i++;
	}
	printf("no such file,please check your filename!\n");
	return -1;
}
Пример #2
0
int create(struct inode *dir, const char *name, int len, int mode, struct inode ** res_inode){
	/*判断目录是否有效*/
	if(dir->ext2_inode.i_block[0] != UINT_MAX){
		perror("inode_operations.c: create error! dir is a file!\n");
		return -1;
	}
	/*判断名字是否有效*/
	if(checkname(name) == -1){
		perror("inode_operations.c: create error! filename is illegal!\n");
		return -1;
	}
	/*判断是否已存在*/
	if(is_exist(dir,name) == 1){
		perror("inode_operations.c: create error! file is alreay exists!\n");
		return -1;
	}
	char buf[BLOCK_SIZE];
	struct ext2_dir_entry_2 *pentry;
	int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/
	int i = 1;
	int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2);
	while(i <= dir_datablocks){
		/*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/
		get_block_data(dir->ext2_inode.i_block[i],buf);
		pentry = (struct ext2_dir_entry_2 *)buf;
		/*寻找pentry->inode为0的每一项,表示未使用,填写目录项*/
		//printf("inode_operations.c: create : dir_datablocks: %d\n",i);
		int j = 0;
		while(j<num){
			//printf("inode_operations.c: create : entry: %d\n",j);
			if(!pentry->inode){
				pentry->name_len = len;
				strcpy(pentry->name,name);
				pentry->file_type = mode;
				pentry->rec_len = 8 + len;
				pentry->inode = new_inode();
				write_block_data(dir->ext2_inode.i_block[i],buf);//更新该数据块
				*res_inode=(struct inode *)malloc(sizeof(struct inode));
				if(*res_inode != NULL){
					get_inode_data(pentry->inode,*res_inode);
					return 1;
				}
			}
			j++;
			pentry++;
		}
		i++;
	}
	/*数据块表项已满,则需申请新的数据块来存放新的目录项*/
	if(dir_datablocks>=14){
		perror("inode_operations.c create error! dir_entry is full,no more sub_dir!\n");
		return -1;
	}
	dir_datablocks = ++(dir->ext2_inode.i_blocks);
	dir->ext2_inode.i_block[dir_datablocks] = new_block();
	write_inode_data(dir->i_number,dir);//因为申请了新块,inode节点及时更新

	get_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);
	pentry = (struct ext2_dir_entry_2 *)buf;
	pentry->name_len = len;
	strcpy(pentry->name,name);
	pentry->file_type = mode;
	pentry->rec_len = 8 + len;
	pentry->inode = new_inode();
	write_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);//更新该数据块
	if((*res_inode=(struct inode *)malloc(sizeof(struct inode))) != NULL){
		get_inode_data(pentry->inode,*res_inode);
		return 1;
	}
	return -1;
}
Пример #3
0
int mkdir(struct inode *dir, const char *name, int len, int mode){
	/*判断目录是否有效*/
	if(dir->ext2_inode.i_block[0] != UINT_MAX){
		perror("inode_operations.c: mkdir error! dir is a file!\n");
		return -1;
	}
	/*判断名字是否有效*/
	if(checkname(name) == -1){
		perror("inode_operations.c: mkdir error! dirname is illegal!\n");
		return -1;
	}
	/*判断是否已存在*/
	if(is_exist(dir,name) == 1){
		perror("inode_operations.c: mkdir error! dirname is alreay exists!\n");
		return -1;
	}
	char buf[BLOCK_SIZE];
	struct inode *m_inode;
	struct ext2_dir_entry_2 *pentry;
	int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/
	int i = 1;
	int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2);
	while(i <= dir_datablocks){
		/*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/
		get_block_data(dir->ext2_inode.i_block[i],buf);
		pentry = (struct ext2_dir_entry_2 *)buf;
		
		/*寻找pentry->inode为0的每一项,表示未使用*/
		int j = 0;
		while(j<num){
			if(!pentry->inode){
				pentry->name_len = len;
				strcpy(pentry->name,name);
				pentry->file_type = mode;
				pentry->rec_len = 8 + len;
				pentry->inode = new_inode();
				write_block_data(dir->ext2_inode.i_block[i],buf);//更新该数据块
				/*下面更新为目录项(文件夹)申请的inode节点信息,并为其预分配一块数据块,用于存放子目录或文件*/
				if((m_inode=(struct inode*)malloc(sizeof(struct inode))) != NULL){
					get_inode_data(pentry->inode,m_inode);
					m_inode->ext2_inode.i_block[0] = UINT_MAX;//表示该节点是目录节点
					m_inode->ext2_inode.i_block[1] = new_block();//为每个目录节点预分配一块数据块,存放目录项
					m_inode->ext2_inode.i_blocks = 1;		
					write_inode_data(pentry->inode,m_inode);
					free(m_inode);
					return 1;
				}
			}
			j++;
			pentry++;
		}
		i++;
	}
	/*数据块表项已满,则需申请新的数据块来存放新的目录项*/
	if(dir_datablocks>=14){
		perror("inode_operations.c mkdir error! dir_entry is full,no more sub_dir!\n");
		return -1;
	}
	dir_datablocks = ++dir->ext2_inode.i_blocks;
	dir->ext2_inode.i_block[dir_datablocks] = new_block();
	write_inode_data(dir->i_number,dir);//因为申请了新块,inode节点及时更新

	get_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);
	pentry = (struct ext2_dir_entry_2 *)buf;
	pentry->name_len = len;
	strcpy(pentry->name,name);
	pentry->file_type = mode;
	pentry->rec_len = 8 + len;
	pentry->inode = new_inode();
	write_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);//更新该数据块
	
	if((m_inode=(struct inode*)malloc(sizeof(struct inode))) != NULL){
		get_inode_data(pentry->inode,m_inode);
		m_inode->ext2_inode.i_block[0] = UINT_MAX;//表示该节点是目录节点
		m_inode->ext2_inode.i_block[1] = new_block();//为每个目录节点预分配一块数据块,存放目录项
		m_inode->ext2_inode.i_blocks = 1;		
		write_inode_data(pentry->inode,m_inode);
		free(m_inode);
		return 1;
	}

	return -1;
}
Пример #4
0
/**
 * Write a file into a buffer.
 *
 * \param fh File handle opened for writing or appending
 * \param data Data to write.
 * \param size Amount of data to write (becomes filesize)
 */
void write(file_handle_t* fh, const fdata_t* data, size_t size)
{
	if (fh->type == FH_WRITE || fh->type == FH_APPEND)
	{
		/*
		 * Handle non-complete blocks for appending
		 */
		if (fh->type == FH_APPEND
				&& fh->filesize % EEPROM_FS_BLOCK_DATA_SIZE > 0)
		{
			// Last block of current file is incomplete. Prepend it to the new data.
			size_t overflow = fh->filesize % EEPROM_FS_BLOCK_DATA_SIZE;
			fdata_t* to_write[overflow + size];

			// Read from last block
			file_handle_t last_block_fh = *fh;
			last_block_fh.first_block = last_block_in_chain(
					alloc_table[fh->filename].data_block);
			last_block_fh.filesize = overflow;
			read(&last_block_fh, (fdata_t*) to_write);

			// Copy new data in to new array
			uintptr_t offset = (uintptr_t) to_write
					+ (uintptr_t) (overflow * sizeof(fdata_t));
			memcpy((void*) offset, data, size * sizeof(fdata_t));

			// Update existing variables
			data = (const fdata_t*) to_write;
			size = overflow + size;
		}

		_fs_debug1("Writing %d bytes to file %d.\n", size, fh->filename);

		size_t num_blocks;

		// Don't allow any files bigger than max blocks
		size_t blocks_in_use = alloc_table[fh->filename].filesize
				/ EEPROM_FS_BLOCK_DATA_SIZE;
		if (blocks_in_use + size / EEPROM_FS_BLOCK_DATA_SIZE
				> EEPROM_FS_MAX_BLOCKS_PER_FILE)
		{
			num_blocks = EEPROM_FS_MAX_BLOCKS_PER_FILE - blocks_in_use;
			_fs_error("File too large - write truncated to %d bytes.\n",
					num_blocks * EEPROM_FS_BLOCK_DATA_SIZE);
		}
		else
		{
			num_blocks = (size / EEPROM_FS_BLOCK_DATA_SIZE) + 1;
		}

		if (num_blocks > 0)
		{
			/*
			 * Split data into blocks
			 */
			block_t block;
			size_t num_bytes = EEPROM_FS_BLOCK_DATA_SIZE;

			fh->first_block = *next_free_block;
			for (uint16_t i = 0; i < num_blocks; i++)
			{
				// Don't write more than file's size
				if ((i + 1) * EEPROM_FS_BLOCK_DATA_SIZE > size)
				{
					num_bytes = size % EEPROM_FS_BLOCK_DATA_SIZE;
				}

				// Copy data for this block
				for (uint16_t j = 0; j < num_bytes; j++)
				{
					block.data[j] = data[i * EEPROM_FS_BLOCK_DATA_SIZE + j];
					_fs_debug4("data[%d] = %c\n", i * EEPROM_FS_BLOCK_DATA_SIZE + j,
							block.data[j]);
				}

				// Update file handle data
				fh->last_block = write_block_data(block.data);
			}

			// In case the data was truncated, recalculate size
			if (size > num_blocks * EEPROM_FS_BLOCK_DATA_SIZE)
			{
				fh->filesize = num_blocks * EEPROM_FS_BLOCK_DATA_SIZE;
			}
			else
			{
				fh->filesize = size;
			}

			_fs_debug1("File %d successfully written.\n", fh->filename);
		}
		else
		{
			_fs_error("No more space available for file %d.\n", fh->filename);
		}
	}
	else
	{
		_fs_error("Tried to write to read-only file handle '%d'\n", fh->filename);
	}
}