從open系統呼叫的原始碼看檔案的開啟過程

2021-05-23 13:36:49 字數 3077 閱讀 6808

我們常常使用系統呼叫open來開啟乙個檔案,例如:

fd = open( "/mnt/data/myfile",o_rdwr|o_creat);

下面來看看linux是如何完成的,首先是系統呼叫的**:

sys_open的源程式

view plaincopy to clipboardprint?

asmlinkage long sys_open(const char * filename, int flags, int mode)  

out:  

putname(tmp);  

}  

return fd;  

out_error:  

put_unused_fd(fd);  

fd = error;  

goto out;  

}  asmlinkage long sys_open(const char * filename, int flags, int mode)

out:

putname(tmp);

}return fd;

out_error:

put_unused_fd(fd);

fd = error;

goto out;

} 這裡面完成的幾個工作

1.注意到返回乙個整數fd,所以在(1)的位置獲得乙個整數fd。

2.根據路徑/mnt/data/myfile找到(或建立)檔案,並且建立乙個結構file(見(2))。

3.將整數fd和file結構指標f聯絡起來(見(3))。

注意:結構file實際上是系統開啟檔案表中的表項,目的是實現不同程序共享檔案的讀寫指標的情形。(另外一種檔案共享是不同的程序有各自的檔案讀寫指標的情形)。

檔案開啟過程的總結:

系統在程序開啟檔案表中找到乙個未使用的fd;

根據open中提供的路徑字串找到(建立)對應的dentry(從而找到inode);

建立系統開啟檔案表中的乙個開啟檔案表項(建立乙個file結構,使用指標filp指向file結構),並使該表項指向dentry(file的字段之一就是f_dentry,指向被開啟檔案在其目錄中的表項dentry);

在fd所指示的程序開啟檔案表表項中設定指向file結構的指標;

系統使用filp->f_dentry->d_inode的方式訪問磁碟inode,將其讀入記憶體中,建立對應的vnode。因此,可以認為系統開啟檔案表表項有指標指向vnode結構

進一步了解:

linux 2.6.11核心檔案io系統呼叫

linux 2.6.11核心檔案io系統呼叫

1.        引言

從事linux環境工作2年有餘,一直懵懵懂懂,1年前拜讀了《萊昂氏unix源**分析》一書,感覺自己的學習道路漫漫且修遠。最近受chinaunix的精華文帖啟發,擬將近來的部分核心呼叫分析筆記拿出來與各前輩先進共同**學習,以壯個人學習之路。

本部分主要講述的是檔案i/o操作的2.6.11核心版本實現,包括了主要的資料結構、巨集定義和函式流程。以下分別講述open,create,close,read,write,lseek系統呼叫。

2.        主要參考

《萊昂氏unix源**分析》

《unix環境高階程式設計》

www.kernel.org

3.        主要資料結構

3.1.        fd

對於核心而言,所有開啟檔案都由檔案描述符引用。檔案描述符是乙個非負整數。當開啟乙個現存盤案或建立乙個新檔案時,核心向程序返回乙個檔案描述符。

當讀、寫乙個檔案時,用open或creat返回的檔案描述符標識該檔案,將其作為引數傳送給read或write。在posix.1應用程式中,檔案描述符為常數0、1和2分別代表stdin_fileno、stdout_fileno和stderr_fileno,意即標準輸入,標準輸出和標準出錯輸出,這些常數都定義在標頭檔案

// 如果不是32位處理器,則增加大檔案標識

#if bits_per_long != 32

flags |= o_largefile;

#endif

// 為了提高使用效率,在使用之前先將檔名拷貝到核心資料區。見3.2.2說明

tmp = getname(filename);

// 獲取到返回值,如果出錯,則返回,否則執行開啟操作。

fd = ptr_err(tmp);

if (!is_err(tmp))

out:

// 釋放getname分配的記憶體空間

putname(tmp);

}return fd;

out_error:

// 將檔案表指標返回到程序的檔案表中,並返回錯誤**。

put_unused_fd(fd);

fd = error;

goto out;

}4.2.3.        sys_open子函式getname

getname函式主要功能是在使用檔名之前將其拷貝到核心資料區,正常結束時返回核心分配的空間首位址,出錯時返回錯誤**。其呼叫了函式do_getname來實現。

static inline int do_getname(const char __user *filename, char *page)

// 將filename拷貝len長度到page中,返回實際拷貝長度

retval = strncpy_from_user(page, filename, len);

if (retval >; 0) else if (!retval)

// filename 為空,則返回-enoent

retval = -enoent;

return retval;

}char * getname(const char __user * filename)

}// 如果前面操作成功,且audit_context不為空,則將當前檔名新增到audit列表中

if (unlikely(current->;audit_context) && !is_err(result) && result)

audit_getname(result);

// 返回處理結果

return result;

從Struts原始碼看action呼叫過程

從struts原始碼看action呼叫過程,以下 片斷來自struts1.1 struts中所有的請求都是通過actionservlet 的,乙個action請求首先會傳給actionservlet,actionservlet會將其委託給requestprocessor,requestprocess...

nginx原始碼分析 從原始碼看nginx框架總結

nginx原始碼總結 1 中沒有特別繞特別彆扭的編碼實現,從變數的定義呼叫函式的實現封裝,都非常恰當,比如從函式命名或者變數命名就可以看出來定義的大體意義,函式的基本功能,再好的架構實現在編碼習慣差的人實現也會黯然失色,如果透徹理解 的實現,領悟架構的設計初衷,覺得每塊 就想經過耐心雕琢一樣,不僅僅...

從原始碼看Handler和Looper

private looper boolean quitallowed public handler looper looper,callback callback,boolean async public inte ce callback從looper的構造方法可以看出,looper建立messag...