inodebuffer.c

来自「参照MINIX3写的操作系统 用GCC+NASM+BOCHS开发」· C语言 代码 · 共 273 行

C
273
字号
#include "../kernel.h"
#include "FileSystem.h"

#define HARD_DISK 0
#define BASE_INODE_BUFFER 0x600000
extern LPBuffer GetPhysicalBlock(int Block ,int Device);
extern void FreeBufferBlock(LPBuffer pFileBuffer);
extern void Sysnc();




InodeBuffer FileInode[NR_INODE_BUFFER];//文件Inode缓冲区

LPInodeBuffer HashInode[NR_HASH_INODE];//文件Inode缓冲区哈希表

static LPInodeBuffer FreeHead;//空闲链的头指针
static LPInodeBuffer FreeTail;//空闲链的尾指针

PUBLIC void InitInodeBuffer()
//初始化文件Inode缓冲区
{
	int i=0;
	t_32 BaseInodeBuffer=BASE_INODE_BUFFER;
    FreeHead=&FileInode[0];//FreePoint指向第一个空闲块
    FileInode[0].NextFree=&FileInode[1];
    FileInode[0].PrevFree=&FileInode[NR_INODE_BUFFER-1];

	FileInode[0].InodeNumber=0;
	FileInode[0].Count=0;
    FileInode[0].Dirty=0;

	for(i=0;i<NR_INODE_BUFFER-1;i++)
	{	
		//初始化空闲链,全部FileInode都链入空闲块
		FileInode[i].NextFree=&FileInode[i+1];
        FileInode[i].PrevFree=&FileInode[i-1];

        FileInode[i].InodeNumber=0;
		FileInode[i].Count=0;
	    FileInode[i].Dirty=0;



		//哈希链
	    FileInode[i].Hash=NULL;
	}
	//最后一块
	FreeTail=&FileInode[NR_INODE_BUFFER-1];//FreeTail指向最后一个空闲块
	FileInode[i].NextFree=&FileInode[0];
    FileInode[i].PrevFree=&FileInode[i-1];  

	FileInode[i].InodeNumber=0;
	FileInode[i].Count=0;
    FileInode[i].Dirty=0;

    FileInode[i].Hash=NULL;


	for(i=0;i<NR_INODE_BUFFER;i++)
	{
		FileInode[i].FileInode=(Inode *)BaseInodeBuffer;
		BaseInodeBuffer+=sizeof(Inode);
	}
	printk("initInodeBuffer\n");


}


PRIVATE LPInodeBuffer GetFreeInodeBlock()
//从文件Inode缓冲区中取得空的可用的块
{
    InodeBuffer *p=NULL;
	if(FreeTail==NULL)
	{
		printk("NO Free InodeBlock!\n");
		//无可用空闲块
		return NULL;
	}
    p=FreeTail;	

	//指向前一块空闲块
    FreeTail=FreeTail->PrevFree;
	printk("FreeTail:%x\n",FreeTail);
	//返回空闲块
	return p;

}
PRIVATE void IOReadInode(t_32 InodeNumber,t_32 Device ,LPInodeBuffer pInodeBuffer)
//从设备中将对应InodeNumber的Inode读入
{
   //计算Inode所在的块号
   t_32 InodeBlock=2+(VIRTUAL_HD_SIZE/1024/1024/8+1)*2+InodeNumber/8;
   //计算Inode在块内的位置
   t_16 Index=(t_16)InodeNumber%8;
   char *pInode;
   int i=0;
   LPBuffer pBlock;
   pBlock=GetPhysicalBlock(InodeBlock ,HARD_DISK);
   pInode=pBlock->Data;
   //定位Inode
   for(i=0;i<Index;i++)
	   pInode+=128;	
 
  MemoryCopy((void *)pInodeBuffer->FileInode,(void *)pInode,sizeof(Inode));
 
  if(pInodeBuffer->Dirty==DIRTY)
		pBlock->Dirty=DIRTY;
 // FreeBufferBlock(pBlock);


}

