第一部分——准备知识
磁盘格式化这一步骤到底做了什么?
为了读懂代码,首先先掌握几个知识点。
memcpy函数
void * __cdecl memcpy(_Out_writes_bytes_all_(_Size) void * _Dst, _In_reads_bytes_(_Size) const void * _Src, _In_ size_t _Size);
void *memcpy(void *memTo, const void *memFrom, size_t size)
{
if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效
return NULL;
char *tempFrom = (char *)memFrom; //保存memFrom首地址
char *tempTo = (char *)memTo; //保存memTo首地址
while(size -- > 0) //循环size次,复制memFrom的值到memTo中
*tempTo++ = *tempFrom++ ;
return memTo;
}
struct direct{
char d_name[DIRSIZ];//目录名
unsigned int d_ino;//磁盘 i节点标识符id
};
strcpy(dir_buf[0].d_name,"..");//父目录
dir_buf[0].d_ino = 1;
strcpy(dir_buf[1].d_name,".");//当前目录root
dir_buf[1].d_ino = 1;
strcpy(dir_buf[2].d_name,"etc");//子目录etc目录
dir_buf[2].d_ino = 2;
memcpy(disk+DATASTART, &dir_buf, 3*(DIRSIZ+4));//dir_buf中的前3个元素拷贝到磁盘数据区的第1个数据块
dir_buf是一个direct结构体,目录名是12个字节,int是4个字节,一共16个字节,拷贝到char中的连续的16个元素中,char一个元素就是一个字节。
memset函数
void * __cdecl memset(_Out_writes_bytes_all_(_Size) void * _Dst, _In_ int _Val, _In_ size_t _Size);
memset(disk, 0x00, ((DINODEBLK+FILEBLK+2)*BLOCKSIZ));
把_Dst所指内存区域的前_Size个字节设置成字符 _Val。
软链接和硬链接
- 格式化将分区分成等大小的数据块block。
- 用户想要去找一个叫sb的文件,先去找inode,从inode得知sb存在哪些数据块。
- 硬链接
假设创建了sb的硬链接文件叫做bs,bs和sb拥有相同的inode的id号,inode相同,存储的数据块也就相同。sb和bs相当于同一个文件,只不过叫不同的名字。一间教室的前门和后门。如果删除任何一个,通过另一个也能访问存储空间,可以理解成同一个存储空间的不同入口。
不能跨分区使用,sb和bs需要在同一个分区。
不能针对目录使用。
- 软链接
假设为csb,有自己的inode和数据块,用户访问csb,先找到csb自己的inode结点,然后找到自己的数据块,在找到原文件的inode,再找到原文件的数据块。
修改原文件,软链接也变,因为原始数据块变了。
修改软链接,最终也是修改原文件的数据块,原文件也被修改了。
删除原文件,软链接不能打开了。
删除原文件,硬链接还可以打开。
第二部分——代码解读
inode解读
目录项=文件名+磁盘结点标号
文件系统存储结构
格式化是要将磁盘分成等大小的数据块,确定inode的数量和数据块的数量,并做一些初始的写入工作,比如创建根目录和一些必要的目录等等。
ls -i 查看文件的inode结点
0. 整个磁盘被划分为等大小的块,称为物理块,引导块占第0个物理块,超级块占用第1个物理块,inode结点表占用接下来的物理块,数据块占用剩下的物理块