本文转载自微信公众号《邂逅Linux》,作者JeffXie。转载本文请联系邂逅Linux公众号。我们都知道linux内核中的代码是非常精巧的,但是由于历史的原因,有些代码为了兼容处理各种情况,最后可能会变得很烂。到处都是goto和if,让人想跳楼(宋老师的口头禅^_^)如果在系统中读取文件时调用了函数generic_file_buffered_read,该函数就是将磁盘中的数据读取到page,或者直接获取缓存中的page,然后调用copy_page_to_iter将page复制到用户层的buffer中。一个安静的下午,闲下来的时候,我打开电脑,准备仔细研究一下这个功能。我发现这个函数的注释是这样写的:*Thisreallyugly.到处都是跳转和判断,看得人眼花缭乱,整个函数达到了300行左右(原谅我看评论才敢说这个:-)),我发现如果我看这个函数,我不会今天一整天都心情愉快。就好了(当时看的是Linux5.10的代码)ssize_tgeneric_file_buffered_read(structkiocb*iocb,structiov_iter*iter,ssize_twritten){find_page:if(fatal_signal_pending(current)){error=-EINTR;gotoout;}error=wait_on_page_locked_killable(page);if(不太可能(error))gotoreadpage_error;if(PageUptodate(page))gotopage_ok;if(inode->i_blkbits==PAGE_SHIFT||!mapping->a_ops->is_partially_uptodate)gotopage_not_up_to_date;/*pipescan'thandlepartiallyuptodatepages*/if(不太可能(iov_iter_is_pipe(iter)))gotopage_not_up_to_date;if(!trylock_page(page))gotopage_not_up_to_date;/*Diditgettruncatedbeforewegotthelock?*/if(!page->mapping)gotopage_not_up_to_date_locked;if(!mapping->a_ops->is_partially_upageoffset,iter->count))gotopage_not_up_to_date_locked;unlock_page(page);}于是想到kernel社区那么多好人,整天盯着这些代码,肯定很多人都注意到了,所以想看看有没有人提交patch到重构这个函数:./scripts/get_maintainer.plmm/filemap.clinux-kernel@vger.kernel.org(openlist)然后在下面的网址里搜索generic_file_buffered_read,是10月25号的(我是11月1号左右看到的代码).有人发来相关补丁:https://lore.kernel.org/lkml/迫不及待查看补丁并下载了整个补丁:这里推荐一个工具,使用b4工具https://git.kernel.org/pub/scm/utils/b4/b4.git可以直接从https://lore.kernel.org获取原始格式补丁,方便gitam后测试#b4amhttps://lore.kernel.org/lkml/20201025212949.602194-1-kent.overstreet@gmail.comv2_20201025_kent_overstreet_generic_file_buffered_read_improvements.coverv2_20201025_kent_overstreet_generic_file_buffered_read_improvements.mbx然后直接gitam,非常方便,这样就打上了lore.kernel.org上提交的patch.gitamv2_20201025_kent_overstreet_generic_file_buffered_read_improvements.mbx提示:在gitam之前,可以提前gitapply--check一下#gitlogdate-3fc5608fc99172020-10-25KentOverstreetfs:generic_file_buffered_read()nowusesfind_get_pages_contig3bcadc3306be2020-10-25KentOverstreetfs:Breakgeneric_file_buffered_readupintomultiplefunctions3650b228f83a2020-10-25LinusTorvaldsLinux5.10-rc1aliasgitlogdate='gitlog--pretty=format:"%h%x09%ad%x09%an%x09%s"--date=short'Afterplayingthispatch,generic_file_buffered_readbecomeslikethis:ssize_tgeneric_file_buffered_read(structkiocb*iocb,structiov_iter*iter,ssize_twritten){..pg_nr=generic_file_buffered_read_get_pages(iocb,iter,pages,nr_pages);...for(i=0;i
