inode和逻辑块,目录的结构,挂载的实现 源码级分析linux内核的文件系统的结构
创始人
2024-06-01 08:42:16
0

在这里插入图片描述

bitmap.c 位图相关

封装了set_bit clear_bit find_first_zero clear_block等操作位图的宏

对应i节点位图和逻辑块位图有对应的四个函数 free_inode, new_inode,free_block, new_block

new_block 创建逻辑块

通过super_block找到逻辑块位图,给逻辑块位图的第一个空闲位(find_first_zero) 置1 (set_bit),获得逻辑块号后,通过getblk(dev,j)来申请一个缓冲块指向设备中的逻辑块,清空缓冲块,从而让对应的设备上的逻辑块清空。bh->b_dirt = 1出现了两次,一次是修改逻辑块位图要落盘,一次是new逻辑块要落盘。

free_block 释放逻辑块

通过super_block找到逻辑块位图,给逻辑块位图的对应的占用位置0 (clear_bit),同时使得hash_table中的该块对应的缓冲块(如果有的话)失效bh->b_uptodate=0

  • 有了缓冲区的存在创建和释放逻辑块的速度非常快,不涉及到同步IO,后面会在某个时刻将buffer同步到设备上的逻辑块。创建和释放也只是操作位图

new_inode 创建i节点

通过super_block找到i节点位图,给i节点位图的第一个空闲位(find_first_zero) 置1 (set_bit),获得i节点号后,通过get_empty_inode取得inode_table中空闲i节点,设置i_count,i_dev,i_num,即说明dev设备的num号i节点被使用(count)。i_dirt,b_dirt都置1,修改的i节点位图要落盘,新的i节点要落盘

free_inode 释放i节点

通过super_block找到i节点位图,给i节点位图的对应的占用位置0 (clear_bit),同时使得inode_table中的该i节点失效memset(inode,0,sizeof(*inode))

inode.c i节点相关

read_inode 读i节点 static

从设备上读取含有指定i节点信息的i节点(d_inode)盘块,然后复制到指定的i节点(m_inode)结构中。

write_inode 写i节点 static

把参数指定的i节点(m_inode)写入缓冲区相应的缓冲块(d_inode)中,bh->b_dirt=1,待缓冲区刷新时会写入盘中。i节点内容已经与缓冲区中的一致,因此修改标志置零inode->i_dirt=0

iget 取一个i节点

首先在位于高速缓冲区中的i节点表中搜寻,若找到指定节点号的i节点则在经过一些判断处理后返回该i节点指针。否则read_inode从设备dev上读取指定i节点号的i节点信息放入i节点表中,并返回该i节点指针。

iput 放回一个i节点

该函数主要用于把i节点引用计数值递减1,并且若是管道i节点,则唤醒等待的进程。若是块设备文件i节点则刷新设备。并且若i节点的链接计数为0,则释放该i节点占用的所有磁盘逻辑块,并释放该i节点。

get_empty_inode

从i节点表(inode table)中获取一个空闲i节点项,寻找引用计数count为0的i节点,并将其写盘后清零,返回其指针。引用计数被置1。

bmap/create_block (f, x) = y

文件数据块映射到盘块的处理操作。(block位图处理函数,bmap: block map) 对于文件f中的第x个数据块,对应的是磁盘上的逻辑块y,返回y,后续根据(dev, y)去访问文件。create_block即为文件f(也可能是目录)的第x个数据块分配一个逻辑块y
在这里插入图片描述

namei.c 目录/软硬链接

add_entry/find_entry static

在这里插入图片描述

添加/查找dir目录下的name目录项,通过res_dir返回目录项,以及目录项所在缓冲区的buffer_head,因为之后肯定涉及到目录项的修改,buffer_head->dirt =1

static struct buffer_head * add_entry(struct m_inode * dir,const char * name, int namelen, struct dir_entry ** res_dir)
static struct buffer_head * find_entry(struct m_inode ** dir,const char * name, int namelen, struct dir_entry ** res_dir)

get_dir static

// 搜寻指定路径名的目录(或文件名)的i节点。
// 参数:pathname-路径名。
// 返回:目录或文件的i节点指针。失败时返回NULL。
// usr/src/linux  : src						  linux不是最顶层目录,因为后面没有/
// usr/src/linux/ : linux
// usr/src/linux/1.txt : linux                可知道最顶层目录是  [xxx]/的形式
static struct m_inode * get_dir(const char * pathname)

dir_namei static

/**	dir_namei函数返回指定目录名的i节点指针,以及在最顶层目录的名称。*/
// 参数:pathname-目录路径名:namelen-路径名长度:name-返回的最顶层目录名。
// 返回:指定目录名最顶层目录的i节点指针 | 最顶层目录名称及长度。      
// pathname: /home/zyx/video  则 namelen:5 name:video          
// 出错时返回NULL。注意!! 这里"最顶层目录"是指路径名中最靠近末端的目录。
// usr/src/linux  : 		返回src			name:linux		len:5					  
// usr/src/linux/ :			返回linux		name:""			len:0
// usr/src/linux/1.txt : 	返回linux       name:1.txt   	len:4
static struct m_inode * dir_namei(const char * pathname,int * namelen, const char ** name)

namei

// 取指定路径名的i节点 
// pathname:路径名
// 返回对应的i节点
// 即:
// usr/src/ 				src节点				dir_namei后返回src
// usr/src/linux			src下搜linux目录	iget后返回linux
// usr/src/linux/1.txt: 	linux下搜1.txt文件	iget后返回1.txt
struct m_inode * namei(const char * pathname)

*open_namei

根据路径名返回对应的i节点。

// namei
// 参数filename是文件名,flag是打开文件标志,它可取值:O_RDONLY(只读)、O_WRONLY
// (只写)或O_RDWR(读写),以及O_CREAT(创建)、O_EXCL(被创建文件必须不存在)、
// O_APPEND(在文件尾添加数据)等其他一些标志的组合。如果本调用创建了一个新文件,则
// mode就用于指定文件的许可属性。这些属性有S_IRWXU(文件宿主具有读、写和执行权限)、
// S_IRUSR(用户具有读文件权限)、S_IRWXG(组成员具有读、写和执行权限)等等。对于新
// 创建的文件,这些属性只应用于将来对文件的访问,创建了只读文件的打开调用也将返回一
// 个可读写的文件句柄。参见相关文件sys/stat.h、fcntl.h。
// 返回:成功返回0,否则返回出错码:res_inode 返回对应文件路径名的i节点指针。
int open_namei(const char * pathname, int flag, int mode,struct m_inode ** res_inode)

目录相关的系统调用 mkdir rmdir link unlink

super.c 挂载是怎么实现的

get_super

取指定设备的超级块,在超级块表(数组)中搜索指定设备dev的超级块结构信息。若找到则返回超级块的指针,否则返回空指针。

read_super

读取超级块信息,如果内存中的超级块数组没有该块,bh = bread(dev,1)直接读超级块到超级块数组中

*((struct d_super_block *) s) = *((struct d_super_block *) bh->b_data);检查i节点位图和逻辑块位图中的block数量 和 2+s->s_imap_blocks+s->s_zmap_blocks记录块数进行对比。

mount 挂载

mount相关的函数有三个,分别是 sys_umount sys_mount mount_root。把一个 mount -o ro /dev/hda1 /mnt 挂载会影响super_block的s_imount字段,以及挂在对应i节点的i_mount字段,后续在iget取节点时,如果是个挂在节点,就会返回对应的挂载的设备和i节点号

if (inode->i_mount)dev = super_block[i].s_dev;nr = ROOT_INO;

在这里插入图片描述

truncate.c

free_ind static

释放一次间接块

free_dind static

释放二次间接块

truncate

将节点对应的文件长度截为0,并释放占用的设备空间

相关内容

热门资讯

“黑马”县的“金”点子 转自:中国银行保险报网□崔艳丽 本报记者 章丽铃长久以来,安徽省滁州市凤阳县因“朱元璋故里”“小岗村...
匠心守护绿茵烽火 智慧赋能城市...   初夏的江苏,绿茵场上烽火正燃。  由江苏省体育局与江苏省各设区市政府联合主办的江苏省城市足球联赛...
半月4家未盈利企业IPO获受理... 导读:虽然科创板、创业板已经开始受理未盈利企业IPO,但对于多数未盈利企业而言,港交所上市的可能性仍...
求一些恋爱养成游戏 求一些恋爱养成游戏翼之梦论坛知道吧?进去注册个号,有一个PC中文版的版块,进去什么都有。这个游戏不到...
为什么山上有老虎? 为什么山上有老虎?因为山上比较便于躲藏,也有各种小动物,是比较适合此类猛兽生活的环境
<<济南的冬天&g... <<济南的冬天>>板书设计有谁可以告诉我的板书设计在哪里可以找到?知到的朋友们请回答我好吗? 济...
带丈的四字成语 带丈的四字成语 火冒三丈软红十丈日落千磨颂迹丈尺水丈波百丈竿头食必方丈巾帼丈夫女中丈夫食前方丈白...
淮南:共同切磋比拼 技能大赛展... (转自:淮南日报)共同切磋比拼 技能大赛展风采“各位评委老师好,我们本次的参赛主题叫做《檐角飞云处 ...
幸福从天而降电视剧结局 幸福从天而降电视剧结局  1、《幸福从天而降》结局:天蓝用自己的经历告诫天晴,终于让天判孝晴打消了离...
51比50,副总统万斯投下关键... 转自:中安在线当地时间7月1日,美国国会参议院通过全面减税和支出法案,并提交众议院。美国参议院当天上...