📄 fs_server.c
字号:
#include "fs_server.h"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#define FILETYPE 0177000
#define SP_bsize 1024
#define DI_bsize 65536
#define DB_bsize 1024000
int Dinode_BtoP(dinode_addr num)
{
return (SP_bsize + (num-1) * 64);
}
int Dblock_BtoP(dblock_addr num)
{
return (SP_bsize + DI_bsize + (num-1) * 1024);
}
void InitSuperBlock(int fd)
{
int i;
SuperBlock.s_isize = 64;
SuperBlock.s_fsize = 1065; //1+64+1000
SuperBlock.s_nfree = 49;
for (i = 48; i >= 0; i--)
SuperBlock.s_free[i] = 50 - i;
SuperBlock.s_ninode = 99;
for (i = 98; i >= 0; i--)
SuperBlock.s_inode[i] = 100 - i;
SuperBlock.s_flock = 0;
SuperBlock.s_ilock = 0;
SuperBlock.s_fmod = 0;
SuperBlock.s_ronly = 0;
SuperBlock.s_time = 0;
for (i = 0; i < 4; i++)
SuperBlock.s_dinfo[i] = 0;
SuperBlock.s_tfree = 999;
SuperBlock.s_tinode = 1023;
strcpy(SuperBlock.s_fname,"mysys");
strcpy(SuperBlock.s_fpack,"fpack");
SuperBlock.s_magic = 1122;
SuperBlock.s_type = 1122;
lseek(fd, 0, 0);
write(fd, &SuperBlock, sizeof(SuperBlock)); //Write SuperBlock
}
void InitDinode(int fd)
{
dinode *p, Dinode;
int i,j;
p = &Dinode;
p->di_mode=0144644; //dwrx-rx-rx
p->di_nlink=0;
p->di_uid=0;
p->di_gid=0;
p->di_size=32; //".", ".." size
p->di_addr[0] = 1; //root point to the first dinode
for(j=1;j<13;j++)
{
p->di_addr[j]=0;
}
lseek(fd, SP_bsize, 0);
write(fd,p,sizeof(dinode));
p->di_addr[0] = 0;
p->di_mode=0;
for(i=1;i<1024;i++)
{
write(fd,p,64);
}
}
void InitDblock(int fd)
{
int s_free[256];
int i,j,k;
direct Direct_default[64];
Direct_default[0].DinodeAddr = 1; //init block1
Direct_default[1].DinodeAddr = 1;
strcpy(Direct_default[0].d_name, ".");
strcpy(Direct_default[1].d_name, "..");
for (i = 2; i < 64; i++)
Direct_default[i].DinodeAddr = 0;
lseek(fd, Dblock_BtoP(1), 0);
for (i = 0; i < 1000; i++)
write(fd, Direct_default, 64*sizeof(direct));
for(j=100;j<1001;j=j+50)
{
k=j;
for(i=0;i<50;i++)
{
s_free[i]=k;
k--;
}
lseek(fd, Dblock_BtoP(j-50), 0);
write(fd,s_free,256*sizeof(int));
}
}
Pathname Getname(const char *string)
{
Pathname pname;
int i,j=0;
pname.num=0;
if (*(++string) == '\0') {
pname.name[0][0] = '/';
pname.name[0][1] = '\0';
return pname;
}
pname.name[0][0] = '/';
pname.name[0][1] = '\0';
for(i=1;;i++)
{
while((*string!='/') && (*string!='\0'))
{
pname.name[i][j]=*string;
j++;
string++;
}
pname.name[i][j]='\0';
pname.num++;
if (*string == '\0')
break;
string=string+1;
j = 0;
}
return pname;
}
dinode_addr SearchPathname(dblock_addr Daddr, char *dirname, int flag)
{
dinode Dinode;
direct Direct[64];
int i;
lseek(fd, Dblock_BtoP(Daddr), 0);
read(fd, Direct, 1024); //Read Dblock
for (i = 2; i < 64; i++) { //beyond ".",".." from 2
if (Direct[i].DinodeAddr == 0)
return 0;
else {
if (strcmp(dirname, Direct[i].d_name) == 0) {
lseek(fd, Dinode_BtoP(Direct[i].DinodeAddr), 0);
read(fd, &Dinode, sizeof(dinode));
if (flag == 0) {
if ((Dinode.di_mode & FILETYPE) == 0144000) //File type is dir
return Direct[i].DinodeAddr; //return dinode_addr
} else {
if ((Dinode.di_mode & FILETYPE) == 0000000)
return Direct[i].DinodeAddr;
}
}
}
}
return 1;
}
dinode_addr GetFreeDinode(void)
{
dinode_addr DinodeAddr;
dinode Dinode[16];
int i, j;
DinodeAddr = SuperBlock.s_inode[--SuperBlock.s_ninode];
if (SuperBlock.s_ninode == 0) {
lseek(fd, 1, 0);
for (i = 0; i < 64; i++) {
read(fd, Dinode, 16*sizeof(dinode));
for (j = 0; j < 16; j++) {
if (Dinode[j].di_mode == 0)
SuperBlock.s_inode[SuperBlock.s_ninode++] = i*16 + j;
if (SuperBlock.s_ninode == 100) break;
}
if (SuperBlock.s_ninode == 100) break;
}
}
return DinodeAddr;
}
dblock_addr GetFreeBlock(void)
{
dblock_addr bno,i;
if(SuperBlock.s_tfree==0)
printf("the free Block is empty\n");
else
{
if(SuperBlock.s_nfree==1)
{
i=SuperBlock.s_free[--SuperBlock.s_nfree];
lseek(fd,Dblock_BtoP(SuperBlock.s_free[i]),0);
read(fd,SuperBlock.s_free,50*sizeof(dblock_addr));
SuperBlock.s_nfree=50;
bno=i;
}
else
{
bno=SuperBlock.s_free[--SuperBlock.s_nfree];
}
SuperBlock.s_tfree=SuperBlock.s_tfree-1;
}
return(bno);
}
dinode_addr LookUp(const char *pathname, unsigned short flag, int filetype )
{
Pathname pname;
int nblock, offset;
dinode Dinode, CreatedDinode, PreDinode;
dinode_addr DinodeAddr, CreatedDinode_addr, PreDinode_addr;
char filename[15];
int i, j;
direct Direct[64];
pname = Getname(pathname);
DinodeAddr = 1;
lseek(fd, Dinode_BtoP(1), 0); //Begin at Dinode1
read(fd, &Dinode, sizeof(dinode));
if ((pname.num == 0)&&(filetype == 0)) //One case is search "/"
return 1; //then return 1 Dinode addr
for (i = 1; i < pname.num ; i++) {
strcpy(filename, pname.name[i]);
for (j = 0; j < 10; j++) { //Only consider 0 lever
DinodeAddr = SearchPathname(Dinode.di_addr[j], filename, 0);//find dir
if (DinodeAddr == 0) {
printf("LookUp():Can't find %s \n",filename); //Can't find the path.
return 1; //A dir don't exist.
} else if (DinodeAddr != 1) { //Find path sucess.
lseek(fd, Dinode_BtoP(DinodeAddr), 0);
read(fd, &Dinode, sizeof(dinode));
break;
}
// always break;
}
}
PreDinode_addr = DinodeAddr; //save pre dinode
lseek(fd, Dinode_BtoP(PreDinode_addr), 0);
read(fd, &PreDinode, sizeof(dinode));
strcpy(filename, pname.name[i]);
for (j = 0; j < 10; j++) {
DinodeAddr = SearchPathname(Dinode.di_addr[j], filename, filetype);
if (DinodeAddr == 1) { //Dinode.di_addr[++j]
} else if (DinodeAddr != 0) {
return DinodeAddr;
} else { //then DinodeAddr = 0; don't exist
if (flag == 1) { //Require Creating
nblock = (PreDinode.di_size + 1023) / 1024; // suppose < 10
CreatedDinode_addr = GetFreeDinode(); //updata block
offset = (PreDinode.di_size/16) % 64;
if (offset != 0) {
lseek(fd, Dblock_BtoP(PreDinode.di_addr[nblock-1]), 0);
read(fd, Direct, 64*sizeof(direct));
Direct[offset].DinodeAddr = CreatedDinode_addr;
strcpy(Direct[offset].d_name, filename);
lseek(fd, Dblock_BtoP(PreDinode.di_addr[nblock-1]), 0);
write(fd, Direct, 64*sizeof(direct));
} else {
PreDinode.di_addr[nblock] = GetFreeBlock();
for (i = 1; i < 64; i++)
Direct[i].DinodeAddr = 0;
Direct[offset].DinodeAddr = CreatedDinode_addr;
strcpy(Direct[offset].d_name, filename);
lseek(fd, Dblock_BtoP(PreDinode.di_addr[nblock]), 0);
write(fd, Direct, 64*sizeof(direct));
}
PreDinode.di_size += 16; //updata pre dinode
lseek(fd, Dinode_BtoP(PreDinode_addr), 0);
write(fd, &PreDinode, sizeof(dinode));
if (filetype == 0) { //creat dir
CreatedDinode.di_size = 32; //updata created dinode
CreatedDinode.di_addr[0] = GetFreeBlock();
for (i = 1; i < 13; i++)
CreatedDinode.di_addr[i] = 0;
lseek(fd, Dinode_BtoP(CreatedDinode_addr), 0);
write(fd, &CreatedDinode, sizeof(Dinode));
Direct[0].DinodeAddr = CreatedDinode_addr; //updata Created block
Direct[1].DinodeAddr = PreDinode_addr;
strcpy(Direct[0].d_name, ".");
strcpy(Direct[1].d_name, "..");
for (i = 2; i < 64; i++)
Direct[i].DinodeAddr = 0;
lseek(fd, Dblock_BtoP(CreatedDinode.di_addr[0]), 0);
write(fd, Direct, 64*sizeof(direct));
} else { //creat data file
CreatedDinode.di_size = 0; //updata created dinode
for (i = 0; i < 13; i++)
CreatedDinode.di_addr[i] = 0;
lseek(fd, Dinode_BtoP(CreatedDinode_addr), 0);
write(fd, &CreatedDinode, sizeof(Dinode));
}
return CreatedDinode_addr;
} else
return 0; //Can't find and don't require Creat
}
}
}
inode DinodetoInode(dinode Dinode, dinode_addr DinodeAddr)
{
inode Inode;
int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -