1.2.3 Ext2索引节点对象的创建
现在还是从一个普通文件的角度来分析上面的过程,比如说,当我门在根目录下调用fd = open("file", O_CREAT)打开(创建)一个文件时,会启动do_sys_open系统调用,并根据路径“file”去触发do_filp_open函数返回一个file结构。do_filp_open主要调用的两个函数(详细的过程请参考博客“VFS系统调用的实现”
http://blog.csdn.net/yunsongice/archive/2010/06/22/5685130.aspx):
(1)open_namei():填充目标文件所在目录(也就是根目录)的dentry结构和所在文件系统的vfsmount结构,并将信息保存在nameidata结构中。在dentry结构中dentry->d_inode就指向目标文件的索引节点。
(2)dentry_open():建立目标文件的一个“上下文”,即file数据结构,并让它与当前进程的task_strrct结构挂上钩。同时,在这个函数中,调用了具体文件系统的打开函数,即f_op->open(),也就是前面看到的generic_file_open,,该函数返回指向新建立的file结构的指针。
注意,如果在访问模式标志中设置了O_CREAT,比如我们这里,则以LOOKUP_PARENT、LOOKUP_OPEN和LOOKUP_CREATE标志的设置开始查找操作。一旦path_lookup()函数成功返回,则检查请求的文件是否已存在。如果不存在,则open_namei会调用父索引节点的create方法分配一个新的磁盘索引节点。这里父索引节点是一个目录的,所以其i_op方法不是上面提到的ext2_file_inode_operations,而是ext2_dir_inode_operations,来自fs/ext2/namei.c:
const struct inode_operations ext2_dir_inode_operations = { .create = ext2_create, .lookup = ext2_lookup, .link = ext2_link, .unlink = ext2_unlink, .symlink = ext2_symlink, .mkdir = ext2_mkdir, .rmdir = ext2_rmdir, .mknod = ext2_mknod, .rename = ext2_rename, #ifdef CONFIG_EXT2_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, .listxattr = ext2_listxattr, .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, .check_acl = ext2_check_acl, }; |
ext2_create函数定义在同一个文件中,传给它的参数是根目录的inode,:
static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) { struct inode *inode;
dquot_initialize(dir);
inode = ext2_new_inode(dir, mode); if (IS_ERR(inode)) return PTR_ERR(inode);
inode->i_op = &ext2_file_inode_operations; if (ext2_use_xip( |