把文件写入内存linux,【5.linux操作系统】-文件/内存/io

虚拟文件系统

bVbvuYO?w=1396&h=896

cache有对磁盘的cache是磁盘到RAM的cache,innode cache也是。还有cpu的cache相当于RAM在cpu上的cache。

write()->sys_write(VFS)->ext2等的write->物理

磁盘 分区:文件,数据,交换区域

文件系统:

ext2 引导块,超级块(包含块大小等),i节点(可对应多级块3IPB,2IPB等),数据

崩溃恢复,元数据不一致,检查要遍历=》日志文件ext3,ext4

文件,目录(目录项缓存),inode,mount point

file {链表,pathh file_operations}

目录包含文件名,inode编号。目录自身的Inode中的类型不同,rename仅操作目录条目不动文件。

文件名到Inode有多个。硬链接指向一个Inode。软链接指向文件名

proc

虚拟文件可以向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段.开发新的:可加载内核模块(LKM)。存在内存中国,动态创建

ext2数据写入

每次更改磁盘会写inode和data位图(超级快),inode数据,data数据

完成附加操作的方法是打开文件,调用lseek()将文件偏移到文件末尾,然后在关闭文件之前对文件发出一个4KB的写入。我们还假设在磁盘上使用的是标准的简单文件系统结构,类似于我们前面章节的文件系统。这个小小的例子包括一个inode位图(只有8位,每个inode一个),一个数据位图(也是8位,每个数据块一个),inode(总共8个,编号为0到7,分布在四个块)和数据块(总共8个,编号为0到7)。下面是这个文件系统的图示:

bVbvuRD?w=511&h=99

bVbvuRP?w=509&h=94

崩溃恢复要fsck扫超级快,元数据块,数据块

日志记录型文件系统

包括Linux ext3和ext4、ReiserFS、IBM的JFS、SGI的XFS和WindowsNTFS。思想来自数据库的redo log

ext3在2基础上加一个日志块

1.日志记录元信息,数据变化

我们首先将TxB、I[v2]、B[v2]、DB和TxE写入日志。当这些写入完成时,我们将通过检查点来完成对I[v2]、B[v2]和DB的写入。

TxB、I[v2]、B[v2]、DB 可以正常发,因为顺序会乱,跟调度相关。为了确保TxE的写入是原子的,应该将它变成一个512字节的块

1).日志写入:将事务的内容(包括TxB、元数据和数据)写入日志;等待这些写入完成。

2).日志提交:将事务提交块(包含TxE)写入日志;等待写入完成

3).检查点: 将更新的内容(元数据和数据)写入它们对应的最终磁盘位置。

2.只记录元信息

1).数据写入:将数据写入最终位置;等待完成(等待是可选的;详见下文)。

2).日志元数据写入:将BEGIN块和元数据写入日志;等待写入完成。

3).日志提交:将事务提交块(包含TxE)写入日志;等待写入完成;完后后事务(包括数据)就表示已经提交了。

4).检查点元数据:将元数据的内容写入文件系统中的最终位置。

5).释放:稍后,在日志超级块中标记事务。

文件查找

文件查找过程:

● 路径解析

● 读取目录项(dentry)内容

● 根据文件名搜索目录项,获取inode位置

● 读取inode信息

● 定位所要访问的块位置

● 访问相应数据块

为描述方便,将目录项和inode内容统称为元数据。通常,元数据和文件的数据内容存放在不同的区域。

在分布式文件系统中,管理区和数据区一般还分散在不同的物理机器上。

小文件问题:

● 元数据和文件数据一般是分区域的,一次IO访问将实际产生多个IO请求

● 元数据相对较大,缓存代价比较昂贵

● 目录项及目标数据块的检索效率

● 频繁增删改带来的碎片化问题

块IO

硬盘等,随机访问的,区别于字符设备只能顺序访问

块缓冲区,已经合成一个页缓存

