Linux VFS III

open()的最终目的是:准备好file以及依赖的数据结构。为此,open()主要做了以下几方面工作:

  1. PathWalk找到目标文件
  2. 构造并初始化inode
  3. 构造并初始化file

其中,PathWalk已经讨论过,本文主要聚焦inode和file的构造和初始化

SYSCALL_DEFINE3(open...)	//open.c +1038
	do_sys_open()
		build_open_flags()
		struct filename *tmp = getname()
			getname_flags()
				kname = (char*)result + sizeof(*result)
				result->name = kname
				strncpy_from_user(kname, filename,max)
				result->uptr = filename
		fd = get_unused_fd_flags()
			__alloc_fd()
		struct file *f = do_filp_open()
			struct nameidata nd
			path_openat()
				file = get_empty_filp()
				file->f_flags = op->open_flag
				path_init()
					link_path_walk()
						may_lookup()
						walk_component()
							handle_dots()
							lookup_fast()	
							lookup_slow()	//
								__lookup_hash()
									lookup_dcache()
									lookup_real()
										dir->i_op->lookup()	//ext4_lookup
											inode = ext4_iget_normal()
												ext4_iget()
													struct ext4_inode * raw_inode
													struct inode *inode
													inode = iget_locked()
														inode = find_inode_fast()
														inode = alloc_inode()
														inode->i_ino = ino
														inode->i_state = I_NEW
														hlist_add_head()
														inode_sb_list_add()
													__ext4_get_inode_loc()
														stuct buffer_head *bh
														struct ext4_group_desc *gdp
														ext4_inode_table()
														iloc->block_group = ...
														iloc->offset = ...
														get_bh(bh)
														bh->b_endio = end_buffer_read_sync
														submit_bh*()
															submit_bio()
														wait_on_buffer()
														iloc->bh = ...
													raw_inode = ext4_raw_inode()
													inode->i_blocks = ext4_inode_blocks()
													inode->isize = ext4_isize()
													inode->i_op=...
													inode->i_fop= ...
							inode = path->dentry->d_inode
							nd->inode = inode
				do_last()
					handle_dots()
					lookup_fast()
					complete_walk()
						dentry->d_op->d_weak_revalidate()
					lookup_open()
						struct dentry *dir = nd->path.dentry
						struct inode *dir_inode = dir->d_inode
						lookup_dcache()
						atomic_open()
						lookup_real()
						vfs_create()
					audit_inode()
					mnt_want_write()
					may_open()
					vfs_open()
						struct inode *inode = path->dentry->d_inode
						inode->i_op->dentry_open()
						do_dentry_open()
							inode = f->f_inode = f->f_path.dentry->d_inode
							f->f_mapping = inode->i_mapping
							f->f_op=fops_get(inode->i_fop)
							open = f->f_op->open
							open(inode,f)
					terminate_walk()
		fsnotity_open()

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.