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 + -
显示快捷键?