linux内核函数open源码,open()在Linux内核的实现(1)-基本实现
原標題:open()在Linux內核的實現(1)-基本實現
1.基本說明
在用戶態使用open()時,必須向該函數傳入文件路徑和打開權限。這兩個參數傳入內核后,內核首先檢查這個文件路徑存在的合法性,同時還需檢查使用者是否有合法權限打開該文件。如果一切順利,那么內核將對訪問該文件的進程創建一個file結構。
在用戶態,通常open()在操作成功時返回的是一個非負整數,即所謂的文件描述符(fd,file deor);并且,用戶態后續對文件的讀寫操作等都是通過fd來完成的。由此可見fd與file結構在內核中有一定的關聯。
具體的,內核使用進程描述符task_struct來描述一個進程,而該進程所有已打開文件對應的file結構將形成一個數組files(其為files_struct結構),內核向用戶返回的fd便是該數組中具體file結構的索引。默認情況下,每個進程創建后都已打開了標準輸入文件、標準輸出文件、標準錯誤文件,因此他們的文件描述符依次為0、1和2。
2.函數分析2.1.do_sys_open
明白了上述原理,那么open系統調用在內核中的基本實現過程就很清晰。根據系統調用入口函數的命名規則,open系統調用的入口函數應該為sys_open。不過,目前內核統一使用SYSCALL_DEFINEn宏來描述系統調用入口函數,因此可以在open.c文件中找到該入口函數,具體如下所示:
1
SYSCALL_DEFINE3(open,constchar__user *, filename,int, flags,int, mode);
該函數內部直接調用了do_sys_open函數,具體聲明如下:
1
longdo_sys_open(intdfd,constchar__user *filename,intflags,intmode);
這個函數的參數基本上與open系統調用的參數一致。
該函數可以簡單概括open系統調用的功能:
1.通過build_open_flags()將用戶態的flags和mode轉換成對應的內核態標志;
2.由于filename是用戶態的內存緩沖區(使用了__user修飾),因此通過getname()將文件名從用戶態拷貝至內核態;
3.get_unused_fd_flags()為即將打開的文件分配文件描述符;也就是在當前進程的files數組中尋找一個未使用的位置;
4.通過do_filp_open()為文件創建file結構體;
5.如果創建file成功,則通過fd_install()將fd和file進行關聯;如果創建file失敗,通過put_unused_fd()將已分配的fd返回至系統,并且根據file生成錯誤的fd;
6.通過putname()釋放在內核分配的路徑緩沖區;
7.返回fd;
當open系統調用執行完畢后,fd返回用戶態,內核態新建了與其關聯的file;對于每個進程而言,通過files_struct來記錄其所打開的文件,具體通過fd_array數據保存fd和file的對應關系,fd本質為該數組的索引。
3.總結
至此,open的基本實現過程已經分析完畢。不過do_sys_open函數沒有直接體現文件路徑的查找過程,這部分將是整個open系統調用內核實現的重要部分。如果對此感興趣,可以繼續閱讀本系列后續文章。
參考資料:
1.Linux源碼3.2.69;
2.Linux系統調用open七日游:http://blog.chinaunix.net/uid-20522771-id-4419666.html
3.深入理解Linux內核:http://book.douban.com/subject/2287506/;
4.深入Linux內核架構:http://book.douban.com/subject/4843567/;
5.Linux內核探秘:http://book.douban.com/subject/25817503/;返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的linux内核函数open源码,open()在Linux内核的实现(1)-基本实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 伤感的游戏名字855个
- 下一篇: 描写秋天的词语有哪些