rw.c
来自「参照MINIX3写的操作系统 用GCC+NASM+BOCHS开发」· C语言 代码 · 共 687 行 · 第 1/2 页
C
687 行
#include "../kernel.h"
#include "FileSystem.h"
extern LPBuffer GetPhysicalBlock(int Block ,int Device);
extern void FreeBufferBlock(LPBuffer pFileBuffer);
t_32 GetAddressFromIndirectBlock(t_8 Device,t_32 Block,t_32 NumberInOneBlock)
//从间接块中读出NumberInOneBlock所对应的Address
{
t_32 i;
LPBuffer Buf;
char *p;
t_32 BlockAddress;
if(NumberInOneBlock<0||NumberInOneBlock>=256)
return ERROR;
Buf=GetPhysicalBlock(Block,Device);
p=Buf->Data;
for(i=1;i<=NumberInOneBlock;i++)
p+=4;
BlockAddress=(*(t_32 *)p);
return BlockAddress;
}
t_bool SetAddressToIndirectBlock(t_8 Device,t_32 Block,t_32 NumberInOneBlock,t_32 Address)
//将物理块写入Inode
{
t_32 i;
LPBuffer Buf;
char *p;
if(NumberInOneBlock<0||NumberInOneBlock>=256)
return ERROR;
Buf=GetPhysicalBlock(Block,Device);
p=Buf->Data;
Buf->Dirty=DIRTY;
for(i=1;i<=NumberInOneBlock;i++)
p+=4;
(*(t_32 *)p)=Address;
FreeBufferBlock(Buf);
return OK;
}
t_32 FileBlockToPhysicalBlock(LPInode pInode,t_32 BlockNumber,t_8 Device)
{
t_32 PhysicalBlock;
// t_32 BlockNumber1;
if(0<=BlockNumber&&BlockNumber<12)//直接块
{
//直接块对应的物理块,直接保存在Inode中
PhysicalBlock=pInode->Block[BlockNumber];
return PhysicalBlock;
}
else if(12<=BlockNumber&&BlockNumber<(12+256))//一次间接块
{
//从一次间接块中读取BlockNumber对应的物理块号
BlockNumber=BlockNumber-12;
PhysicalBlock=GetAddressFromIndirectBlock(Device,pInode->Block[12],BlockNumber);
return PhysicalBlock;
}else
{
printk("暂时不支持\n");
return -1;
}
/*else if(256<BlockNumber<=(12+256+256*256))//二次间接块
{
BlockNumber1=(BlockNumber-12-256)/256;//计算二次间接块中,一次间接块的块号
//取得一次间接块块号
PhysicalBlock=ReadPhysicalBlock(Inode->Block[13],BlockNumber1);
//计算BlockNumber在块内的位置
BlockNumber1=(BlockNumber-12-256)%256;
PhysicalBlock=ReadPhysicalBlock(BlockAddress,BlockNumber1);
return PhysicalBlock;
}
else if((12+256+256*256)<BlockNumber<=(12+256+256*256+256*256*256))//读三次间接块
{
//计算三次间接块中,二次间接块的块号
BlockNumber1=(BlockNumber-12-256-256*256)/256;
//取得二次间接块块号
PhysicalBlock=ReadPhysicalBlock(Inode->Block[14],BlockNumber1);
//计算三次间接块中,一次间接块的块号
BlockNumber1=(BlockNumber-12-256-256*256)/(256*256);
//取得一次间接块块号
PhysicalBlock=ReadPhysicalBlock(BlockAddress,BlockNumber1);
//计算直接块在块内的位置
BlockNumber1=(BlockNumber-12-256-256*256)%(256*256);
//取得直接块
PhysicalBlock=ReadPhysicalBlock(BlockAddress,BlockNumber1);
return PhysicalBlock;
}*/
}
short GetBit(int Start,char Byte)
//返回Byte从Start位起第一个Value值(0或1)所在的位置
{
int i=0;
/*if(Value==0)
Byte=(~Byte);*/
for(i=Start;i<8;i++)
{
if(((~Byte)>>i)&1)
return i;
}
return -1;
}
void SetBit(unsigned char *Byte,int Bit)
{
unsigned char Temp=0x1;;
switch(Bit)
{
case 0:Temp=0x1;break;
case 1:Temp=0x2;break;
case 2:Temp=0x4;break;
case 3:Temp=0x8;break;
case 4:Temp=0x10;break;
case 5:Temp=0x20;break;
case 6:Temp=0x40;break;
case 7:Temp=0x80;break;
default :break;
}
*Byte|=Temp;
}
t_32 SearachFreeBlock(t_8 Device,t_32 StartPosition,t_32 Count,t_8 Value)
//不包括StartPosition本身
//在从指定的位置开始在块位图中搜索Count个块返回第一个空闲块
{
t_32 BitmapBlock=0;
t_32 LocalStart=0;
t_32 CurrentPosition=0;
LPBuffer pBlock=NULL;
t_32 i=0;
short Temp;
char *Byte;
//根据StartPosition计算第一块位图块的位置给BitmapBlock
BitmapBlock=StartPosition/(1024*8);
CurrentPosition+=BitmapBlock*8192;
pBlock=GetPhysicalBlock(BitmapBlock++,Device);//取得该块
printk("pBlock %x\n",pBlock);
//计算块内的开始位置
LocalStart=StartPosition-CurrentPosition;
CurrentPosition=(StartPosition-StartPosition%8);
Byte=pBlock->Data;
Byte+=(LocalStart/8);
if((Temp=GetBit(StartPosition-CurrentPosition,*Byte))!= -1)
{
SetBit((unsigned char *)Byte,Temp);
pBlock->Dirty=DIRTY;
FreeBufferBlock(pBlock);
return (CurrentPosition+i*8+Temp);
}
i+=1;
Byte++;
while(i<Count)
{
if((i+(LocalStart/8))>1023)
{
pBlock=GetPhysicalBlock(BitmapBlock++,Device);
Byte=pBlock->Data;
CurrentPosition+=i*8;
i=0;
Count-=(i*8);
}
if((Temp=GetBit(0,*Byte))!= -1)
{
SetBit((unsigned char *)Byte,Temp);
pBlock->Dirty=DIRTY;
FreeBufferBlock(pBlock);
return (CurrentPosition+i*8+Temp);
}
else
{
i+=1;
Byte++;
}
}
return ERROR;
}
t_32 NewMallocPhysicalBlock(LPSuper Super,LPInode pInode,int EstimateSize)
//开辟新的物理块
{
t_32 Block;
//t_32 NextFreeBlock;
Block=Super->FirstFreeBlock;//取得FirstFreeBlock所指的空闲块
//如果预分配以超出磁盘空间范围,就不再进行预分配,直接用最近空闲块
//if(Super->FirstFreeBlock+EstimateSize>HD_SIZE)
pInode->FutuerBlocks=EstimateSize;
Super->FirstFreeBlock+=EstimateSize;
//NextFreeBlock=SearachFreeBlock(Block+EstimateSize);//搜索下一个空闲块的位置
//Super->FirstFreeBlock=NextFreeBlock;
Block=SearachFreeBlock(0,Block,EstimateSize,0);
return Block;
}
t_32 AllotInode(LPSuper Super)
{
return SearachFreeBlock(0,Super->FirstFreeInode,Super->TotalInode,0);
}
t_32 OldMallocPhysicalBlock(LPSuper Super,LPInode pInode)
{
if(pInode->Blocks==0)
return ERROR;
if((pInode->Blocks%pInode->FutuerBlocks)==0)
{
return NewMallocPhysicalBlock(Super,pInode,pInode->FutuerBlocks);
}
else
return SearachFreeBlock(0, pInode->LastBlock,10000,0);
}
/*PhysicalBlockToFileBlock0(LPSuper SuperBlock,LPInode pInode,t_32 PhysicalBlock,t_8 Device)
{
pInode->Block[FileBlockSize]=PhysicalBlock;
}
PhysicalBlockToFileBlock1(LPInode pInode,t_32 IndirectBlock1,t_32 PhysicalBlock,t_8 Device)
{
if(IndirectBlock1==0)//一次间接块指针尾空
{
//申请新块,作为一次间接块
NewBlock=OldMallocPhysicalBlock(LPInode pInode);
//取得该块
pBuffer=GetPhysicalBlock(NewBlock ,Device);
Data=pBuffer->Data;
//清零
memset((void *)Data,1024,0);
//将PhysicalBlock写入一次块
SetAddressToIndirectBlock(Device,NewBlock,0,PhysicalBlock);
}
else//一次块已经存在
{
//计算新的PhysicalBlock在一次间接块中的位置
NewBlock=FileBlockSize-12;
//将PhysicalBlock写入一次块
SetAddressToIndirectBlock(Device,IndirectBlock1,NewBlock,PhysicalBlock);
}
}
PhysicalBlockToFileBlock2(LPInode pInode,t_32 IndirectBlock2,t_32 PhysicalBlock,t_8 Device)
{
if(IndirectBlock2==0)//二次间接块指针为空
{
//申请新块,作为二次间接块
NewBlock2=OldMallocPhysicalBlock(LPInode pInode);
//取得该块
pBuffer=GetPhysicalBlock(NewBlock ,Device);
Data=pBuffer->Data;
//清零
memset((void *)Data,1024,0);
//申请新块,作为一次间接块
NewBlock1=OldMallocPhysicalBlock(LPInode pInode);
//取得该块
pBuffer=GetPhysicalBlock(NewBlock ,Device);
Data=pBuffer->Data;
//清零
memset((void *)Data,1024,0);
//将一次间接块写入二次块间接块
SetAddressToIndirectBlock(Device,NewBlock2,0,NewBlock1)
//将PhysicalBlock写入一次块
SetAddressToIndirectBlock(Device,NewBlock1,0,NewBlock1)
}
else //二次间接块存在
{
if((FileBlockSize-12-256)/256==0)//一次间接块指针为空
{
//申请新块,作为一次间接块
NewBlock1=OldMallocPhysicalBlock(LPInode pInode);
//取得该块
pBuffer=GetPhysicalBlock(NewBlock ,Device);
Data=pBuffer->Data;
//清零
memset((void *)Data,1024,0);
//将一次间接块写入二次块间接块
SetAddressToIndirectBlock(Device,Inode->Block[13],0,NewBlock1);
}
else//一次间接块存在
{
//计算一次块在二次块中的位置
NewBlock1=(FileBlockSize-12-256)/256;
NewBlock1=GetAddressFromIndirectBlock(Device,Inode->Block[13],NewBlock1);
//计算新的PhysicalBlock在一次间接块中的位置
NewBlock=(FileBlockSize-12-256)%256;
//将PhysicalBlock写入一次块
SetAddressToIndirectBlock(Device,NewBlock1,NewBlock,PhysicalBlock);
}
}
}
}*/
void PhysicalBlockToFileBlock(LPSuper Super,LPInode pInode,t_32 PhysicalBlock,t_8 Device)
{
t_32 FileBlockSize= pInode->FileSize/1024 ;//计算总的文件块数+1(新加进的块)
t_32 NewBlock;
LPBuffer pBuffer;
char *Data;
if(0<=FileBlockSize&&FileBlockSize<12)//在直接块内
pInode->Block[FileBlockSize]=PhysicalBlock;
else if(12<=FileBlockSize&&FileBlockSize<(12+256))//在一次间接块内
{
if(pInode->Block[12]==0)//一次间接块指针尾空
{
//申请新块,作为一次间接块
NewBlock=OldMallocPhysicalBlock(Super,pInode);
//取得该块
pBuffer=GetPhysicalBlock(NewBlock ,Device);
Data=pBuffer->Data;
//清零
MemorySet((void *)Data,0,1024);
//将PhysicalBlock写入一次块
pInode->Block[12]=NewBlock;
SetAddressToIndirectBlock(Device,NewBlock,0,PhysicalBlock);
}
else//一次块已经存在
{
//计算新的PhysicalBlock在一次间接块中的位置
NewBlock=FileBlockSize-12;
//将PhysicalBlock写入一次块
SetAddressToIndirectBlock(Device,pInode->Block[12],NewBlock,PhysicalBlock);
}
}else
{
printk("暂时不支持\n");
}
pInode->LastBlock=PhysicalBlock;
/*pInode->Blocks+=1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?