1. 程式人生 > >open調用過程

open調用過程

__user 操作 pac style set bsp lin 包含 使用

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調用過程