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 從程序...