open系統呼叫 建立file結構體

2021-05-25 08:14:30 字數 3151 閱讀 7037

open系統呼叫:建立file結構體,(指標)放入程序開啟檔案表,返回表下標(檔案描述符)

**:我們常常使用系統呼叫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;

creat 與open 系統呼叫

creat 建立檔案,顯然引數只需要 路徑path,許可權mode 1 如果檔案存在怎麼辦?直接覆蓋掉!不管你裡面有沒有內容。include include include includeusing namespace std int main 建立成功,但是有個問題。給的許可權八進位制777最大許...

open 系統呼叫的實現

open系統呼叫的服務例程是sys open 函式,它接受三個引數 要開啟檔案的路徑名filename,訪問模式的表示flags和檔案許可權掩碼mode。在核心中,sys open實際呼叫do sys open函式來完成所有操作。do sys open主要執行如下操作 1,通過getname 從程序...

open 系統呼叫的實現

open系統呼叫的服務例程是sys open 函式,它接受三個引數 要開啟檔案的路徑名filename,訪問模式的表示flags和檔案許可權掩碼mode。在核心中,sys open實際呼叫do sys open函式來完成所有操作。do sys open主要執行如下操作 1,通過getname 從程序...