⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fs_server.c

📁 题目:文件系统的模拟实现 目的:深入理解文件系统的实现机制
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -