Unix文件系统代码实现

来源:互联网 发布:怎么样开好淘宝店 编辑:程序博客网 时间:2024/06/07 21:03


源代码

一、实验介绍

本实验要求完成一个 UNIX文件系统的子集的模拟实现。实验的提示与要求:

(1)   文件卷结构设计

盘块管理采用成组链接法。

0#块可省略

I节点栈及空间为20项

块大小为512字节

卷盘块数大于100

I节点盘块数大于10块

(2)   I节点结构设计

文件大小

文件联接计数

文件地址

文件拥有者

文件所属组

文件权限及类别

文件最后修改时间

其中文件地址为六项:四个直接块号,一个一次间址,一个两次间址

(3)   目录结构

用16字节表示,其中14字节为文件名,2字节为I节点号

(4)   用户及组结构

用户信息中包括用户名、口令,所属组,用户打开文件表

(文件树结构应与用户相对应:有每个用户的HOME目录)

组信息中可只包含组名

(5)   文件树结构

除(4)要求外,适当考虑UNIX本身文件树结构

(6)   实现功能

ls                显示文件目录

chmod        改变文件权限

chown              改变文件拥有者

chgrp               改变文件所属组

pwd            显示当前目录

cd               改变当前目录

mkdir               创建子目录

rmdir                删除子目录

mv              改变文件名

cp               文件拷贝

rm              文件删除

ln              建立文件联接

cat              连接显示文件内容

passwd       修改用户口令

 

二、实验环境

操作系统    :windows7 64位

开发工具    :vc6.0

三、实验设计

3.1 系统流程


图3.1.1系统流程图

注释:命令执行完毕后将返回输入命令界面

文字说明:

      系统开始后进行初始化操作,首先判断模拟磁盘文件是否存在,不存在则初始化一个模拟磁盘,存在则读入超级块、用户、组,初始化当前目录。

      接着用户登录,登录成功后进入系统主界面,输入各项命令即可进行各项操作。

3.2 文件结构


图3.2.1文件卷结构

文字说明:

      模拟磁盘大小为200KB,每一个盘块大小为512字节,一共400个盘块,其中0号盘块预留,1号盘块为超级块,2~41号盘块为INode节点,42号~399号盘块为Block。

3.3 实现命令操作

本系统主要实现了以下命令:

ls               显示目录文件

chmod      改变文件权限

chown       改变文件拥有者

chgrp        改变文件所属组

pwd          显示当前目录

cd             改变当前目录

mkdir        创建子目录

rmdir         删除子目录

mv            改变文件名;

cp             文件拷贝

rm             文件删除

ln              建立文件联接

cat            连接显示文件内容

passwd      修改用户口令

touch        创建文件

>>            文本内容追加

注释:测试系统时为了校验特地加了sp命令:输出超级块内容

三、数据结构

3.1 超级块

SuperBlock结构体:

structsuperBlock  //超级块

{

      unsigned int size;  //磁盘大小

      unsigned int freeINodeNum; //空闲INode数

      unsigned int freeINode[INODE_NUM];   //空闲INode栈

      unsigned int nextFreeINode; //栈中下一个INode

      unsigned int freeBlockNum;  //空闲盘块数

      unsigned int freeBlock[BLOCK_GROUP_SIZE];     //空闲盘块栈

      unsigned int nextFreeBlock;  //栈中下一个盘块

};

文字说明:

      空闲INode栈和空闲盘块栈在形式上虽然表现为数组模式,但是通过nextFreeINode和nextFreeBlock的指向实现栈的弹出和弹入。当nextFreeBlock指向0且用户又申请盘块存储数据时,将通过读freeBlock[0]指向的盘块读入下一组盘块刷新freeBlock和nextFreeBlock。

3.2 磁盘iNode

dINode结构体:

structdINode //磁盘iNode

{

      unsigned int fileSize;  //文件大小

      unsigned int linkNum;     //文件的链接数

      unsigned int addr[6];  //文件地址:四个直接块号,一个一级间址,一个二级间址

      unsigned short ownerId;  //文件拥有者Id

      unsigned short groupId;  //文件所属组Id

      unsigned int mod;      //文件权限和类型

      long int createTime;   //文件创建时间

      long int modifyTime;  //文件最后修改时间

      long int readTime;           //文件最后访问时间

};

