如果在系统中读一个文件时会调用
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/
