open調用過程
1. 首先傳到vfs的do_sys_open,在open.c中。
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
此時,我們只知道open傳遞過來的一些參數,比如filename,open調用是這樣的
int open(const char *pathname, int flags, mode_t mode);
因此,只有dfd是新加的,我們先不管他的作用。
do_sys_open主要做以下事情
(1) int fd = build_open_flags(flags, mode, &op);//將open傳遞過來的flags和mode進行整理,賦值給op
fd = get_unused_fd_flags(flags);//分配一個未使用的fd
這個fd就是返回給用戶open函數的fd。
(2) tmp = getname(filename); 將文件名做整理,並填充給tmp結構//struct filename *tmp;
(3) struct file *f = do_filp_open(dfd, tmp, &op); 這個就是實際的打開函數,填充struct file
(4) fd_install(fd, f); 將fd與 f進行關聯。
2. 上面第(3)步是核心內容。首先我們在這裏看struct file結構,/include/linux/fs.h
裏面有三個比較重要的域。
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
struct address_space *f_mapping;
我們看do_filp_open如何對他們進行填充。
(1)首先創建struct nameidata nd; set_nameidata(&nd, dfd, pathname); struct nameidata 含有域struct path root; struct inode *inode; struct inode *link_inode;等。set_nameidata主要使用參數 pathname 。
struct task_struct首先使用局部指針指向當前進程的nameidata, struct nameidata *old = current->nameidata; 也即是說,每個進程結構包含一個nameidata
然後只是給nd的total_link_count和pathname賦值。inode並沒有管。total_link_count據說是用來防止循環死鏈的。
(2) filp = path_openat(&nd, op, flags | LOOKUP_RCU);
首先是file = get_empty_filp(); 為struct file 分配內存。
(3)主要的打開操作在 do_last 中。
link_path_walk 用於一級一級解析文件路徑,每一級都調用do_last。 參考:http://alanwu.blog.51cto.com/3652632/1120652
open調用過程