📄 blockbuffer.c
字号:
#include "../kernel.h"
#include "FileSystem.h"
#define BUFFER_BASE 0X300000
Buffer FileBuffer[NR_FILE_BUFFER];//(* LPBuffer)0x300000;//文件数据缓冲区
Buffer *HashBuffer[NR_HASH_BUFFER];//文件数据缓冲区哈希表
//extern void SendMessage(int TaskID, Message *pMessage);//发送消息
//extern void InitVCHDTask();
//FreeHead和FreeTail指向一个空闲队列,采用LRU算法,
//不用的块将会被链入队列头FreeHead,
//从队尾FreeTail中取出最久不用的块
static LPBuffer FreeHead=NULL;//空闲链的头指针
static LPBuffer FreeTail=NULL;//空闲链的尾指针
LPBuffer DirtyLink=NULL;//被修改过的数据的队列头指针
PUBLIC void InitFileBuffer()
//初始化文件数据缓冲区
{
int i=0;
t_32 BufferBase=BUFFER_BASE;
FreeHead=&FileBuffer[0];//FreePoint指向第一个空闲块
FileBuffer->PrevFree=&FileBuffer[NR_FILE_BUFFER-1];
FileBuffer[0].NextFree=&FileBuffer[1];
FileBuffer[0].DirtyLink=NULL;
FileBuffer[0].Count=0;
FileBuffer[0].Dirty=0;
FileBuffer[0].Block=NO_BLOCK;
FileBuffer[0].Device=NO_DEVICE;
for(i=1;i<NR_FILE_BUFFER-1;i++)
{
//初始化空闲链,全部FileBuffer都链入空闲块
FileBuffer[i].NextFree=&FileBuffer[i+1];
FileBuffer[i].PrevFree=&FileBuffer[i-1];
FileBuffer[i].Count=0;
FileBuffer[i].Dirty=0;
FileBuffer[i].Block=0;
FileBuffer[i].Device=0;
//哈希链
FileBuffer[i].Hash=NULL;
//修改链
FileBuffer[i].DirtyLink=NULL;
}
//最后一块
FreeTail=&FileBuffer[NR_FILE_BUFFER-1];//FreeTail指向最后一个空闲块
FileBuffer[i].NextFree=&FileBuffer[0];
FileBuffer[i].PrevFree=&FileBuffer[i-1];
FileBuffer[i].Count=0;
FileBuffer[i].Dirty=0;
FileBuffer[i].Block=0;
FileBuffer[i].Device=0;
FileBuffer[i].Hash=NULL;
FileBuffer[i].DirtyLink=NULL;
for(i=0;i<NR_FILE_BUFFER;i++)
{
FileBuffer[i].Data=(t_8 *)BufferBase;
BufferBase+=BUFFER_SIZE;
}
printk("Init Buffer");
}
PRIVATE HDRead(t_32 Begin,t_32 pBuffer,t_32 Block)
//读硬盘
//Begin开始的扇区号,pBuffer数据区指针,Block要读的块数
{
//填写消息
/* Message mMessage;
mMessage.Type=READ;
mMessage.SECTORS=Block*2;
mMessage.FSADDR=(int)pBuffer;
mMessage.STARTSECTOR=Begin*2;
mMessage.Next=NULL;
//发送消息
SendMessage( HD,&mMessage);
ChangeProcess();
WaitMessage(FS,HD,NULL);*/
int i=0;
char *Data=(char *)pBuffer;
for(i=0;i<Block;i++)
{
readSector(Begin+i,Data);
Data+=512;
}
}
PRIVATE HDWrite(t_32 Begin,t_32 pBuffer,t_32 Block)
//写硬盘
//Begin开始的扇区号,pBuffer数据区指针,Block要读的块数
{
//填写消息
/* Message mMessage;
mMessage.Type=WRITE;
mMessage.SECTORS=Block*2;
mMessage.FSADDR=(int)pBuffer;
mMessage.STARTSECTOR=Begin*2;
mMessage.Next=NULL;
//发送消息
SendMessage( HD,&mMessage);
ChangeProcess();
WaitMessage(FS,HD,NULL);*/
int i=0;
char *Data=(char *)pBuffer;
for(i=0;i<Block;i++)
{
writeSector(Begin+i,Data);
Data+=512;
}
// printk("hui lai le\n");
}
PUBLIC LPBuffer GetFreeBlock()
//从文件数据缓冲区中取得空的可用的块
{
LPBuffer p=NULL;
if(FreeTail==NULL)
//无可用空闲块
return NULL;
p=FreeTail;
//指向前一块空闲块
FreeTail=FreeTail->PrevFree;
//返回空闲块
return p;
}
PUBLIC void FreeBufferBlock(LPBuffer pFileBuffer)
//释放不用的文件数据缓冲区块
{
LPBuffer p=NULL;
//如果被修改过则链入修改链
if(pFileBuffer->Dirty==DIRTY)
{ // printk("%x\n",pFileBuffer->Data);
HDWrite(pFileBuffer->Block,(t_32)pFileBuffer->Data,1);//写盘
/*pFileBuffer->DirtyLink=DirtyLink;
DirtyLink=pFileBuffer;*/
}
p=HashBuffer[MASK(pFileBuffer->Block)];//取得所在哈希链表的头指针
if(!p)
//不存在,出错
printk("HashBuffer No Exit,Error!\n");
//找到pFileBuffer前一项
while(p&&p->Hash)
{
if(p->Hash->Block==pFileBuffer->Block&&
p->Hash->Device==pFileBuffer->Device)
break;
p=p->Hash;
}
p->Hash=pFileBuffer->Hash;//将pFileBuffer从Hash链中删除
//清空相关项
pFileBuffer->Count=0;
pFileBuffer->Block=NO_BLOCK;
pFileBuffer->Device=NO_DEVICE;
pFileBuffer->Dirty=CLEAR;
//pFileBuffer链入空闲链表,成为第一个空闲块
pFileBuffer->NextFree=FreeHead;
FreeHead=pFileBuffer;
}
LPBuffer SearchBlock(int Block ,int Device)
//从哈希表中搜索指定的块
{
LPBuffer p=NULL;
p=HashBuffer[MASK(Block)];//取得所在哈希链表的头指针
//从哈希表中搜索
while(p)
{
if(p->Block==Block&&p->Device==Device)
break;
p=p->Hash;
}
//返回,没找到p将是NULL;
return p;
}
PRIVATE void DeHashLink(LPBuffer pFileBuffer)
//将指定块链入哈希表
{
LPBuffer p=NULL;
p=HashBuffer[MASK(pFileBuffer->Block)];//取得所在哈希链表的头指针
//该块成为该哈希链第一块
if(!p)
{
HashBuffer[MASK(pFileBuffer->Block)]=pFileBuffer;
return ;
}
//移动到哈希表尾
while(p->Hash)
p=p->Hash;
//链入表尾
p->Hash=pFileBuffer;
}
//取得指定的物理块
PUBLIC LPBuffer GetPhysicalBlock(int Block ,int Device)
//先从哈希表中搜索没找到
//就从空闲块中取出一块
//并将相应块从设备读入,链入哈希表中
{
LPBuffer p=NULL;
p=SearchBlock(Block , Device);//从哈希表中搜索
t_8 *Data;
int i=0;
//找到,返回
if(p)
return p;
p=FreeHead;
//从空闲链中搜索
while(p)
{
//提高刚使用文件缓冲时的搜索效率
if(p->Device==NO_DEVICE&&p->Block==NO_BLOCK)
break;
if(p->Device==Device&&p->Block==Block)
if(p->Dirty)
{
//被修改过,先写回磁盘
HDWrite(Block,(t_32)p->Data,1);
//返回
return p;
}
}
//从空闲块中取出一块
p=GetFreeBlock();
if(!p)
//无可用块了,出错
printk("Out Of DataBuffer!\n");
//IO读入相应的块
HDRead(Block,(t_32)p->Data,1);
//printk("Read hui lai le\n");
Data=p->Data;
p->Block=Block;
p->Device=Device;
p->Count++;
//将相应块链入哈希表
DeHashLink(p);
return p;
}
PUBLIC void Sysnc()
//将修改过的数据块,全部写入磁盘
{
LPBuffer pDirty=DirtyLink;
LPBuffer pPrevDirty;
//
while(pDirty)
{
if(pDirty->Dirty==DIRTY)
HDWrite(pDirty->Block,(t_32)pDirty->Data,1);//写盘
pDirty->Dirty=CLEAR;
pPrevDirty=pDirty;
pDirty=pDirty->DirtyLink;
pPrevDirty->DirtyLink=NULL;
}
DirtyLink=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -