读取硬盘前的准备工作有哪些?

db583e547b0b9e3e10da303f4d059b12.gif

作者 | 闪客sun

来源 | 低并发编程

读取硬盘数据到内存中,是操作系统的一个基础功能。

读取硬盘需要有块设备驱动程序,而以文件的方式来读取则还有要再上面包一层文件系统。

把读出来的数据放到内存,就涉及到内存中缓冲区的管理。

上面说的每一件事,都是一个十分庞大的体系,我们今天的文章一个都不展开讲,哈哈。

我们就讲讲,读取块设备与内存缓冲区之间的桥梁,块设备请求项的初始化工作。

我们以 Linux 0.11 源码为例,发现进入内核的 main 函数后不久,有这样一行代码。

void main(void) {...blk_dev_init();...
}

看到这个方法的全部代码后,你可能会会心一笑,也可能一脸懵逼。

void blk_dev_init(void) {int i;for (i=0; i<32; i++) {request[i].dev = -1;request[i].next = NULL;}
}

这也太简单了吧?

就是给 request 这个数组的前 32 个元素的两个变量 devnext 附上值,看这俩值 -1NULL 也可以大概猜出,这是没有任何作用时的初始化值。

我们看下 request 结构体。

/** Ok, this is an expanded form so that we can use the same* request for paging requests when that is implemented. In* paging, 'bh' is NULL, and 'waiting' is used to wait for* read/write completion.*/
struct request {int dev;        /* -1 if no request */int cmd;        /* READ or WRITE */int errors;unsigned long sector;unsigned long nr_sectors;char * buffer;struct task_struct * waiting;struct buffer_head * bh;struct request * next;
};

注释也附上了。

哎哟,这就有点头大了,刚刚的函数虽然很短,但看到这个结构体我们知道了,重点在这呢。

这也侧面说明了,学习操作系统,其实把遇到的重要数据结构牢记心中,就已经成功一半了。比如主内存管理结构 mem_map,知道它的数据结构是什么样子,其功能也基本就懂了。

收,继续说这个 request 结构,这个结构就代表了一次读盘请求,其中:

dev 表示设备号,-1 就表示空闲。

cmd 表示命令,其实就是 READ 还是 WRITE,也就表示本次操作是读还是写。

errors 表示操作时产生的错误次数。

sector 表示起始扇区。

nr_sectors 表示扇区数。

buffer 表示数据缓冲区,也就是读盘之后的数据放在内存中的什么位置。

waiting 是个 task_struct 结构,这可以表示一个进程,也就表示是哪个进程发起了这个请求。

bh 是缓冲区头指针,这个后面讲完缓冲区就懂了,因为这个 request 是需要与缓冲区挂钩的。

next 指向了下一个请求项。

这里有的变量看不懂没关系。

不过我们倒是可以基于现有的重点参数猜测一下,比如读请求时,cmd 就是 READ,sector nr_sectors 这俩就定位了所要读取的块设备(可以简单先理解为硬盘)的哪几个扇区,buffer 就定位了这些数据读完之后放在内存的什么位置。

这就够啦,想想看,这四个参数是不是就能完整描述了一个读取硬盘的需求了?而且完全没有歧义,就像下面这样。

82b20feffee2918c6f19f92cabc4b9e4.png

而其他的参数,肯定是为了更好地配合操作系统进行读写块设备操作嘛,为了把多个读写块设备请求很好地组织起来。这个组织不但要有这个数据结构中 hb 和 next 等变量的配合,还要有后面的电梯调度算法的配合,仅此而已,先点到为止。

总之,我们这里就先明白,这个 request 结构可以完整描述一个读盘操作。然后那个 request 数组就是把它们都放在一起,并且它们又通过 next 指针串成链表。

1f1ccba061ad42cc90a82949112dbd89.png

好,本文讲述的两行代码,其实就完成了上图所示的工作而已。

但讲到这就结束的话,很多同学可能会不太甘心,那我就简单展望一下,后面读盘的全流程中,是怎么用到刚刚初始化的这个 request[32] 结构的。

读操作的系统调用函数是 sys_read,源代码很长,我给简化一下,仅仅保留读取普通文件的分支,就是如下的样子。

int sys_read(unsigned int fd,char * buf,int count) {struct file * file = current->filp[fd];struct m_inode * inode = file->f_inode;// 校验 buf 区域的内存限制verify_area(buf,count);// 仅关注目录文件或普通文件return file_read(inode,file,buf,count);
}

看,入参 fd 是文件描述符,通过它可以找到一个文件的 inode,进而找到这个文件在硬盘中的位置。

b9b99786450c40fa4270eed67b09355c.png

另两个入参 buf 就是要复制到的内存中的位置,count 就是要复制多少个字节,很好理解。

钻到 file_read 函数里继续看。

int file_read(struct m_inode * inode, struct file * filp, char * buf, int count) {int left,chars,nr;struct buffer_head * bh;left = count;while (left) {if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) {if (!(bh=bread(inode->i_dev,nr)))break;} elsebh = NULL;nr = filp->f_pos % BLOCK_SIZE;chars = MIN( BLOCK_SIZE-nr , left );filp->f_pos += chars;left -= chars;if (bh) {char * p = nr + bh->b_data;while (chars-->0)put_fs_byte(*(p++),buf++);brelse(bh);} else {while (chars-->0)put_fs_byte(0,buf++);}}inode->i_atime = CURRENT_TIME;return (count-left)?(count-left):-ERROR;
}

整体看,就是一个 while 循环,每次读入一个块的数据,直到入参所要求的大小全部读完为止。

直接看 bread 那一行。

int file_read(struct m_inode * inode, struct file * filp, char * buf, int count) {...while (left) {...if (!(bh=bread(inode->i_dev,nr)))}
}

这个函数就是去读某一个设备的某一个数据块号的内容,展开进去看。

struct buffer_head * bread(int dev,int block) {struct buffer_head * bh = getblk(dev,block);if (bh->b_uptodate)return bh;ll_rw_block(READ,bh);wait_on_buffer(bh);if (bh->b_uptodate)return bh;brelse(bh);return NULL;
}

其中 getblk 先申请了一个内存中的缓冲块,然后 ll_rw_block 负责把数据读入这个缓冲块,进去继续看。

void ll_rw_block(int rw, struct buffer_head * bh) {...make_request(major,rw,bh);
}static void make_request(int major,int rw, struct buffer_head * bh) {...
if (rw == READ)req = request+NR_REQUEST;elsereq = request+((NR_REQUEST*2)/3);
/* find an empty request */while (--req >= request)if (req->dev<0)break;...
/* fill up the request-info, and add it to the queue */req->dev = bh->b_dev;req->cmd = rw;req->errors=0;req->sector = bh->b_blocknr<<1;req->nr_sectors = 2;req->buffer = bh->b_data;req->waiting = NULL;req->bh = bh;req->next = NULL;add_request(major+blk_dev,req);
}

看,这里就用到了刚刚说的结构咯。

具体说来,就是该函数会往刚刚的设备的请求项链表 request[32] 中添加一个请求项,只要 request[32] 中有未处理的请求项存在,都会陆续地被处理,直到设备的请求项链表是空为止。

具体怎么读盘,就是与硬盘 IO 端口进行交互的过程了,可以继续往里跟,直到看到一个 hd_out 函数为止,本讲不展开了。

具体读盘操作,后面会有详细的章节展开讲解,本讲你只需要知道,我们在 main 函数的 init 系列函数中,通过 blk_dev_init 为后面的块设备访问,提前建立了一个数据结构,作为访问块设备和内存缓冲区之间的桥梁,就可以了。

23c068d208eb7069ae08d0c458afd8d0.gif

往期推荐

进程切换的本质是什么?

一次限制进程的 CPU 用量的实操过程

Redis 内存满了怎么办?这样置才正确!

手工模拟实现 Docker 容器网络!

f3a0bcf9f9309c27ae820be9ba16400f.gif

点分享

376e182e55bbb5000618b34e13d9586b.gif

点收藏

e4ae5c2a19fcf40772628ca9a872e6a7.gif

点点赞

6500d38127805ed7c34bd9765a1b3891.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【视频特辑】提效神器,如何用Quick BI高效配置员工的用数权限

简介&#xff1a;随着企业数字化进程逐步加速&#xff0c;企业所产生和积累的数据资源日益增多。每当员工的用数权限发生变动&#xff0c;管理员都需要进行复杂繁琐的重复性配置流程&#xff0c;不仅耗时耗力还容易出错。 如何能便捷地对员工用数权限进行高效管理&#xff1f;试…

让容器跑得更快:CPU Burst 技术实践

简介&#xff1a;让人讨厌的 CPU 限流影响容器运行&#xff0c;有时人们不得不牺牲容器部署密度来避免 CPU 限流出现。我们设计的 CPU Burst 技术既能保证容器运行服务质量&#xff0c;又不降低容器部署密度。CPU Burst 特性已合入 Linux 5.14&#xff0c;Anolis OS 8.2、Aliba…

实时数仓Hologres首次走进阿里淘特双11

简介&#xff1a;这是淘特在阿里巴巴参与的第二个双11大促&#xff0c;大促期间累计超过上千万消费者在此买到心仪的商品&#xff0c;数百万家商家因为淘特而变得不同&#xff0c;未来&#xff0c;淘特也将会继续更好的服务于下沉市场&#xff0c;让惠民走近千万家。 2021年11…

Cluster 集群能支撑的数据有多大?

作者 | 码哥字节来源 | 码哥字节本文将对集群的节点、槽指派、命令执行、重新分片、转向、故障转移、消息等各个方面进行深入拆解。目的在于掌握什么是 Cluster &#xff1f;Cluster 分片原理&#xff0c;客户端定位数据原理、故障切换&#xff0c;选主&#xff0c;什么场景使用…

All in one:如何搭建端到端可观测体系

简介&#xff1a;一文看懂可观测&#xff01; 作者&#xff1a;西杰 & 白玙 可观测的前生今世 系统的可观测与故障可分析作为系统运维中重要的衡量标准&#xff0c;随着系统在架构、资源单位、资源获取方式、通信方式演进过程&#xff0c;遇到了巨大挑战。而这些挑战&am…

链路分析 K.O “五大经典问题”

简介&#xff1a;链路分析是基于已存储的全量链路明细数据&#xff0c;自由组合筛选条件与聚合维度进行实时分析&#xff0c;可以满足不同场景的自定义诊断需求。 作者&#xff1a;涯海 链路追踪的 “第三种玩法” 提起链路追踪&#xff0c;大家会很自然的想到使用调用链排查…

Kubernetes 上容器的启动顺序如何把控?

作者 | AddoZhang来源 | 云原生指北为什么要做容器启动顺序控制&#xff1f;我们都知道 Pod 中除了 init-container 之外&#xff0c;是允许添加多个容器的。类似 TektonCD 中 task 和 step 的概念就分别与 pod 和 container 对应&#xff0c;而 step 是按照顺序执行的。此外还…

一文说清linux system load

简介&#xff1a;双十一压测过程中&#xff0c;常见的问题之一就是load 飙高&#xff0c;通常这个时候业务上都有受影响&#xff0c;比如服务rt飙高&#xff0c;比如机器无法登录&#xff0c;比如机器上执行命令hang住等等。本文就来说说&#xff0c;什么是load&#xff0c;loa…

KubeDL 0.4.0 - Kubernetes AI 模型版本管理与追踪

简介&#xff1a;欢迎更多的用户试用 KubeDL&#xff0c;并向我们提出宝贵的意见&#xff0c;也期待有更多的开发者关注以及参与 KubeDL 社区的建设&#xff01; 作者&#xff1a;陈裘凯&#xff08; 求索&#xff09; 前言 KubeDL 是阿里开源的基于 Kubernetes 的 AI 工作负…

上云一时爽,遇坑泪两行

如今&#xff0c;企业的数字化转型进程已经进入了“快车道”&#xff0c;各行各业基于自身业务发展与变革的需要&#xff0c;为整体数字化转型带来了更多要求。企业纷纷依托云原生、低代码、大数据、人工智能等技术手段积极加入这场没有硝烟的战争。 对于传统企业而言&#xf…

读研期间一定得看论文吗_读研期间各阶段的目标和任务,你明确吗?

读研期间一般都要经历上课、论文材料的收集、论文的开题、发表小论文、毕业论文的答辩、找工作或考博士等几个关键环节。在校期间&#xff0c;我们不仅要完成以上的全部工作&#xff0c;还需要不断地学习正确的价值观和人生观&#xff0c;学会科学的思考。如何让自己的研究生生…

Spring Boot Serverless 实战系列“架构篇” | 光速入门函数计算

简介&#xff1a;如何以 Serverless 的方式运行 Spring Boot 应用&#xff1f; 作者&#xff1a;西流&#xff08;阿里云函数计算专家&#xff09; Spring Boot 是基于 Java Spring 框架的套件&#xff0c;它预装了 Spring 一系列的组件&#xff0c;开发者只需要很少的配置即可…

从 “香农熵” 到 “告警降噪” ,如何提升告警精度?

简介&#xff1a;ARMS 智能降噪功能依托于 NLP 算法和信息熵理论建立模型&#xff0c;从大量历史告警事件中去挖掘这些事件的模式规律。当实时事件触发后&#xff0c;实时为每一条事件打上信息熵值与噪音识别的标签&#xff0c;帮助用户快速识别事件重要性。 作者&#xff1a;…

AI 机器学习如何不被底层资源和数据“拉胯”,听听亚马逊云科技怎么说

编辑 | 宋慧 出品 | CSDN 云计算 在人工智能从爆火到普及应用之后&#xff0c;数据分析今年又一次被技术界广泛关注&#xff0c;热度再次到达高点。 分析与咨询机构也纷纷发表与数据相关的报告&#xff0c;德勤在刚刚发布的《 2022年度技术趋势 》中&#xff0c;第一个趋势即是…

Flow vs Jenkins 实操对比,如何将Java应用快速发布至ECS

简介&#xff1a;Jenkins 由于其开源特性以及丰富插件能力&#xff0c;长久以来都是中小企业搭建 CICD 流程的首选。不过 Jenkins 存在维护成本高、配置复杂等缺点&#xff0c;云效 Flow 较好地解决了这些问题。 本文从一个 Java 应用部署到云服务器&#xff08;ECS&#xff09…

CSS 中的简写到底有多少坑?以后不敢了...

作者 | 零一来源 | 前端印象简写&#xff08;语法糖&#xff09;可能给我们编码带来了很多便利&#xff0c;但简写也会带来一些问题&#xff0c;今天来讨论一下 CSS 中的简写的"爱恨情仇"为什么说是爱恨情仇呢&#xff1f;因为简写给我们带来了很多的便利&#xff0c…

智能巡检云监控指标的实践

简介&#xff1a;在真实的企业生产中&#xff0c;对研发和运维的同学都会面临一个十分繁复且艰难的问题&#xff0c;就是对指标的监控和告警。具体我枚举一些特定的问题请对号入座&#xff0c;看看在算力爆炸的时代能否通过算力和算法一起解决&#xff01; 背景介绍 在真实的…

新常态成型,飞连联手Forrester聚焦数字化办公新体验

随着互联网技术不断发展&#xff0c;在企业办公领域时间与空间的限制正在逐步消弭。但是&#xff0c;当企业面对内外部大量的不确定因素时&#xff0c;以往的办公模式无论是效率、安全性还是体验等各方面都将大打折扣。而在数字时代&#xff0c;混合办公模式则有望成为企业办公…

聊聊我们在业务链路升级中做的数据洞察

简介&#xff1a;关于数据相关的词条很多&#xff0c;虽然有不同的定义&#xff0c;但是本质上是相辅相成&#xff0c;通常结合使用才能拿到结果。类比词条诸如 数据分析&#xff0c;数据挖掘&#xff0c; 数据洞察。本文将聊聊我们在业务链路升级中做的数据洞察。 作者 | 金铎…

阿里云佘俊泉:创新探索不停,边缘云持续为客户创造价值

简介&#xff1a;在12月15日上午举办的分布式云领袖论坛中&#xff0c;阿里云边缘云产品负责人佘俊泉先生发表了《阿里云边缘云产品创新与场景探索》的主题演讲&#xff0c;分享了阿里云在边缘云领域的探索和思考&#xff0c;如何从产品演进、技术创新、场景应用等方面助力企业…