一个令人拍案叫绝的Linux内核补丁

如果在系统中读一个文件时会调用

generic_file_buffered_read

这个函数的功能是把磁盘中的数据读到page之后,或者直接获取cache中的page,然后调用copy_page_to_iter把page拷贝到用户层的buffer中。

一天寂静的下午,得空,打开电脑,准备仔细研究一下这个函数,发现这个函数的注释上面就写明了:


  1. * This is really ugly. But the goto's actually try to clarify some 
  2. of the logic when it comes to error handling etc. 

仔细看了一下代码,果然ugly的不像话,到处都是跳转和判断,令人眩晕,而且整个函数达到300行左右(原谅我看了注释才斗胆这样讲:-) ),发现要是把这个函数看下去,今天一整天的心情都不会好了(当时看的是Linux5.10的代码)


  1. ssize_t generic_file_buffered_read(struct kiocb *iocb, 
  2.                 struct iov_iter *iter, ssize_t written) 
  3.  
  4. find_page: 
  5.                 if (fatal_signal_pending(current)) { 
  6.                         error = -EINTR; 
  7.                         goto out
  8.                 } 
  9.                         error = wait_on_page_locked_killable(page); 
  10.                         if (unlikely(error)) 
  11.                                 goto readpage_error; 
  12.                         if (PageUptodate(page)) 
  13.                                 goto page_ok; 
  14.  
  15.                         if (inode->i_blkbits == PAGE_SHIFT || 
  16.                                         !mapping->a_ops->is_partially_uptodate) 
  17.                                 goto page_not_up_to_date; 
  18.                         /* pipes can't handle partially uptodate pages */ 
  19.                         if (unlikely(iov_iter_is_pipe(iter))) 
  20.                                 goto page_not_up_to_date; 
  21.                         if (!trylock_page(page)) 
  22.                                 goto page_not_up_to_date; 
  23.                         /* Did it get truncated before we got the lock? */ 
  24.                         if (!page->mapping) 
  25.                                 goto page_not_up_to_date_locked; 
  26.                         if (!mapping->a_ops->is_partially_uptodate(page, 
  27.                                                         offset, iter->count)) 
  28.                                 goto page_not_up_to_date_locked; 
  29.                         unlock_page(page); 
  30.                 } 

于是就想内核社区这么多牛人,他们整天盯着这些代码,肯定很多人早已经注意到了,于是想去看看有没有人提交patch重构这个函数:


  1. ./scripts/get_maintainer.pl   mm/filemap.c 
  2. linux-kernel@vger.kernel.org (open list) 

然后我就在下面网址中搜索generic_file_buffered_read,果然在10月25号(我看代码那天在11月1号前后),就有人发了相关patch:


  1. https://lore.kernel.org/lkml/ 
【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章