linux内核多个补丁,一个令人惊叹的Linux内核补丁
我们都知道linux内核中的代码非常精妙,但是有些代码由于历史原因,一个函数为了兼容处理各种情况,到最后可能变得非常糟糕,到处都是goto 和if,看的想跳楼(宋老师口头禅^_^)
如果在系统中读一个文件时会调用
generic_file_buffered_read
这个函数的功能是把磁盘中的数据读到page之后,或者直接获取cache中的page,然后调用copy_page_to_iter把page拷贝到用户层的buffer中。
一天寂静的下午,得空,打开电脑,准备仔细研究一下这个函数,发现这个函数的注释上面就写明了:
* This is really ugly. But the goto's actually try to clarify some
* of the logic when it comes to error handling etc.
仔细看了一下代码,果然ugly的不像话,到处都是跳转和判断,令人眩晕,而且整个函数达到300行左右(原谅我看了注释才斗胆这样讲:-) ),发现要是把这个函数看下去,今天一整天的心情都不会好了(当时看的是Linux5.10的代码)
ssize_t generic_file_buffered_read(struct kiocb *iocb,
struct iov_iter *iter, ssize_t written)
{
find_page:
if (fatal_signal_pending(current)) {
error = -EINTR;
goto out;
}
error = wait_on_page_locked_killable(page);
if (unlikely(error))
goto readpage_error;
if (PageUptodate(page))
goto page_ok;
if (inode->i_blkbits == PAGE_SHIFT ||
!mapping->a_ops->is_partially_uptodate)
goto page_not_up_to_date;
/* pipes can't handle partially uptodate pages */
if (unlikely(iov_iter_is_pipe(iter)))
goto page_not_up_to_date;
if (!trylock_page(page))
goto page_not_up_to_date;
/* Did it get truncated before we got the lock? */
if (!page->mapping)
goto page_not_up_to_date_locked;
if (!mapping->a_ops->is_partially_uptodate(page,
offset, iter->count))
goto page_not_up_to_date_locked;
unlock_page(page);
}
于是就想内核社区这么多牛人,他们整天盯着这些代码,肯定很多人早已经注意到了,于是想去看看有没有人提交patch重构这个函数:
./scripts/get_maintainer.pl mm/filemap.c
linux-kernel@vger.kernel.org (open list)
然后我就在下面网址中搜索generic_file_buffered_read,果然在10月25号(我看代码那天在11月1号前后),就有人发了相关patch:
https://lore.kernel.org/lkml/
然后迫不及待查看patch,并把整个patch 下载下来:
这里推荐一个工具,使用b4工具
https://git.kernel.org/pub/scm/utils/b4/b4.git
可以直接从
https://lore.kernel.org
获取原始格式的patch,便于自己git am之后测试。
# b4 am https://lore.kernel.org/lkml/20201025212949.602194-1-kent.overstreet@gmail.com
v2_20201025_kent_overstreet_generic_file_buffered_read_improvements.cover
v2_20201025_kent_overstreet_generic_file_buffered_read_improvements.mbx
然后直接 git am ,非常方便,这样就打上了lore.kernel.org上提交的patch.
git am v2_20201025_kent_overstreet_generic_file_buffered_read_improvements.mbx
提示:在git am之前,可以提前git apply --check 一下
# gitlogdate -3
fc5608fc9917 2020-10-25 Kent Overstreet fs: generic_file_buffered_read() now uses find_get_pages_contig
3bcadc3306be 2020-10-25 Kent Overstreet fs: Break generic_file_buffered_read up into multiple functions
3650b228f83a 2020-10-25 Linus Torvalds Linux 5.10-rc1
alias gitlogdate='git log --pretty=format:"%h%x09%ad%x09%an%x09%s" --date=short'
打了这个patch之后,generic_file_buffered_read变成了这个样子:
ssize_t generic_file_buffered_read(struct kiocb *iocb,
struct iov_iter *iter, ssize_t written)
{
..
pg_nr = generic_file_buffered_read_get_pages(iocb, iter,
pages, nr_pages);
...
for (i = 0; i < pg_nr; i++) {
copied = copy_page_to_iter(pages[i], offset, bytes, iter);
}
而且
generic_file_buffered_read_get_pages
也非常之清晰:
static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
struct iov_iter *iter,
struct page **pages,
unsigned int nr)
nr_got = find_get_pages_contig(mapping, index, nr, pages);
if (nr_got)
goto got_pages;
if (iocb->ki_flags & IOCB_NOIO)
return -EAGAIN;
page_cache_sync_readahead(mapping, ra, filp, index, last_index - index);
nr_got = find_get_pages_contig(mapping, index, nr, pages);
if (nr_got)
goto got_pages;
...
}
看完generic_file_buffered_read()之后,整个下午的心情都好多了。
ps: 这个补丁很快就被各种review, 并被相关maintainer收进自己仓库。
获取更多使用patch研究linux内核的方法,可以参考:
分享以原始patch开始深究Linux内核
linux内核多个补丁,一个令人惊叹的Linux内核补丁相关推荐
- 免费创建一个令人惊叹的网站的7个技巧
这里有一些好消息.你不需要花钱来创建一个令人惊叹的网站.你甚至不需要设计或编程经验.你所需要的只是一个互联网连接和一台电脑.就这么简单.看看这个,创建你自己的免费网站吧 1. 从环境中获得灵感 你的竞 ...
- 神经辐射场(NERF)模型:一个令人惊叹的三维场景重建方法
在计算机图形学.计算机视觉和增强现实等领域,三维场景重建一直是一个热门话题.近年来,神经网络模型的出现已经彻底改变了这个领域,而其中最引人注目的就是 NERF(神经辐射场)模型.在这篇文章中,我们将深 ...
- 2038年问题 linux内核5.6,又一个“千年虫”问题!Linux Kernel 5.6已着手应对
原标题:又一个"千年虫"问题!Linux Kernel 5.6已着手应对 新十年伊始,Linux Kernel 5.6 的开发者已经准备好着手解决将在下一个十年到来的 2038 年 ...
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- Linux内核分析2:一个简单的时间片轮转多道程序内核代码分析
Lab2:一个简单的时间片轮转多道程序内核代码 席金玉 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...
- 身份证扫描器web开发_如何以Web开发人员的身份建立一个令人惊叹的投资组合网站
身份证扫描器web开发 This sponsored article was created by our content partner, BAW Media. Thank you for supp ...
- linux软件实现看门狗,一个软件实现的Linux看门狗—soft_wdt
soft_wdt(下面简称本软件)是一个软件实现的Linux看门狗. 本软件是一款开源.免费软件. 下载地址: 本软件和/drivers/watchdog/softdog.c实现的软件看门狗差点儿一样 ...
- linux内核实验一:一个简单的时间片轮转多道程序内核代码
学号517原创作品,转载请注明出处. 本实验资源来源: https://github.com/mengning/linuxkernel/ 一.mykernel 本次实验是在孟宁老师所建立的一个供用户开 ...
- Linux云计算学习教程,一个全新的世界—Linux
1990 年代中期,因特网因出现 World Wide Web, HTML 这种新型态的应用, 而开始迅速的延烧全世界.一夕间,架设因特网主机的需求激增.这时有一套可 以免费取得,并且能让 x86 计 ...
- linux补丁rt ck pf zen,Linux 内核社区补丁对比
Linux 内核主线总体而言兼具了性能.稳定和安全于一身,不过总有些 Geek 不满足主线中的种种限制,使用各自社区的补丁为它添砖加瓦. 概述 pf内核,这算是一个非常为人熟知的内核.包含了ck补丁( ...
最新文章
- python基础-------迭代器,生成器,协程函数
- python算法与数据结构-二分查找算法
- [python] 基于k-means和tfidf的文本聚类代码简单实现
- STL中sort算法简析
- [js] 使用ajax请求真的不安全吗?为什么?
- 自动化测试工具selenium python_Selenium自动化测试工具使用方法汇总
- 编码规范二 缩进与注释
- Quartz调度源码分析
- spring this.logger.isDebugEnabled()
- 【No.1】基于Cookie的单点登录(SSO)
- MySql数据库导出完整版(导出数据库,导出表,导出数据库结构)
- python实现按照给定范围随机生成小数,偶数,奇数,整数,正态分布,均匀分布数据以及图片
- TechTool Pro 11 Mac(硬件检测和系统维护工具)附序列号中文版
- 大数据平台建设方案(项目需求与技术方案)
- JavaWeb之servlet详解(转帖)
- 通过jacob实现office在线预览
- SpringCloud分布式开发理解
- 解决Ubuntu系统上网速度慢的问题
- java-php-python-ssm企业员工考勤系统的设计与实现计算机毕业设计
- Lambda将搬砖变成艺术