Linux檔案系統呼叫open 七日遊 (六)
阿新 • • 發佈:2018-11-08
還記得在上一個場景中,build_open_flags裡面有一個對標誌位O_PATH的判斷麼?現在我們就來看看這個標誌位是幹啥的:
【場景二】open(pathname,O_PATH)
這個O_PATH似乎是不常用的,咱們先看看它的使用說明:
【open(2)】 http://man7.org/linux/man-pages/man2/open.2.html
咱們還是先看看build_open_flags針對O_PATH做了什麼手腳:
【fs / open.c】 sys_open > do_sys_open > build_open_flags
【fs / namei.c 】 sys_open > do_sys_open > do_filp_open > path_openat> do_last
接下來lookup_open就不用說了吧,當它返回的時候路徑會站上最終目標,nd則原地不動,它在等待在觀望:如果path站上 不是符號連結或者即使是符號連結但是“即使是符號連結也OK啦”(3003)就會跟著路站上最終目標,然後在finish_open中完成開啟。
finish_open主要是呼叫do_dentry_open,我們進去看看:
【FS /open.c】 sys_open > do_sys_open > do_filp_open > path_openat> do_last
好像這個O_PATH情景比上一個O_RDONLY還要簡單,那我們就再假設一個情景。
轉自:http://blog.chinaunix.net/uid-20522771-id-4426763.html
【場景二】open(pathname,O_PATH)
這個O_PATH似乎是不常用的,咱們先看看它的使用說明:
【open(2)】 http://man7.org/linux/man-pages/man2/open.2.html
- O_PATH(自Linux 2.6.39起)
- 獲取可用於兩個目的的檔案描述符:指示檔案系統樹中的位置並執行純粹在檔案描述符級別的操作。檔案本身未開啟
- 可以對生成的檔案描述符執行以下操作:
-
- * close(2); fchdir(2)(自Linux 3.5起); fstat(2)(自Linux 3.6起)。
- *複製檔案描述符(dup(2),fcntl(2)F_DUPFD等)。
- *獲取和設定檔案描述符標誌(fcntl(2)F_GETFD和F_SETFD)。
- *使用fcntl(2)F_GETFL操作檢索開啟檔案狀態標誌:返回的標誌將包括位O_PATH。
- *將檔案描述符作為openat(2)的dirfd引數和另一個“* at()”系統呼叫傳遞。這包括linkat(2)與AT_EMPTY_PATH(或通過使用AT_SYMLINK_FOLLOW的procfs),即使該檔案不是目錄。
- *通過UNIX域套接字將檔案描述符傳遞給另一個程序(請參閱unix(7)中的SCM_RIGHTS)。
- 在flags中指定O_PATH時,將忽略O_CLOEXEC,O_DIRECTORY和O_NOFOLLOW以外的標誌位。
- 如果路徑是一個符號連結和O_NOFOLLOW標誌也s ^ pecified,則呼叫返回一個檔案描述符指
咱們還是先看看build_open_flags針對O_PATH做了什麼手腳:
【fs / open.c】 sys_open > do_sys_open > build_open_flags
點選(此處)摺疊或開啟
- static inline int build_open_flags (int flags , umode_t mode , struct open_flags * op )
- {
...
- } else if ( flags & O_PATH ) {
- / *
- * 如果我們在開啟標誌中有O_PATH 。 然後我們
- *除了以下標誌集之外,不能有任何其他內容
- * /
- flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH ;
- acc_mode = 0 ;
- } else {
...
- op - > intent = flags & O_PATH ?0 : LOOKUP_OPEN ;
...
- if ( flags & O_DIRECTORY )
- lookup_flags | = LOOKUP_DIRECTORY ;
- if (!( flags & O_NOFOLLOW ))
- lookup_flags | = LOOKUP_FOLLOW ;
- op - > lookup_flags = lookup_flags ;
- 返回0 ;
- }
【fs / namei.c 】 sys_open > do_sys_open > do_filp_open > path_openat> do_last
點選(此處)摺疊或開啟
- static int do_last ( struct nameidata * nd , struct path * path ,
- struct file * file , const struct open_flags * op ,
- int * opens , struct filename * name )
- {
...
- if (!( open_flag & O_CREAT )) {
- 如果 ( ND - >最後。名[ ND - >最後。LEN ] )
- nd - > flags | = LOOKUP_FOLLOW | LOOKUP_DIRECTORY ;
- 如果 ( open_flag & O_PATH && !( ND - >標誌及 LOOKUP_FOLLOW ))
- symlink_ok = true ;
...
- }
...
- error = lookup_open ( nd , path , file , op , got_write , opened );
...
- if ( should_follow_link ( path - > dentry , ! symlink_ok )) {
...
- 返回1 ;
- }
...
- 誤差 = finish_open (檔案,第二- >路徑。目錄項, NULL ,開啟);
...
- }
接下來lookup_open就不用說了吧,當它返回的時候路徑會站上最終目標,nd則原地不動,它在等待在觀望:如果path站上 不是符號連結或者即使是符號連結但是“即使是符號連結也OK啦”(3003)就會跟著路站上最終目標,然後在finish_open中完成開啟。
finish_open主要是呼叫do_dentry_open,我們進去看看:
【FS /open.c】 sys_open > do_sys_open > do_filp_open > path_openat> do_last
點選(此處)摺疊或開啟
- static int do_dentry_open ( struct file * f ,
- int (* open )( struct inode * , struct file * ),
- const struct cred * cred )
- {
...
- if (不太可能( f - > f_flags & O_PATH )) {
- f - > f_mode = FMODE_PATH ;
- f - > f_op = & empty_fops ;
- 返回0 ;
- }
...
- }
好像這個O_PATH情景比上一個O_RDONLY還要簡單,那我們就再假設一個情景。
轉自:http://blog.chinaunix.net/uid-20522771-id-4426763.html