Beispiel #1
0
//--------------------------------------------------------------------------------------------------*/
// 文件系统初始化
void init_fs(void)
{
	File_Desc*	p_fd;
	Inode*		p_inode;
	no_answer = 0;
	for(p_fd = file_table;p_fd < file_table + MAX_ALL_FILE;p_fd++)
		p_fd->fd_inode = 0;
	for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++)
		p_inode->i_cnt = 0;
	hd_open(ROOT_DEV);
	hd_read(ROOT_DEV,fsbuf,512,1);
	DEV_Super_Block*	p_sb = (DEV_Super_Block*)fsbuf;
	if(p_sb->magic != MAGIC)
		fs_make();	// 只在建立文件系统的时候调用,调用之后会覆盖之前的文件系统
	
	hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * INODE_1ST_SECTS,1);	// 获取目录inode
	DEV_Inode*	p_devinode	= (DEV_Inode*)fsbuf;
	inode_table[0]		= *(Inode*)(p_devinode + 1);	// inode_table第0个元素用于存放目录inode
	inode_table[0].i_dev	= ROOT_DEV;
	inode_table[0].i_cnt	= 1;
	inode_table[0].i_num	= 1;
	p_inode_de		= inode_table;
}
Beispiel #2
0
void main()
{
	hd_writeonechar(0xa4);
	lcd_writecd(0,0x0c);
	lcd_writecd(0,0x01);
	delay_1ms(5);
	lcd_string(0x96,"0.");
	while(1)
	{
		if(!hd_key)
		{
			key_process(hd_keyconvert(hd_read(0x15)));
		}while(!hd_key);
		delay_1ms(5);
	}	
}
Beispiel #3
0
/*
函数功能:删除普通文件
输入参数:文件名	pathname
	删除方式	flags
输出参数:成功返回0,失败返回-1
*/
int fs_delete(char * pathname,int flags)
{
	DEV_Inode*	p_devinode;
	int		inode_nr;
	Inode*		p_inode;
	Dir_Entry*	p_de;
	int		i,j,k;
	
	// 读目录文件,获取Dir_Entry 和 inode_nr
	int	file_offset	= 0;
	int	de_nr		= 0;
	for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE)
	{
		file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE);
		for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++)
		{
			if(strcmp(p_de->name,pathname) == 0)
			{
				inode_nr	= p_de->inode_nr;
				de_nr	+= j;
				break;
			}
		}
		if(inode_nr != 0)
			break;
		de_nr += DIR_ENT_PER_SECT;
	}
	// 目录中寻找结束
	if(inode_nr == 0)
	{
		printk("can not find the file for delete ! %s\n",pathname);
		return	-1;		// 待删除的文件不存在
	}
	if(inode_nr < 5)
	{
		printk("can not delete this file! %s\n",pathname);
		return	-1;		// 前4个文件不能删除。1:"." 2-4:tty0-tty2
	}
	// 检测inode_table中是否有inode_nr,如果没有,则表示没有进程在使用该文件,可以删除
	for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++)
	{
		if(p_inode->i_num == inode_nr && p_inode->i_cnt != 0)
		{
			printk("can not delete the file ! %s\n",pathname);
			return -1;	// 当前有进程在使用该文件,所以不能删除
		}
	}
	// 设备中释放imap,smap,Dir_Entry
	// imap
	int sect = IMAP_1ST_SECTS + inode_nr / 8 / SECTOR_SIZE;
	hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1);
	fsbuf[inode_nr / 8 % SECTOR_SIZE] &= (U8)~(1 << (inode_nr % 8)  );
	hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1);
	// smap
	sect = INODE_1ST_SECTS + inode_nr / INODE_PER_SECT;	// 获取devinode
	hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1);
	p_devinode = (DEV_Inode*)fsbuf;
	p_devinode += inode_nr % INODE_PER_SECT;
	int start_sect	= p_devinode->i_start_sect;
	int nr_sects	= p_devinode->i_nr_sects;
	
	i	= start_sect / 8 / SECTOR_SIZE;	// 所在扇区号
	j	= start_sect / 8 % SECTOR_SIZE;	// 扇区内字节号
	k	= start_sect % 8;			// 字内位号
	//printk("start_sect:%d,i:%d,j:%d,k:%d\n",start_sect + DAT_1ST_SECT,i,j,k);
	while(nr_sects > 0)				// 释放smap
	{
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1);
		while(j < SECTOR_SIZE && nr_sects >0)
		{
			if(8 - k >= nr_sects)		// 该字节内解决问题
			{
				while(nr_sects-- > 0)
				{
					fsbuf[j] &= (char)~(1 << k++);
				}
				break;
			}
			else				// 该字节内解决不了问题
			{
				if(k == 0)		// 全0
				{
					fsbuf[j] = 0;
					nr_sects -= 8;
				}
				else			// 非全0
				{
					while(k < 8)
					{
						fsbuf[j] &= (char)~(1 << k++);
						nr_sects--;
					}
				}
				j++;
				k = 0;
			}
		}
		//printk("i:%d,j:%d,k:%d\n",i,j,k);
		hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1);
		i++;
		j = 0;
	}
	// Dir_Entry
	Dir_Entry	de;
	de.inode_nr = 0;
	//printk("de_nr:%d  ",de_nr);
	file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry));
	sync_buff(p_inode_de,0);		// 0:不释放缓冲	1:同步之后释放缓冲
	// 成功返回0
	return	0;
}
Beispiel #4
0
/*
函数功能:打开文件
输入参数:文件名	pathname
	打开方式	flags
	进程指针	p_tcb
输出参数:成功返回进程filp中的fd下标,失败返回-1
*/
int fs_open(char * pathname,int flags,TCB* p_tcb)
{
	pathname		= va2pa(p_tcb->pdb,pathname);
	DEV_Inode*	p_devinode;
	int		inode_nr;
	File_Desc*	p_fd;
	Inode*		p_inode;
	Dir_Entry*	p_de;
	int		i,j;
	
	// 读目录文件,寻找pathname,获得其inode_nr
	int	file_offset	= 0;
	for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE)
	{
		file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE);
		for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++)
		{
			if(strcmp(p_de->name,pathname) == 0)
			{
				inode_nr = p_de->inode_nr;
				break;
			}
		}
		if(inode_nr != 0)
			break;
	}
	// 目录中寻找结束
	if(inode_nr == 0)				// 没找到dev_inode
	{
		if(flags == O_CREATE)
		{
			// 这里应该判断待创建打开的是否是普通文件
			inode_nr = create_file(pathname);
			if(inode_nr == 0)
			{
				printk("create_file error! %s\n",pathname);
				return	-1;	// 创建文件失败
			}
		}
		else
		{
			printk("no file : %s\n",pathname);
			return	-1;		// 没有找到,也没有创建文件
		}
	}
	//printk("file : %s   inode_nr : %d\n",pathname,inode_nr);
	// 找到了dev_inode编号inode_nr
	// 查看内存里的inode_table中是否存在该inode
	int	i_dev = ROOT_DEV;
	Inode*	p_inode_empty = 0;
	Inode*	p_inode_empty1 = 0;
	for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++)
	{
		if(p_inode->i_cnt == 0)
		{
			if(p_inode_empty == 0)
				p_inode_empty = p_inode;	// 第一个空位
			
			if(p_inode_empty1 == 0 && p_inode->i_dev == 0 && p_inode->i_num == 0)
				p_inode_empty1 = p_inode;	// 第一个从未被使用过的空位
		}
		if(p_inode->i_dev != i_dev)		continue;
		if(p_inode->i_num != inode_nr)	continue;
		break;
	}
	int	new_inode	= 0;
	if(p_inode >= inode_table + MAX_ALL_INODE)		// 不在inode_table里,需要手动添加
	{	// 在inode_table中寻找一个空位
		if(p_inode_empty1 != 0)
		{
			p_inode		= p_inode_empty1;
		}
		else
		{
			if(p_inode_empty == 0)
			{
				printk("inode_table full : %s----",pathname);
				return	-1;	// inode_table无空位
			}
			p_inode		= p_inode_empty;
		}
		
		new_inode		= 1;	// 用于判断该inode是否是新添加的
	}
	// 此时p_inode的i_dev i_num正确,但是i_cnt可能是0。即:现在找到的inode可能是正在被其他进程共享的,也可能是被其他进程废弃的
	// 在file_table中寻找一个空位
	for(p_fd = file_table;p_fd < file_table + MAX_ALL_FILE;p_fd++)
	{
		if(p_fd->fd_inode == 0)
			break;
	}
	//printk(" p_fd : %d   \n",p_fd - file_table);
	if(p_fd >= file_table + MAX_ALL_FILE)
	{
		printk("file_table full : %s----",pathname);
		return	-1;	// file_table无空位
	}
	// 在进程filp数组中寻找一个空位
	for(i = 0;i < MAX_TASK_FILE;i++)
	{
		if(p_tcb->filp[i] == 0)
			break;
	}
	if(i >= MAX_TASK_FILE)
	{
		printk("filp full : %s----",pathname);
		return	-1;	// filp无空位
	}
	// 填充空位信息
	p_tcb->filp[i]		= p_fd;
	
	p_fd->fd_mode		= RD_WR;
	p_fd->fd_pos		= 0;
	p_fd->fd_inode		= p_inode;
	p_inode->i_cnt++;
	if(new_inode == 1)		// 新添加的inode,需要赋值
	{
		//printk("new inode : %d\n",inode_nr);
		// 获取dev_inode指针
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (INODE_1ST_SECTS + inode_nr  / INODE_PER_SECT),1);
		p_devinode = (DEV_Inode*)fsbuf;
		p_devinode += inode_nr % INODE_PER_SECT;
		// 赋值
		p_inode->i_mode		= p_devinode->i_mode;
		p_inode->i_size		= p_devinode->i_size;
		p_inode->i_start_sect	= p_devinode->i_start_sect;
		p_inode->i_nr_sects		= p_devinode->i_nr_sects;
		p_inode->i_dev		= ROOT_DEV;
		p_inode->i_num		= inode_nr;
	}
	// 返回filp中的下标
	//printk("file open : %s  ----",pathname);
	if(p_inode->i_mode == I_MODE_CHAR)			// 字符设备文件
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_OPEN;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);	// 字符设备的i_start_sect即设备号
		//printk("sub_device : %d       ",msg.msg_union.tty_msg.sub_device);
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			assert(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == 0);
		}
		enable_int();
		
	}
	//printk(" i : %d----",i);
	return	i;
}
Beispiel #5
0
/*
函数功能:创建普通文件
输入参数:文件名	pathname
输出参数:0 创建失败,非0 新文件在设备中的inode_nr
*/
int create_file(char * pathname)
{
	int		inode_nr = 0;
	int		start_sect = 0;
	int		i,j,k;
	// 在imap中找一个空位
	for(i =  0;i < NR_IMAP_SECTS ;i++)
	{
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1);
		for(j = 0;j < SECTOR_SIZE;j++)
		{
			if(fsbuf[j] == (char)0xff)
				continue;
			for(k = 0;k < 8;k++)
			{
				if(( fsbuf[j] & (1<<k) ) == 0)
				{	// 此时第i扇区,第j字节,第k位为待找的空位
					//printk("imap find3\n");
					inode_nr	= SECTOR_SIZE * i * 8 + j * 8 + k;
					if(inode_nr == 0)	continue;
					//printk("imap find4,inode_nr: %d\n",inode_nr);
					fsbuf[j] |= (1 << k);
					hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1);
					break;
				}
			}
			if(inode_nr != 0) break;
		}
		if(inode_nr != 0) break;
	}
	if(inode_nr == 0)
	{
		printk("imap full----");
		return	0;	// 没有空位
	}
	// 在smap中找 inode_nr对应的 SECTS_PER_FILE 个连续空位,然后全部置1
	for(i = 0;i < NR_SMAP_SECTS;i++)	//
	{
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (SMAP_1ST_SECTS + i),1);
		for(j = 0;j < SECTOR_SIZE;j++)
		{
			if(fsbuf[j] == (char)0xff)
				continue;
			for(k = 0;k < 8;k++)
			{
				if((fsbuf[j] & (1 << k)) == 0)
				{	// 此时第i扇区,第j字节,第k位为待找的空位
					//printk("i:%d j:%d k:%d\n",i,j,k);
					start_sect = SECTOR_SIZE * i * 8 + j * 8 + k;
					int nr_sects = SECTS_PER_FILE;
					while(nr_sects > 0)				// 填充smap
					{
						hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1);
						while(j < SECTOR_SIZE && nr_sects >0)
						{
							if(8 - k >= nr_sects)		// 该字节内解决问题
							{
								while(nr_sects-- > 0)
								{
									if(fsbuf[j] & (char)(1 << k))
									{
										printk("i:%d j:%d k:%d\n",i,j,k);
										printk("OMG retry1!\n");
										goto	repeat;
									}
									fsbuf[j] |= (char)(1 << k++);
								}
								hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1);
								goto	smapOK;
							}
							else				// 该字节内解决不了问题
							{
								if(k == 0)		// 全1
								{
									if(fsbuf[j] != 0)
									{
										printk("i:%d j:%d k:%d\n",i,j,k);
										printk("OMG retry2!\n");
										goto	repeat;
									}
									fsbuf[j] = 0xff;
									nr_sects -= 8;
								}
								else			// 非全1
								{
									while(k < 8)
									{
										if(fsbuf[j] & (char)(1 << k))
										{
											printk("i:%d j:%d k:%d\n",i,j,k);
											printk("OMG retry3!\n");
											goto	repeat;
										}							
										fsbuf[j] |= (char)(1 << k++);
										nr_sects--;
									}
								}
								j++;
								k = 0;
							}
						}
						hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1);
						i++;
						j = 0;
					}
				}
			repeat:	;
			}
		}
	}