文字说明:

      fileSize不仅提供了计算文件地址的依据,也是控制数据读写的关键参数。

      linkNum为实现ln命令提供了方便,链接方和被链接方共享一个iNode,链接数也相应增加,进行删除命令删除一个链接文件时,只需使链接数减1并删除在父亲节点留下的目录信息即可,除非链接数为1时才真正删除该文件。

      ownerId为权限管理提供了依据。

      mod决定了文件的权限和类型:

dir=8,r=4,w=2,x=1

文件Mode

若要rwx属性则4+2+1=7

若要rw-属性则4+2=6

若要r-x属性则4+1=5

若要r--属性则4=4

若要-wx属性则2+1=3

若要-w-属性则2=2

若要--x属性则1=1

文件夹Mode

若要rw-属性则8+4+2=14

若要r--属性则8+4=12

若要-w-属性则8+2=10

3.3 内存iNode

iNode结构体:

structiNode    //内存iNode

{

      dINode dINode;

      iNode *parent;      //所属的目录i节点

      unsigned int nodeId;  //i节点Id

      unsigned int users;     //引用计数

};

文字说明:

      parent指针为cd ../操作提供了返回的路径。

3.4 目录

direct结构体:

structdirect    //目录项结构

{

      char name[MAX_NAME_SIZE];     //文件或目录的名字

      unsigned short iNodeId;  //文件或目录的i节点号

};

 

dir结构体:

structdir   //目录结构

{

      unsigned short dirNum;   //目录项数

      direct direct[MAX_DIRECT_NUM];     //目录项数组

      char padding[DIR_PADDING_SIZE];   //目录结构填充字符组

};

文字说明:填充字符为了使dir结构占512个字节方便读写。

3.5 用户

owner结构体:

structowner   //用户

{

      unsigned short ownerId;  //用户Id

      unsigned short groupId;  //组Id

      char ownerName[MAX_NAME_SIZE];      //用户名

      char ownerPassword[MAX_NAME_SIZE];//用户密码

};

 

owners结构体:

structowners  //用户组

{

      unsigned short ownerNum;   //用户项数

      owner os[MAX_OWNER_NUM];   //用户项组

};

3.6 用户组

group结构体:

structgroup    //组

{

      unsigned short groupId;  //用户组Id

      char groupName[MAX_NAME_SIZE];//组名

};

 

groups结构体:

structgroups  //组集合

{

      unsigned short groupNum;   //组数

      group gs[MAX_GROUP_NUM];

};

 

五、模块详解

5.1 文件操作

1.chgrp

1)     命令格式:

chgrp[组] [文件名]

2)     命令功能:

改变文件所属组

3)     命令参数:

[组]:用户组ID

[文件名]:文件名称

2.chown

1)     命令格式:

chown [用户][文件名]

2)     命令功能:

改变文件拥有者。

3)     命令参数:

[用户名]:用户ID

[文件名]:文件名称

3.chmod

1)     命令格式:

chmod [mod] [文件名]

2)     命令功能:

改变文件所属的权限和类型。

3)     命令参数:

[mod] 文件权限码

dir=8,r=4,w=2,x=1

文件mode

若要rwx属性则4+2+1=7

若要rw-属性则4+2=6

若要r-x属性则4+1=5

若要r--属性则4=4

若要-wx属性则2+1=3

若要-w-属性则2=2

若要--x属性则1=1

文件夹mode

若要rw-属性则8+4+2=14

若要r--属性则8+4=12

若要-w-属性则8+2=10

[文件名] 文件名称

4.cat

1)     命令格式:

cat [文件名]

2)     命令功能:

连接显示文件内容

5.cp

1)     命令格式:

cp [源] [目的]

2)     命令功能:

复制源文件到目的文件,若目的文件不存在则创建一个,若存在则目的文件被覆盖。

3)     命令参数:

[源]:源文件

[目的]:目的文件

6.touch

1)     命令格式:

touch [文件名]

2)     命令功能:

创建一个新的不存在文件

7.>> 

1)     命令格式:

>> [文件名]

2)     命令功能:

向已存在文件追加内容。(输入ctrl+q,回车结束输入)

8.mv

1)     命令格式:

mv [文件] [新文件名]

2)命令功能:

      更改文件的文件名。

9.rm

2)     命令格式:

rm [文件]

2)命令功能:

      文件删除。

10.ln

3)     命令格式:

mv [源] [目的]

2)命令功能:

      将源文件链接到目的文件。

 

 

