unix 文件系统模拟_unix文件系统对文件存储空间 - CSDN
  • 本周进行操作系统课程设计,在很多的题目中选了个unix文件系统模拟,主要就是操作结构与文件。 为了方便,文件系统结构如下: Super block -- Block bitmap -- Inode bitmap -- Inode table -- Block zone ...

    本周进行操作系统课程设计,在很多的题目中选了个unix文件系统模拟,主要就是操作结构与文件。

    为了方便,文件系统结构如下:

    Super block   --  Block bitmap  -- Inode bitmap  -- Inode table -- Block zone

    其中:

    Super block: 存储基本信息

    Block bitmap:块分配情况

    Inode bitmap:索引节点分配情况

    Inode table: Indoe 节点存放区

    Block zone:存放数据区

    效果如下:


    总的说来,做的还是挺简单的,只是实现了基本的功能.而块的分配没有怎么完成,linux系统中一般是通过多级索引的方式为inode分配块.

    刚开始我的想法是:inode的块(512B)只写510B,留下2B用于记录下一块的块号,我觉得应该可行,但觉得繁,就没有写下去.所以就没有多余的

    块分配操作.知识INode对应一个Block....,太懒了.还有一个缺点,文件指针移动太频繁了,而且都是绝对定位移动(好算,呵呵)

    代码如下:

    /*核心思想:一切皆是文件
    如果是目录:Block中存储的是目录下文件和目录的fcb
    如果是文件:Block中存储的是文件的内容
    */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <signal.h>
    
    #define BLOCKSIZE 512
    #define BLOCKNUM  512
    #define INODENUM  30
    #define FILENAME "file.dat"
    
    typedef struct{
    	unsigned short blockSize;
    	unsigned short blockNum;
    	unsigned short inodeNum;
    	unsigned short blockFree;
    	unsigned short inodeFree;
    }SuperBlock;
    
    typedef struct{
    	unsigned short inum;
    	char fileName[10];
    	unsigned short isDir;  // 0-file 1-dir
    	unsigned short iparent;
    	unsigned short length;    //if file->filesize  if dir->filenum
    	unsigned short blockNum;
    }Inode,*PtrInode;
    
    //Fcb用于存储文件与 目录信息,主要用途:将一个目录下的所有文件(包括目录)写入到该目录对应的Block中
    typedef struct {
        unsigned short inum;
        char fileName[10];
        unsigned short isDir;
    }Fcb,*PtrFcb;
    
    
    typedef struct{
    	char userName[10];
    	char passWord[10];
    }User;
    
    
    char blockBitmap[BLOCKNUM];
    char inodeBitmap[INODENUM];
    
    SuperBlock superBlock;
    User curUser=(User){"root","root"};
    
    unsigned short currentDir; //current inodenum
    FILE *fp;
    const unsigned short superBlockSize=sizeof(superBlock);
    const unsigned short blockBitmapSize=sizeof(blockBitmap);
    const unsigned short inodeBitmapSize=sizeof(inodeBitmap);
    const unsigned short inodeSize=sizeof(Inode);
    const unsigned short fcbSize=sizeof(Fcb);
    char		*argv[5];
    int argc;
    
    
    void createFileSystem()
    /*创建*/
    {
    	long len;
    	PtrInode fileInode;
    	if ((fp=fopen(FILENAME,"wb+"))==NULL)
    	{
    		printf("open file %s error...\n",FILENAME);
    		exit(1);
    	}
    
        //init bitmap
    	for(len=0;len<BLOCKNUM;len++)
            blockBitmap[len]=0;
    
        for(len=0;len<INODENUM;len++)
            inodeBitmap[len]=0;
    
         //memset
    
    	for (len=0;len<(superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+BLOCKSIZE*BLOCKNUM);len++)
    	{
    		fputc(0,fp);
    	}
    	rewind(fp);
    
    	//init superBlock
    	superBlock.blockNum=BLOCKNUM;
    	superBlock.blockSize=BLOCKSIZE;
    	superBlock.inodeNum=INODENUM;
    	superBlock.blockFree=BLOCKNUM-1;
    	superBlock.inodeFree=INODENUM-1;
    
    	fwrite(&superBlock,superBlockSize,1,fp);
    
    	//create root
    	fileInode=(PtrInode)malloc(inodeSize);
    	fileInode->inum=0;
    	strcpy(fileInode->fileName,"/");
    	fileInode->isDir=1;
    	fileInode->iparent=0;
    	fileInode->length=0;
    	fileInode->blockNum=0;
    
    	//write / info to file
    	inodeBitmap[0]=1;
    	blockBitmap[0]=1;
    	fseek(fp,superBlockSize,SEEK_SET);
    	fwrite(blockBitmap,blockBitmapSize,1,fp);
    	fseek(fp,superBlockSize+blockBitmapSize,SEEK_SET);
    	fwrite(inodeBitmap,inodeBitmapSize,1,fp);
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize,SEEK_SET);
    	fwrite(fileInode,inodeSize,1,fp);
    	fflush(fp);
    
    	//point to currentDir
    	currentDir=0;
    
    }
    
    void openFileSystem()
    /*如果FILENAME可读,则代表之前已有信息,并读取相应数据    如果不可读,则创建文件系统 */
    {
    
    	if((fp=fopen(FILENAME,"rb"))==NULL)
    	{
    		createFileSystem();
    	}
    	else
    	{
    	    if ((fp=fopen(FILENAME,"rb+"))==NULL)
            {
                printf("open file %s error...\n",FILENAME);
                exit(1);
            }
    	    rewind(fp);
            //read superBlock from file
            fread(&superBlock,superBlockSize,1,fp);
    
            //read bitmap from file
            fread(blockBitmap,blockBitmapSize,1,fp);
            fread(inodeBitmap,inodeBitmapSize,1,fp);
    
            //init current dir
            currentDir=0;
    
    	}
    
    }
    
    
    void createFile(char *name,int flag) //flag=0 ->create file   =1 ->directory
    {
    	int i,nowBlockNum,nowInodeNUm;
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	PtrInode parentInode=(PtrInode)malloc(inodeSize);
    	PtrFcb fcb=(PtrFcb)malloc(fcbSize);
    
    	//the available blockNumber
    	for(i=0;i<BLOCKNUM;i++)
    	{
    		if(blockBitmap[i]==0)
    		{
    			nowBlockNum=i;
    			break;
    		}
    
    	}
    
    	//the available inodeNumber
    	for(i=0;i<INODENUM;i++)
    		{
    			if(inodeBitmap[i]==0)
    			{
    				nowInodeNUm=i;
    				break;
    			}
    
    		}
    
    	//init fileINode struct
    	fileInode->blockNum=nowBlockNum;
    	strcpy(fileInode->fileName,name);
    	fileInode->inum=nowInodeNUm;
    	fileInode->iparent=currentDir;
    	if(flag==0)
    	{
    		fileInode->isDir=0;
    	}
    	else
    	{
    		fileInode->isDir=1;
    	}
    	fileInode->length=0;
    
    	//write fileInfo to file
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*nowInodeNUm,SEEK_SET);
    	fwrite(fileInode,inodeSize,1,fp);
    
    	//update superBlock and bitmap
    	superBlock.blockFree-=1;
    	superBlock.inodeFree-=1;
    	blockBitmap[nowBlockNum]=1;
    	inodeBitmap[nowInodeNUm]=1;
    
    	//init fcb info
    	strcpy(fcb->fileName,fileInode->fileName);
    	fcb->inum=fileInode->inum;
    	fcb->isDir=fileInode->isDir;
    
    	//update to file ...
    
    	//update parent dir block info
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fread(parentInode,inodeSize,1,fp);
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE+parentInode->length*fcbSize,SEEK_SET);
    	fwrite(fcb,fcbSize,1,fp);
    
    	//update parent dir inode info
    	parentInode->length+=1;
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fwrite(parentInode,inodeSize,1,fp);
    
    	// free resource
    	free(fileInode);
    	free(parentInode);
    	free(fcb);
    }
    
    
    
    void list()
    {
    	int i;
    	PtrFcb fcb=(PtrFcb)malloc(fcbSize);
    	PtrInode parentInode=(PtrInode)malloc(inodeSize);
    
    	//read parent inode info from file
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fread(parentInode,inodeSize,1,fp);
    
    	//point to parent dir block
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
    
    	//list info
    	for(i=0;i<parentInode->length;i++)
    	{
    		fread(fcb,fcbSize,1,fp);
    		printf("Filename: %-10s",fcb->fileName);
    		printf("Inode number: %-2d    ",fcb->inum);
    		if(fcb->isDir==1)
    		{
    		printf("Directory\n");
    		}
    		else
    		{
    			printf("Regular file\n");
    		}
    	}
    
    	//free resource
    	free(fcb);
    	free(parentInode);
    }
    
    
    int findInodeNum(char *name,int flag)  //flag=0 ->find file flag=1 -> find dir
    {
    	int i,fileInodeNum;
    	PtrInode parentInode=(PtrInode)malloc(inodeSize);
    	PtrFcb fcb=(PtrFcb)malloc(fcbSize);
    
    	//read current inode info from file
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fread(parentInode,inodeSize,1,fp);
    
    	//read the fcb in the current dir block
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+inodeSize*INODENUM+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
    
    	for(i=0;i<parentInode->length;i++)
    	{
    		fread(fcb,fcbSize,1,fp);
    		if(flag==0)
    		{
    			if((fcb->isDir==0)&&(strcmp(name,fcb->fileName)==0))
    					{
    						fileInodeNum=fcb->inum;
    						break;
    					}
    
    		}
    		else
    		{
    			if((fcb->isDir==1)&&(strcmp(name,fcb->fileName)==0))
    					{
    						fileInodeNum=fcb->inum;
    						break;
    					}
    
    		}
    	}
    
    	if(i==parentInode->length)
    			fileInodeNum=-1;
    
    	free(fcb);
    	free(parentInode);
    	return fileInodeNum;
    }
    
    void cd(char *name)
    {
    	int fileInodeNum;
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	if(strcmp(name,"..")!=0)
    	{
    		fileInodeNum=findInodeNum(name,1);
    		if(fileInodeNum==-1)
    			printf("This is no %s directory...\n",name);
    		else
    		{
    			currentDir=fileInodeNum;
    		}
    	}
    	else
    	{
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    		fread(fileInode,inodeSize,1,fp);
    		currentDir=fileInode->iparent;
    
    	}
    	free(fileInode);
    }
    
    void cdParent()
    {
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fread(fileInode,inodeSize,1,fp);
    	currentDir=fileInode->iparent;
    
    	free(fileInode);
    }
    
    void write(char *name)
    {
    	int fileInodeNum,i=0;
    	char c;
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	if((fileInodeNum=findInodeNum(name,1))!=-1)
    	{
    		printf("This is a directory,not a file...\n");
    		return;
    	}
    
    	fileInodeNum=findInodeNum(name,0);
    	if(fileInodeNum==-1)
    		printf("This is no %s file...\n",name);
    	else
    	{
    		//get inode->blocknum
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
    		fread(fileInode,inodeSize,1,fp);
    		//point to the block site
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+fileInode->blockNum*BLOCKSIZE,SEEK_SET);
    		printf("please input file content(stop by #):\n");
    		while((c=getchar())!='#')
    		{
    			fputc(c,fp);
    			i++;
    		}
    
    		//update inode->length
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
    		fread(fileInode,inodeSize,1,fp);
    		fileInode->length=i-1;
    		fseek(fp,-inodeSize,SEEK_CUR);
    		fwrite(fileInode,inodeSize,1,fp);
    	}
    
    	free(fileInode);
    
    }
    
    void read(char *name)
    {
    	int fileInodeNum;
    	char c;
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	if((fileInodeNum=findInodeNum(name,1))!=-1)
    	{
    			printf("This is a directory,not a file...\n");
    			return;
    	}
    	fileInodeNum=findInodeNum(name,0);
    	if(fileInodeNum==-1)
    		printf("This is no %s file...\n",name);
    	else
    	{
    		//get inode->blocknum
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
    		fread(fileInode,inodeSize,1,fp);
    		//point to the block site
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+fileInode->blockNum*BLOCKSIZE,SEEK_SET);
    
    		//read content
    		if(fileInode->length!=0)
    		{
    			while((c=fgetc(fp))!=EOF)
    			{
    				putchar(c);
    			}
    			printf("\n");
    		}
    
    	}
    
    	free(fileInode);
    }
    
    
    void delete(char *name) 
    /*delete 一个文件,需要修改SuperBlock,Blockbitmap,Inodebitmap,并更新父节点长度,删除父节点Block中存储的该文件fcb*/ 
    {
    	int fileInodeNum,i;
    	PtrInode fileInode=(PtrInode)malloc(inodeSize);
    	PtrInode parentInode=(PtrInode)malloc(inodeSize);
    	Fcb fcb[20];
    	if(((fileInodeNum=findInodeNum(name,0))==-1)&&((fileInodeNum=findInodeNum(name,1))==-1))
    	{
    		printf("This is no %s...\n",name);
    	}
    	else
    	{
    		if((fileInodeNum=findInodeNum(name,0))==-1)
    		{
    			fileInodeNum=findInodeNum(name,1);
    		}
    
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInodeNum*inodeSize,SEEK_SET);
    		fread(fileInode,inodeSize,1,fp);
    
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInode->iparent*inodeSize,SEEK_SET);
    		fread(parentInode,inodeSize,1,fp);
    
    
    		//update parent info
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
    		for(i=0;i<parentInode->length;i++)
    		{
    			fread(&fcb[i],fcbSize,1,fp);
    				//fcb[i]=tmp;
    		}
    
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
    		for(i=0;i<BLOCKSIZE;i++)
    				fputc(0,fp);
    
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+INODENUM*inodeSize+parentInode->blockNum*BLOCKSIZE,SEEK_SET);
    		for(i=0;i<parentInode->length;i++)
    		{
    			if((strcmp(fcb[i].fileName,name))!=0)
    			{
    					fwrite(&fcb[i],fcbSize,1,fp);
    			}
    		}
    
    		parentInode->length-=1;
    		fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+fileInode->iparent*inodeSize,SEEK_SET);
    		fwrite(parentInode,inodeSize,1,fp);
    		//update bitmap
    		inodeBitmap[fileInodeNum]=0;
    		blockBitmap[fileInode->blockNum]=0;
    
    		//update superblock
    		superBlock.blockFree+=1;
    		superBlock.inodeFree+=1;
    	}
    
    	free(fileInode);
    	free(parentInode);
    
    }
    
    void updateResource()
    {
    	rewind(fp);
    	fwrite(&superBlock,superBlockSize,1,fp);
    	fwrite(blockBitmap,blockBitmapSize,1,fp);
    	fwrite(inodeBitmap,inodeBitmapSize,1,fp);
    	fclose(fp);
    }
    
    void pathSet()
    {
    	PtrInode curInode=(PtrInode)malloc(inodeSize);
    	fseek(fp,superBlockSize+blockBitmapSize+inodeBitmapSize+currentDir*inodeSize,SEEK_SET);
    	fread(curInode,inodeSize,1,fp);
    	printf("%s@localhost:%s#",curUser.userName,curInode->fileName);
    	free(curInode);
    }
    
    void systemInfo()
    {
    	printf("Sum of block number:%d\n",superBlock.blockNum);
    	printf("Each block size:%d\n",superBlock.blockSize);
    	printf("Free of block number:%d\n",superBlock.blockFree);
    	printf("Sum of inode number:%d\n",superBlock.inodeNum);
    	printf("Free of inode number:%d\n",superBlock.inodeFree);
    }
    
    void help()
    {
    	printf("command: \n\
    	help   ---  show help menu \n\
    	sysinfo  --- show system base information \n\
    	cls  ---  clear the screen \n\
    	cd     ---  change directory \n\
    	mkdir  ---  make directory   \n\
    	touch  ---  create a new file \n\
    	cat   ---  read a file \n\
    	write  ---  write something to a file \n\
    	logout ---  exit user \n\
    	rm     ---  delete a directory or a file \n\
    	exit   ---  exit this system\n");
    }
    
    int analyse(char *str)
    {
    	int  i;
    	char temp[20];
    	char *ptr_char;
    	char *syscmd[]={"help","ls","cd","mkdir","touch","cat","write","rm","logout","exit","sysinfo","cls"};
    	argc = 0;
    	for(i = 0, ptr_char = str; *ptr_char != '\0'; ptr_char++)
    	{
    		if(*ptr_char != ' ')
    		{
    			while(*ptr_char != ' ' && (*ptr_char != '\0'))
    				temp[i++] = *ptr_char++;
    			argv[argc] = (char *)malloc(i+1);
    			strncpy(argv[argc], temp, i);
    			argv[argc][i] = '\0';
    			argc++;
    			i = 0;
    			if(*ptr_char == '\0')
    				break;
    		}
    	}
    	if(argc != 0)
    	{
    		for(i = 0; (i < 12) && strcmp(argv[0], syscmd[i]); i++);
    			return i;
    	}
    	else
    		return 12;
    	return 0;
    }
    
    void login()
    {
    	char userName[10];
    	char passWord[10];
    	while(1)
    	{
    		printf("login:");
    		gets(userName);
            system("stty -echo");
    		printf("passwd:");
    		gets(passWord);
    		system("stty echo");
    		printf("\n");
    		if(strcmp(userName,curUser.userName)==0&&strcmp(passWord,curUser.passWord)==0)
    			break;
    	}
    }
    
    void stopHandle(int sig)
    {
        printf("\nPlease wait...,update resource\n");
        updateResource();
        exit(0);
    }
    
    void command(void)
    {
    	char cmd[20];
    	do
    	{
    		pathSet();
    		gets(cmd);
    		switch(analyse(cmd))
    		{
    			case 0:
    				help();
    				break;
    			case 1:
    				list();
    				break;
    			case 2:
    				cd(argv[1]);
    				break;
    			case 3:
    				createFile(argv[1],1);
    				break;
    			case 4:
    				createFile(argv[1],0);
    				break;
    			case 5:
    				read(argv[1]);
    				break;
    			case 6:
    				write(argv[1]);
    				break;
    			case 7:
    				delete(argv[1]);
    				break;
    			case 8:
    				updateResource();
    				login();
    				openFileSystem();
                    command();
    				break;
    			case 9:
    				updateResource();
    				exit(0);
    				break;
    			case 10:
    				systemInfo();
    				break;
                case 11:
                    system("clear");
    				break;
    			default:
    				break;
    		}
    	}while(1);
    }
    
    int main(int argc,char **argv){
        signal(SIGINT,stopHandle);
    	login();
    	openFileSystem();
    	command();
    	return 0;
    }



              



    展开全文
  • UNIX文件系统模拟实现

    千次阅读 2015-05-17 00:31:46
    项目背景 开发环境 ...代码实现项目背景完成一个 UNIX文件系统的子集的模拟实现。 1. 完成文件卷结构设计 2. I节点结构设计 3. 目录结构 4. 用户及组结构 5. 文件树结构 6. 实现功能如下命令:


    项目背景

    完成一个 UNIX文件系统的子集的模拟实现。
    1. 完成文件卷结构设计
    2. I节点结构设计
    3. 目录结构
    4. 用户及组结构
    5. 文件树结构
    6. 实现功能如下命令:

    Ls 显示文件目录
    Chmod 改变文件权限
    Chown 改变文件拥有者
    Chgrp 改变文件所属组
    Pwd 显示当前目录
    Cd 改变当前目录
    Mkdir 创建子目录
    Rmdir 删除子目录
    Umask 文件创建屏蔽码
    Mv 改变文件名
    Cp 文件拷贝
    Rm 文件删除
    Ln 建立文件联接
    Cat 连接显示文件内容
    Passwd 修改用户口令


    开发环境

    操作系统 :windows 7 64位
    开发工具 :visual studio 2010
    程序类型 :win32 控制台应用程序


    分析

    文件系统特特性

    文件数据除了文件的实际内容外,通常还包含很多额外的属性,例如Linux操作系统的文件权限(RWX)与晚间属性(所有者、族群、时间参数等)。文件系统通常会将这两部分数据分别存放在不同的块,权限与属性放置到Inode中,至于时间数据则放置到Data Block中。另外,还有一个超级块 Superblock 会记录整个文件系统的整体信息,包括inode和block的总量、使用量、剩余量。

    • super block:记录此文件系统的整体信息,包括inode/block 的总量,使用情况、剩余量。以及文件系统的格式相关信息等;
    • inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block的号码;
    • block:实际记录文件的内容,若文件太大的时候,会占用多个block

    盘块的管理

    位示图法

    位示图是利用二级制的以为来表示磁盘的中有个盘块的使用情况。当其值为“0”时,表示对应的盘块空闲;为“1”的时,表示已经分配。

    成组链接法

    在UNIX系统中,将空闲块分成若干组,每100个空闲块为一组,每组的第一空闲块登记了下一组空闲块的物理盘块号和空闲块总数。如果一个组的第二个空闲块号等于0,则有特殊的含义,意味着该组是最后一组,即无下一个空闲块。

    分配空闲块的时候,从前往后分配,先从第一组开始分配,第一组空闲的100块分完了,才进入第二组。

    释放空闲块的时候正好相反,从后往前分配,先将释放的空闲块放到第一组,第一组满了,在第一组前再开辟一组,之前的第一组变成第二组。


    设计

    系统流程

    系统流程图

    程序开始执行后,程序会先将资源文件读取,并以一文件指针保存在全局变量virtualDisk中。
    读取文件成功以后,通过文件指针访问超级块所在盘块,读取内容保存在全局变量super中。
    加载超级块以后,程序通过iget操作获取到root节点,保存在全局变量root中。
    接下来,进入登录界面,用户输入密码和口令,程序根据用户的输入,读取用户文件,判断是否登录成功,成功以后进入程序的主界面。


    文件卷设计

    这里写图片描述

    本程序的模拟磁盘的大小是8MB,每个盘块的大小设定为1KB,共8192个盘块。其中0号盘块在本程序中没有使用,但保留了下来。1号盘块保存超级块的信息。2-911盘块保存的是finode节点的信息。从912盘块开始,都是存储文件内容的盘块,使用成组链接法来管理,每组的盘块数是20。关于结点等数据结构会在下面部分详细介绍。


    数据结构设计

    超级快数据结构

    1#块为超级块(superblock)。磁盘的回收和索引结点的分配与回收,将涉及到超级块。超级块是专门用于记录文件系统中盘块和磁盘索引节点使用情况的一个盘块,其中含有以下各个字段:

    1. size :文件系统的盘块数。
    2. freeBlock:空闲盘块号栈,即用于记录当前可用的空闲盘块编号的栈。
    3. nextFreeBlock:当前空闲盘快号数,即在空闲盘块号栈中保存的空闲盘块号的数目。他也可以被视为空闲盘块号栈的指针。
    4. freeInode:空闲磁盘i结点编号栈,即记录了当前可用的素偶皮空闲结点编号的栈。
    5. nextFreeInode:空闲磁盘i结点数目,指在磁盘i结点栈中保存的空闲i结点编号的数目,也可以视为当前空闲i结点栈顶的指针。
    6. freeBlockNum:空闲盘块数,用于记录整个文件系统中未被分配的盘块个数。
    7. freeInodeNum:空闲i结点个数,用于记录整个文件系统中未被分配的节点个数。
    8. lastLogin:上次登录时间
    struct supblock
    {
        unsigned int size;                  //the size of the disk
        unsigned int freeBlock[BLOCKNUM];   //the stack of the free block
        unsigned int    nextFreeBlock;      //the pointer of the next free block in the stack
        unsigned int freeBlockNum;          //the totally number of the free block in the disk
        unsigned int freeInode[INODENUM];   //the stack of the free node
        unsigned int freeInodeNum;          //the totally number of the free inode in the disk
        unsigned int nextFreeInode;         //the next free inode in the stack
        unsigned int lastLogin;
    };

    结点数据结构

    关于索引结点,本程序的主要由两种结构的定义,分别是内存索引结点和磁盘索引结点。
    磁盘索引结点:
    1. mode :文件类型及属性
    2. fileSize :文件大小
    3. fileLink :文件连接数
    4. owner :所属用户名
    5. group :所属用户组
    6. modifyTime :修改时间
    7. createTime :创建时间
    8. addr :盘块地址数组

    truct finode
    {
        int             mode;
        long        int fileSize;
        int             fileLink;
        char            owner[MAXNAME];
        char            group[GROUPNAME];
        long        int modifyTime;
        long        int createTime;
        int             addr[6];
        char            black[45];              //留空,以备内容扩充时不会影响结构大小
    };

    内存索引结点:
    内存索引结点是保存在内存中索引结点的数据结构,当文件第一次被打开时,文件的索引结点从模拟磁盘上读出,并保存在内存中,方便下一次文件的打开。
    1. finode:磁盘索引结点结构,保存从磁盘读出的索引结点信息
    2. parent:父级内存索引结点指针
    3. inodeID:索引结点号

    struct inode
    {
        struct                      finode finode;
        struct                      inode *parent;
        unsigned short int          inodeID;                //the node id
        int                         userCount;                  //the number of process using the inode
    };

    文件目录项:

    文件目录项由文件名和文件索引结点号组成。
    1. directName:文件名或目录名
    2. inodeID:文件索引结点号

    struct direct
    {
        char                    directName[DIRECTNAME];
        unsigned short int      inodeID;
    };

    目录数据结构

    目录结构:
    1. dirNum:目录数目
    2. direct:目录项数组

    struct dir
    {
        int     dirNum;
        struct  direct direct[DIRNUM];
    };

    对于目录类,它的内容都是以dir结构保存在磁盘中的,并以dir结构读取。


    代码实现

    主函数

    主函数中,最最核心的函数就是dispatch函数,它解析用户输入的指令,并解析出参数,调用用户需要的函数。其流程图如下:
    这里写图片描述


    核心函数

    一下函数为整一个文件系统最最核心的功能,所有的操作都是建立在一下函数的基础上进行的:
    1. 盘块读函数
    int bread(void * _Buf,unsigned short int bno,long int offset,int size,int count=1)
    该函数将指定的盘块号内容的读取到对应的数据结构中。

    1. 盘块写函数
      int bwrite(void * _Buf,unsigned short int bno,long int offset,int size,int count=1)

    2. 结点分配函数
      struct inode* ialloc()
      该函数的作用是为从超级块的空闲结点栈中取出一个新的结点,并 出示化该结点。其流程图如图所示。
      这里写图片描述

    3. 盘块分配函数
      int balloc()
      该函数的主要功能是从超级快的空闲盘块栈中取出一个空闲盘块号,若栈只剩一个空闲盘块,那么采用成组链接法,读取下一组的空闲盘块栈。函数流程图如图所示。
      这里写图片描述

    4. 盘块回收函数
      int bfree(int bno)
      该函数的主要功能是回收空闲盘块,若超级块中的空闲盘块栈未满,则回收盘块号入栈,若空闲盘块栈满,则将栈内容写到新回收的盘块上,清空栈,并将新的盘块号入栈。流程图如图。
      这里写图片描述

    代码实现

    点我点我

    展开全文
  • 本次实验的内容是完成一个 UNIX文件系统的子集的模拟实现。 实验要求: 完成文件卷结构设计 I节点结构设计 目录结构 用户及组结构 文件树结构 实现功能如下命令: 点击此处下载...

    一、实验介绍

    本次实验的内容是完成一个 UNIX文件系统的子集的模拟实现。

    实验要求:

    • 完成文件卷结构设计

    • I节点结构设计

    • 目录结构

    • 用户及组结构

    • 文件树结构

    • 实现功能如下命令:

    点击此处下载文档和源码

     

    展开全文
  • 模拟UNIX文件系统的设计及实现》

    千次阅读 2005-09-26 16:00:00
    本人有《模拟UNIX文件系统的设计及实现》,如要源代码,请与本人联系,电邮:sgzcl@21cn.com
    本人有《模拟UNIX文件系统的设计及实现》,如要源代码,请与本人联系,电邮:sgzcl@21cn.com
    展开全文
  • 模拟UNIX文件系统的设计及实现

    千次阅读 热门讨论 2007-06-14 12:28:00
    一、题目: 模拟UNIX文件系统的设计及实现 即:多用户、多目录的文件系统的设计------对模拟文件系统的管理 二、目的 通过OS子系统的设计、增强OS设计的技巧,达到提高解决实际OS的设计能力的提高。 三、内容 多...
  • UNIX文件系统的路径组织结构[操作系统] UNIX并不使用驱动器名如 C: D: 等来标记一硬盘或分区,在整个系统上,不管有多少个硬盘,分区是怎样的,只有一个根目录,叫做root 标记为 / ,其下任何一个子目录,却可以是...
  • 自己编写UNIX文件系统

    千次阅读 2016-09-09 08:54:52
    近日有人求助,要写一个UNIX文件系统作为暑假作业。这种事情基本是学操作系统的必须要做的或者是做过的,毕竟文件系统是操作系统课程的一个重要组成部分。要实现这个UNIX文件系统,很多人就扎进了UNIX V6的的系统...
  • JAVA实现UNIX文件管理系统

    千次阅读 2018-07-26 11:05:16
    这个项目是操作系统的期末课设,...一、UNIX文件系统的基本原理  UNIX采用树型目录结构,每个目录表称为一个目录文件。一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在...
  • 编写一个UNIX文件系统

    千次阅读 2013-08-25 14:30:51
    近日有人求助,要写一个UNIX文件系统作为暑假作业。这种事情基本是学操作系统的必须要做的或者是做过的,毕竟文件系统是操作系统课程的一个重要组成部分。要实现这个UNIX文件系统,很多人就扎进了UNIX V6的的系统...
  • 文件系统设计与模拟实现   要求编写程序,完成如下功能: 构建成组链:  根据用户定义的盘块大小、文件区占用磁盘块数和分组的块数,模拟Unix系统将磁盘空闲块进行分组,并将这些盘块组构成成组链。 查询  ...
  • 了解FAT文件系统的结构 学习文件管理系统的一般开发方法。 2 需求说明 2.1 基本要求 设计并实现一个目录列表函数(无须支持选项,如ls -a、ls -l等),用来显示当前目录下包含的文件信息 设计并...
  • testMyFileSystem 接收用户输入的文件操作命令,测试文件系统和API 只要提交一个makefile文件完成代码自动生成的工作,过程是研究UNIX V6++的各种代码然后剪剪切切改改用到自己的程序里面。 要实现把文件存进取出,...
  • //[原创][5.磁盘存储空间的管理/十大题型]算法... UNIX系统文件管理成组连接算法说明 UNIX系统文件管理成组连接算法: 把空闲块分成若干组,把指向一组中各空闲块的指针集中一起。 这样既可方便查找,又可减少
  • unix树形目录结构

    千次阅读 2013-09-19 14:20:49
    unix操作系统采用树形带沟连的目录结构,如下图所示,在这种结构中,一个文件的名字是由根目录到... 根文件系统常用目录 根文件系统的常用目录举例如下表:   unix树形目录结构  / 根目录,这是所有目录和文件
  • Unix操作系统常用命令

    千次阅读 2019-10-17 02:48:51
    Unix操作系统常用命令 一、关于档案/目录处理的命令 1、ls——列目录 这是最基本的档案指令。ls的意义为"list",也就是将某一个目录或是某一个档案的内容显示出来。 格式:ls-1ACFLRabcdfgilmnopqrstux-W[sv]...
  • 模拟文件系统

    千次阅读 2015-04-13 20:13:10
     首先,创建一个大约100M的文件作为模拟的硬盘。硬盘的空间总共分为三个部分:超级块区,inode区和磁盘块区。其中超级块区就是一个struct结构,其中保存了inode区和磁盘块区的使用情况。inode区则由1024个inode块...
  • 模拟文件系统课程设计

    千次阅读 2013-03-05 10:56:12
    课程设计的实验文档,简单模拟linux文件系统的结构并作简单实现 实验概述 【实验目的及要求】 通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。     【实验原理...
  • //思路:用户登录文件系统,然后创建、打开、读、写、关闭、删除文件 import java.io.*; import java.util.*; public class Main{ public static void main(String[] args){ Scanner scan = new Scanner...
  • 操作系统实验之UNIX混合索引方式模拟(外存的增量式索引组织方式)目前常用的外存组织方式有: 连续组织方式 链式组织方式 隐式链接 显式链接 索引组织方式 单级索引组织方式 多级索引组织方式 增量式索引组织方式...
1 2 3 4 5 ... 20
收藏数 52,650
精华内容 21,060
关键字:

unix 文件系统模拟