smapOK:	if(start_sect == 0) 
	{
		printk("smap full2----");
		return	0;	// 没有空位	
	}
	// devinode赋值
	int offset = (SECTOR_SIZE * INODE_1ST_SECTS + inode_nr * INODE_SIZE) & ~0x1ff;
	hd_read(ROOT_DEV,fsbuf,offset,1);
	DEV_Inode* p_devinode = (DEV_Inode*)fsbuf;
	p_devinode += inode_nr % INODE_PER_SECT;
	p_devinode->i_mode		= I_MODE_FILE;
	p_devinode->i_size		= FILE_MAX_SIZE;
	p_devinode->i_start_sect	= start_sect;
	p_devinode->i_nr_sects	= SECTS_PER_FILE;
	printk("new file %s  start_sect :%d  sects: %d\n",pathname,start_sect,SECTS_PER_FILE);
	hd_write(ROOT_DEV,fsbuf,offset,1);
	// Dir_Entry
	// 在root中找一个空位
	Dir_Entry*	p_de;
	int	file_offset	= 0;
	int	de_nr		= 0;
	for(i = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE)
	{
		file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE);
		for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++)
		{
			if(p_de->inode_nr == 0 && (i !=0 || j != 0))	// 第0号位置保留
			{
				de_nr	+= j;
				//printk("de_nr:%d  ",de_nr);
				Dir_Entry	de;
				de.inode_nr = inode_nr;
				memcopy(de.name,pathname,MAX_FILENAME_LEN);
				file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry));
				sync_buff(p_inode_de,0);		// 0:不释放缓冲	1:同步之后释放缓冲
				
				// 返回inode_nr
				printk("create file success: %s\n",pathname);
				return inode_nr;	// 返回inode_nr	0:失败,非0:成功
			}
		}
		de_nr += DIR_ENT_PER_SECT;
	}
	printk("Dir_Entry empty\n");
	return	0;	// 没有找到Dir_Entry
}