@@ -5,7 +5,7 @@ categories:
55 - 内核层
66abbrlink : f548d964
77date : 2024-12-24 16:05:00
8- updated : 2024-12-31 11:30 :00
8+ updated : 2024-12-31 16:00 :00
99---
1010
1111<meta name =" referrer " content =" no-referrer " />
@@ -791,12 +791,14 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
791791
792792# page cache
793793
794- 笔记摘抄自文章 [https://blog.csdn.net/CoolBoySilverBullet/article/details/121747994 ](https://blog.csdn.net/CoolBoySilverBullet/article/details/121747994 )。
794+ 笔记摘抄自文章 [https://blog.ywang-wnlo.xyz/posts/9ba60726/ ](https://blog.ywang-wnlo.xyz/posts/9ba60726/ )。
795795
796796由于磁盘 HDD 以及现在广泛使用的固态硬盘 SSD 的读写速度都远小于内存 DRAM 的读写速度。为避免每次读取数据都要直接访问这些低速的底层存储设备,Linux 利用 DRAM 实现了一个缓存层,缓存的粒度是 page,也叫 page cache,也就是页(面)缓存。
797797
798798经过这层 page cache 的作用,I/O 的性能得到了显著的提升。不过由于 DRAM 具有易失性,在掉电后数据会丢失,因此内核中的 回写机制定时将 page cache 中的数据下刷到设备上,保证数据的持久化。此外内核还在 page cache 中实现了巧妙的预读机制,提升了顺序读性能。
799799
800+ 写入到 page cache 的数据不会立刻写入后端设备,而是标记为“脏”,并被加入到脏页链表,后续由内核中的回写进程周期性的将脏页写回到底层存储设备。
801+
800802在拥有 page cache 这一层后,写数据就有了三种不同的策略:
801803
8028041. **不经过缓存,直接写底层存储设备,但同时要使缓存中数据失效,也叫不缓存(nowrite)。**
@@ -809,7 +811,7 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
809811
810812第三种策略虽然能非常简单保证缓存和底层设备的一致性,不过基于时间局部性原理,page cache 中的数据可能只是中间态,会被频繁修改,每次写穿会产生大量的开销。
811813
812- 关于 page cache 的写回机制(write back),参考 [https://blog.csdn.net/CoolBoySilverBullet/article/details/121439670 ](https://blog.csdn.net/CoolBoySilverBullet/article/details/121439670 )。
814+ 关于 page cache 的写回机制(write back),参考 [https://blog.ywang-wnlo.xyz/posts/646202b9/ ](https://blog.ywang-wnlo.xyz/posts/646202b9/ )。
813815
814816# address_space
815817
@@ -853,6 +855,7 @@ struct address_space_operations {
853855 int (*readpage)(struct file *, struct page *);
854856
855857 /* Write back some dirty pages from this mapping. */
858+ // writepage() 或 writepages() 负责对这些物理页的实际写入。
856859 int (*writepages)(struct address_space *, struct writeback_control *);
857860
858861 /* Set a page dirty. Return true if this dirtied it */
@@ -866,9 +869,11 @@ struct address_space_operations {
866869 struct list_head *pages, unsigned nr_pages);
867870 void (*readahead)(struct readahead_control *);
868871
872+ // 主要负责查找、或者分配新的物理页,并将其锁定,有时还需要先从底层读取最新的数据页。
869873 int (*write_begin)(struct file *, struct address_space *mapping,
870874 loff_t pos, unsigned len, unsigned flags,
871875 struct page **pagep, void **fsdata);
876+ // 主要负责解锁这些物理页,并且更新 inode 中的元数据信息,例如 i_size。
872877 int (*write_end)(struct file *, struct address_space *mapping,
873878 loff_t pos, unsigned len, unsigned copied,
874879 struct page *page, void *fsdata);
0 commit comments