open()的最终目的是:准备好file以及依赖的数据结构。为此,open()主要做了以下几方面工作:
- PathWalk找到目标文件
- 构造并初始化inode
- 构造并初始化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()