PRIVATE void IOWriteInode(t_32 InodeNumber,t_32 Device ,LPInodeBuffer pInodeBuffer)
//从设备中将对应InodeNumber的Inode读入
{
	int n;
	void *q;
   //计算Inode所在的块号
   t_32 InodeBlock=2+(VIRTUAL_HD_SIZE/1024/1024/8+1)*2+InodeNumber/8;
   //就算Inode在块内的位置
   t_16 Index=(t_16)InodeNumber%8;
   char *pInode;
   int i=0;
   LPBuffer pBlock;
   pBlock=GetPhysicalBlock(InodeBlock ,HARD_DISK);
   pInode=pBlock->Data; 
   //定位Inode
   for(i=0;i<Index;i++)
	   pInode+=128;
  
   MemoryCopy((void *)pInode,(void *)(pInodeBuffer->FileInode),sizeof(Inode));
   n=sizeof(Inode);
  if(pInodeBuffer->Dirty==DIRTY)
		pBlock->Dirty=DIRTY;
  FreeBufferBlock(pBlock);


}

PUBLIC void FreeInodeBuffer(LPInodeBuffer pInodeBuffer)
//释放不用的文件数据缓冲区块
{

	 LPInodeBuffer p=NULL;
	 //被修改过,将其写回
	 if(pInodeBuffer->Dirty==DIRTY)
	 {
		 
         IOWriteInode(pInodeBuffer->InodeNumber,HARD_DISK ,pInodeBuffer);
	 }
     p=HashInode[MASK(pInodeBuffer->InodeNumber)];//取得所在哈希链表的头指针
	 if(!p)
		 //不存在,出错
		 printk("HashInode No Exit,Error!\n");
	//找到pInodeBuffer前一项
	 while(p&&p->Hash)
	 {
		 if(p->Hash->InodeNumber==pInodeBuffer->InodeNumber)
			break;
		 p=p->Hash;
	 }
	 p->Hash=pInodeBuffer->Hash;//将pFileBuffer从Hash链中删除

	 //清空相关项
     p->Count=0;
	 p->InodeNumber=0;
  


	 //pFileBuffer链入空闲链表,成为第一个空闲块
     pInodeBuffer->NextFree=FreeHead;
	 FreeHead=pInodeBuffer;


}

LPInodeBuffer SearchInodeBlock(unsigned long InodeNumber)
//从哈希表中搜索指定的块
{   
    LPInodeBuffer p=NULL;
	p=HashInode[MASK(InodeNumber)];//取得所在哈希链表的头指针

	//从哈希表中搜索
	 while(p)
	 {
		 if(p->InodeNumber==InodeNumber)
			break;
		 p=p->Hash;
	 }

     //返回,没找到p将是NULL;
	 return p;





}	

PRIVATE void DeHashLink(LPInodeBuffer pInodeBuffer)
//将指定块链入哈希表
{	
	LPInodeBuffer p=NULL;
	p=HashInode[MASK(pInodeBuffer->InodeNumber)];//取得所在哈希链表的头指针
	//该块成为该哈希链第一块
    if(!p)
	{
       HashInode[MASK(pInodeBuffer->InodeNumber)]=pInodeBuffer;
	   return ;
	}
	//移动到哈希表尾
	while(p->Hash)	
		 p=p->Hash;
	//链入表尾
     p->Hash=pInodeBuffer;

	
}
//取得指定的Inode
LPInodeBuffer GetInode(unsigned long InodeNumber)
//先从哈希表中搜索没找到
//就从空闲块中取出一块
//并将相应块从设备读入,链入哈希表中
{
	LPInodeBuffer p=NULL;
    p=SearchInodeBlock(InodeNumber);//从哈希表中搜索
	//找到,返回
	if(p)
		return p; 
	p=FreeHead;
	//从空闲链中搜索
	while(p)
	{
		//提高刚使用文件缓冲时的搜索效率
		if(p->InodeNumber==0)
			break;

		if(p->InodeNumber==InodeNumber)
			if(p->Dirty)
			{
				//被修改过,先写回磁盘    
				IOWriteInode(p->InodeNumber,HARD_DISK ,p);
				//返回
				return p;

			}
	}

	//从空闲块中取出一块
	p=GetFreeInodeBlock();


	if(!p)
		//无可用块了,出错
		printk("Out Of InodeBuffer!\n");
   

	//计算出Inode所在的块
    //IO读入相应的块
    IOReadInode(InodeNumber,HARD_DISK ,p);

    p->InodeNumber=InodeNumber;
	p->Count++;
	//将相应块链入哈希表
      DeHashLink(p);
	  
	  return p;


}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?