您好,登錄后才能下訂單哦!
這篇文章主要介紹“Linux內核補丁舉例分析”,在日常操作中,相信很多人在Linux內核補丁舉例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Linux內核補丁舉例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
如果在系統中讀一個文件時會調用
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; ... }
到此,關于“Linux內核補丁舉例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。