Skip to content

Latest commit

 

History

History
102 lines (76 loc) · 4.13 KB

9_磁盘的结构.md

File metadata and controls

102 lines (76 loc) · 4.13 KB

磁盘的结构

[ boot block | sb block | log | inode blocks | free bit map | data blocks ]

  • 超级块里有一个魔数用来验证文件系统
  • 超级块里保存了日志区,inode区,位图区的起始位置
  • 超级块里保存了日志区,inode区,数据区和整个镜像的大小

函数的功能

/*
 * 作用: 依据块的使用情况写位图区
 * int : 已经使用的块的数量
 * 原理: 
 */
void balloc(int);                                                       

/*
 * 作用:向指定扇区写入数据。
 * sec : sect No.
 * *buf : 要写入扇区的数据。
 * 原理:首先用lseek系统调用定位到扇区所在的位置,然后用write系统调用把arg2写入到对应扇区。
 */
void wsect(uint, void*);  

/*
 * 作用: 依据inode的编号把它对应的数据结构写入到硬盘的inode区
 * uint: inode的编号。
 * struct dinode*: 用来指向inode对应的数据结构
 * 原理:
 */
void winode(uint, struct dinode*);                                       

/*
 * 作用:依据inode的编号获取它的数据结构
 * inum : inode的编号
 * *ip : 用来指向inode对应的数据结构
 * 原理:
 */
void rinode(uint inum, struct dinode *ip);                               

/*
 * 作用:从指定扇区读出数据
 * sec : sect No.
 * *buf : 缓冲区地址。
 * 原理 : 首先用lseek系统调用定位到扇区所在的位置,然后用read系统调用从对应扇区把数据读到缓冲区里。
 */
void rsect(uint sec, void *buf);                                         

/*
 * 作用 : 分配一个inode
 * type : inode类型,有目录、文件、设备三种类型
 * 返回值 : inode号
 * 原理 : 分配一个inode号并初始化一个dinode数据结构,然后调用winode把这个数据结构写入到inode区里inode号对应的位置。
 */
uint ialloc(ushort type);                                               

/*
 * 作用 : 向inode里添加内容
 * inum : inode号
 * *xp : 要添加的信息的指针
 * n : 要添加的信息的大小
 * 原理 : 首先得到这个文件的大小,把它赋值给off变量。 进而得到当前文件末尾的块编号fbn,进而得到分配的块号x。然后以buf为缓冲区,把不大于1个块的内容写入x号块。调整n,off,p的值,并持续循环,直到把所有的内容都写到块里。最后,修改inode的属性,并调用winode把inode的信息再写回磁盘。
 */
void iappend(uint inum, void *p, int n);

格式化的过程

本程序的功能是创建一个格式化的镜像。至少要有两个参数,第一个参数是镜像名称,第二个及以后的参数是要放到镜像里的文件的名称。镜像有1000个块,每个块1KB,故镜像大小为1M。

数据结构de代表了目录文件里的每一项。

字符数组buf的大小是一个块的大小,这样可以方便地把buf里的数据写入到扇区里。

整数freeinode代表了空闲inode的编号。每分配出一个inode它就执行加1操作。

首先,使用系统调用open,以第一个参数为文件名创建一个文件,其文件描述符赋值给fsfd。

然后,计算各个数据区的大小。

  • 启动块和超级块点两个块。
  • 日志块nlog占30个块,inode块ninodeblocks占的块数(即inode的总数200除以每个块可以保存的inode数据结构的数量,其值为13),位图占用的块数nbitmap,其值为1。
  • 如上的块组成元数据区nmeta,共占46个块。
  • 除了元数据区,镜像空间剩下的即为数据区nblocks,共占954个块。

然后,填充超级块的数据结构。xint的作用是让数字满足内存里的表示形式,即低位放在低字节,高位放在高字节。

然后,在for循环里调用wsect函数把整个镜像填充为0。

然后,把超级块的内容写入到1号扇区。

然后,为根目录分配一个inode号rootino。

然后,为根目录添加条目...

然后,在一个for循环里,把要传入的文件依次复制到镜像的根目录下。

然后,修改根目录所对应的inode的数据结构的size属性。

最后,执行balloc函数,把数据块的使用情况写入到位图区。