5.2目录操作

1.     ls

1)     命令格式:

ls

2)     命令功能:

打印出当前目录清单。

2.     pwd

1)     命令格式:

pwd

2)     命令功能:

查看当前目录路径。

3.     cd

1)     命令格式:

cd [目录名]

2)     命令功能:

改变当前目录。

4.     mkdir

1)     命令格式:

mkdir [目录名]

2)     命令功能:

在当前目录下创建子目录。

5.     rmdir

1)命令格式:

rmdir [目录名]

2)命令功能:

删除指定目录和该目录下所有内容。

6.     ln

1)命令格式:

ln   [源] [目的]

2)命令功能:

      将源目录链接到目标目录。

 

5.3核心函数

核心函数表

函数名

描述

void initGlobal(FILE* f);

初始化全局变量、超级块、用户、用户组和成组链接信息(均写入磁盘),仅当模拟磁盘文件不存在时调用

void initSystem();

初始化文件系统:读入超级块、用户、用户组、当前目录

bool readINode(iNode* r);

读取磁盘INode信息,成功返回true,失败返回false

bool writeINode(iNode* w);

写入磁盘INode信息,成功返回true,失败返回false

bool writeSuperBlock();

写入超级块信息,成功返回true,失败返回false

bool writeDir(unsigned int blockId,dir* d);

写入目录结构,成功返回true,失败返回false

bool readDir(unsigned int blockId,dir* d);

读取目录结构,成功返回true,失败返回false

bool readNextBG();

读取下一组盘块组信息,,成功返回true,失败返回false

int mkdir(iNode* parent,char name[MAX_NAME_SIZE]);

创建目录,返回状态码

int getFreeBlock();

获取空闲盘块,成功返回空闲盘块号,失败返回状态码

int getFreeINode();

获取空闲INode节点,成功返回空闲INode节点,失败返回状态码

int login();

登录,返回状态码

void commandDispatcher();

命令分派器

void displayCommands();

显示所有命令

string pwd();

返回当前路径字符串

string trim(string s);

去除字符串两侧空格

int readCurDir();

读取当前目录,返回状态码

string ls();

返回当前目录清单字符串

bool checkFileName(char name[MAX_NAME_SIZE]);

检查当前目录下是否存在该名字,存在返回true,不存在返回false

int cd(char name[MAX_NAME_SIZE]);

改变当前目录,返回状态码

int superMkdir(iNode* parent,char name[MAX_NAME_SIZE],unsigned short ownerId,unsigned short groupId);

创建用户目录,返回状态码

int chmod(char name[MAX_NAME_SIZE],unsigned int mod);

改变文件权限,返回状态码

int chown(char name[MAX_NAME_SIZE],unsigned short ownerId);

改变文件拥有者,返回状态码

int chgrp(char name[MAX_NAME_SIZE],unsigned short groupId);

改变文件所属组,返回状态码

int passwd();

更改当前用户密码,返回状态码

bool writeOS();

写入用户组信息,成功返回true,失败返回false

int mv(char oldName[MAX_NAME_SIZE],char newName[MAX_NAME_SIZE]);

修改文件名,返回状态码

int touch(iNode* parent,char name[MAX_NAME_SIZE]);

创建新文件,返回状态码

int writeText(iNode* temp,string text);

写入文件内容,返回状态码

int textAppend(char name[MAX_NAME_SIZE]);

文件内容追加操作,返回状态码

int cat(char name[MAX_NAME_SIZE]);

显示文件内容,返回状态码

int readText(iNode *temp);

读取文件内容,返回状态码

int rm(char name[MAX_NAME_SIZE]);

删除文件,返回状态码

int returnFreeBlock(unsigned int blockId);

回收空闲盘块,返回状态码

int returnFreeINode(unsigned int iNodeId);

回收空闲INode节点,返回状态码

int ln(char source[MAX_NAME_SIZE],char des[MAX_NAME_SIZE]);

链接源文件至目标文件,返回状态码

void rmIter(unsigned short iNodeId);

迭代删除目录下所有内容(即级联删除)

int rmdir(char name[MAX_NAME_SIZE]);

删除目录操作,返回状态码

int cp(char source[MAX_NAME_SIZE],char des[MAX_NAME_SIZE]);

复制源文件至目标文件,返回状态码

string getText(iNode* temp);

获取文件内容字符串

 


0 0
原创粉丝点击