【Linux内核】---- 03 安装文件系统
发布日期:2021-06-29 14:51:06
浏览次数:3
分类:技术文章
本文共 2890 字,大约阅读时间需要 9 分钟。
【Linux内核】---- 03 安装文件系统
3.1 从硬盘上获取hello.txt 文件的 i 节点
在文件系统中,每个文件都对应一个唯一的 i 节点。
目录文件和普通文件是有区别的,它们存储的内容不一样。目录文件存储着若干个目录项,每个目录项由两部分组成:
一个是文件名,表明该项目所对应的文件名,它可以是对应着普通文件,也可以对应着目录。 另一个是 i 节点号,表明该目录项所对应的文件在 i 节点表中的项号,通过这个i节点表中找到所对应的文件的 i 节点。整个解析过程如下
根目录文件 i 节点 ----> 找到根目录文件 ----> mnt目录文件 i 节点 ----> 对应硬盘上超级块 ----> 磁盘根目录文件 i 节点----> 找到硬盘根目录文件 ----> user目录文件 i 节点 —> 找到user 目录文件 ----> hello.txt文件 i 节点 —> 找到hello.c 文件。3.1.1 准备查找枝梢 i 节点 ---- user目录文件的 i 节点
hello.txt 的目录为 /mnt/user/hello.txt
通过路径解析出 i 节点,这是由open_namei函数完成的,所以sys_open 函数接下来要调用open_namei// fs/open.cint sys_open(const char * filename, int flag, int mode){ if( (i = open_namei(filename, flag, mode, &inode) ) < 0 ) ...}
进入 open_namei 函数后,调用 dir_namei 函数,通过解析路径名得到枝梢 i 节点,对于 “/mnt/user/hello.txt” 这个路径名而言,枝梢i 节点就是 user这个目录文件的 i 节点,执行代码如下:
// fs/namei.cint open_namei(const char * pathname, int flag , int mode, struct m_inode ** res_inode){ if(!(dir = dir_namei(pathname, &namelen, &basename ))) ...}
进入 dir_namei 函数 后,调用 get_dir 函数,同时将路径名也传递下去,开始实质性的 i 节点解析工作。
// fs/namei.cstatic struct m_inode * dir_namei(const char * pathname, int * namelen, const char ** name){ if(!(idr = get_dir(pathname))) ...}
3.1.2 确定查找操作起点
进入 get_dir 函数后,开始对路径名进行分析,
// fs/namei.cstatic struct m_inode * get_dir(const char * pathname ){ if((c = get_fs_byte(pathname)) == '/' ){ inode = current->root; pathname++; }}
3.1.3 获得名为mnt的目录项
- 先解析出 mnt 这个字符串的长度。
// 代码路径: fs/namei.cstatic struct m_inode * get_dir(const char * pathname){ for(namelen = 0; (c = get_fs_byte(pathname++)) && (c!='/'); namelen++)}
- 再以mnt这个名字为参照,在根目录文件中找到名字为mnt的目录项,
// 代码路径: fs/namei.cstatic struct m_inode * get_dir(const char * pathname){ if(!(bh=find_entry(&inode, thisname, namelen, &de)))}
thisname 标识了mnt字符串的起始位置,namelen标识了该字符串的长度,这样就能锁写mnt这个 字符串。
进入find_entry函数后,开始将根目录文件读取出来,从中找到 名字为mnt的目录项,读取并分析的过程 是这样的: 先确定这个目录文件的大小,因为确定了大小就可以确定目录文件包含多少条目录项,方法是通过根 i 节点中表示根目录文件大小的 i_size 字段除以每个目录占用的字节数。// fs/namei.cstatic struct buffer_head * find_entry(struct m_inode ** dir, const char * name, int namelen, struct dir_entry ** res_dir){ entries = (*dir)->i_size / (sizeof( struct dir_entry) );}
- 从目录文件的第一个数据块开始读取数据,将数据块读入到 缓冲块,并调用match(namelen, name, de) 函数分析这些数据中有没有mnt的目录项。
// fs/namei.cstatic struct buffer_head * find_entry(struct m_inode ** dir , const char *name, int namelen, struct dir_entry ** res_dir){ if(! (bh = bread((*dir)->i_dev, block)) ) de = (struct dir_entry *)bh->b_data; while(i < entries){ if((char *)de >= BLOCK_SIZE + bh->b_data){ breles(bh); bh = NULL; if(! (block = bmap(*dir, i/DIR_ENTRIES_PER_BLOCK)) || !(bh = bread((*dir)->i_dev, block))){ i += DIR_ENTRIES_PER_BLOCK; continue; } de = (struct dir_entry *) bh->b_data; } if(match(namelen, name, de)){ *res_dir = de; return bh; } de++; i++; }}
- 最终找到 mnt 这个目录项,值得注意的是,根目录文件在虚拟盘上,所以此时调用bread 函数从设备上读取数据并不会产生中断,之后,find_entry 函数就返回了,
转载地址:https://ciellee.blog.csdn.net/article/details/104837103 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
很好
[***.229.124.182]2024年04月25日 04时56分11秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
树莓派网线直连
2019-04-29
复合材料培训(I第七期)
2019-04-29
复合材料生活中的应用
2019-04-29
ABAQUS复合材料(适合小白)
2019-04-29
ABAQUS高级案例解析
2019-04-29
人工智能药物研发
2019-04-29
【超级干货+福利】AIDD最全面的学习教程
2019-04-29
最新通知:AIDD与网络药理学资料大全
2019-04-29
Lammps分子动力学与第一性原理材料模拟及催化
2019-04-29
实习生小白的日常
2019-04-29
实习小白的日常(3)
2019-04-29
实习小白的日常(4)
2019-04-29
APP页面布局参考
2019-04-29
linux 的 Socket IO 模型
2019-04-29
APP调用服务器API设计
2019-04-29
Opencv+Zbar二维码识别(标准条形码/二维码识别)
2019-04-29
zbar优化
2019-04-29
微信扫码登录验证PHP代码(不用开放平台)
2019-04-29
CH554E USB单片机 10引脚小封装低成本USB方案
2019-04-29