调度 块IO请求队列(一个块设备一个)

linusx电梯 合并请求,临近插入

最终期限 超时时间(读500ms,写5s)三个队列:读FIFO/写FIFO/排序队列同linus=>超时派发队列

预测IO 超时后等几ms,相邻合并

完全公正,每个进程一个队列

空IO,只合并相邻的

bVbvdyt?w=1180&h=1082

sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。fsync等磁盘结束返回

进程地址空间

连续虚拟地址

mm_struct 分配,撤销……{内存区域vm_area_struct红黑树和链表,pgd,所有mm_struct链表,每段起始地址等}

vm_area_strict区间地址等。

虚拟地址=》物理页面 三级页表(pgd,pmd,pte)硬件效率有限,TLB缓存

在堆上分配,sbrk。改变programm break位置,进程可以访问这部分地址,若RAM未分配,内核会在进程是首次访问这些虚拟内存地址时自动分配新RAM页

malloc,free内找/分割,不够sbrk

bVbvgla?w=1028&h=758

页缓存(磁盘和内存ms/ns的差距)

页告诉缓存是RAM组成,对应硬盘上的物理块(扇区整数倍但比页小,一般512B/1kb/4kb),

linux 写缓存,标记脏,脏页链表, 回写进程刷会磁盘

缓存回收 LRU 双链(活跃/非活跃)

address_space 每页一个

页内搜索 基树。回收时要反向检查引用的项。根据页内偏移起终范围找vma,起点基树,终点堆,很多个共同引用优先搜索树(堆+基树)。

回写线程flusher 一个设备一个线程,每个收集自己的。以前固定线程数,当一个设备阻塞会阻塞其上个所有线程。因为拥塞发生次数太频繁改一个设备一个线程。

若页属于一个文件(该文件存放在磁盘上文件系统中,如ext4),那么页的所有者就是文件的inode;并且对应的address_space对象存放在VFS inode对象的i_data字段中。

fd与磁盘的关联

fd->file->path->dentry->inode->address_space->page->buffer_head->磁盘块号

https://segmentfault.com/a/11...

IO分类综述

1.磁盘文件,内核有cache,不需要等实际的写入,读取cache没有会让进程休眠,同时读入。所以没有阻塞的概念呢。除非inotify的文件,read无事件时阻塞。可以用信号IO形式。(vfs->cache->disk。DIRECTIO直接VFS->DISK。SYNC模式CACHE后阻塞的DISK。DISK向下有IO等待队列)

read->cache不在page_cache_sync_readhead可能会预读,进程挂起恢复还是从cache读。写不在add_to_page_cache_lru。

DMA是磁盘到cache不需要CPU

directio generic_file_direct_IO取代page_cache_sync_readhead,__blockdev_direct_IO() 会一直等到所有的 I/O 操作都结束才会返回,因此,一旦应用程序 read() 系统调用返回,应用程序就可以访问用户地址空间中含有相应数据的缓冲区。但是,这种方法在应用程序读操作完成之前不能关闭应用程序,这将会导致关闭应用程序缓慢。写要检查缓冲区有先刷回去再写。

2.其他FIFO,套接字,管道,终端,伪终端可以设置阻塞/非阻塞。非阻塞多路复用:select/poll/epoll,信号驱动.以上都需要同步IO操作,即只是告诉就绪(除非是AIO)。读写的过程还是一样的,看各种的自己了比如套接字就是send buf而不是磁盘的cache了。

select(nfds,readxx) nfds比要检查的fd大1,read等感兴趣位图和结果位图,要遍历

什么是就绪?IO不阻塞就是就绪,普通文件一直不阻塞,不能用

select和poll都是水平触发

信号驱动IO IO/文件nofity 边缘触发

epoll 可边缘/水平。

边缘:注意不再通知,还要注意防止饥饿。维护一个就绪文件描述符列表,读到EAGAIN移除,循环读取处理

虚拟内存交换等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值