linux设备驱动模型--open系统调用(创建文件)
2013-04-11 17:05
162 查看
前面
而在创建/dev目录的时候,就会将其i_op设置为shmem_dir_inode_operations,所以这时对应调用shmem_create这个方法。
linux设备驱动模型一字符设备open系统调用流程这里讲了linux open系统调用的流程,里面主要是打开一个已经存在的文件,但是当文件不存在时,如果指定了O_CREATE标志,并且可以创建文件的话,就会新创建一个文件,这里接着了解下文件的创建过程,这里的内核版本是3.0的,跟前面 这个不同,不过流程其实还是一样的
接着open系统调用到了do_last,进行一些初始化及判断后,调用vfs_create
error = security_path_mknod(&nd->path, dentry, mode, 0); if (error) goto exit_mutex_unlock; error = vfs_create(dir->d_inode, dentry, mode, nd); if (error) goto exit_mutex_unlock; mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = dentry; goto common;
vfs_create函数比较简单,
int vfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd){ int error = may_create(dir, dentry); printk("leaves Enter %s \n", __FUNCTION__); printk("leaves dentry %s \n", dentry->d_name.name); if (error) return error; if (!dir->i_op->create) return -EACCES; /* shouldn't it be ENOSYS? */ mode &= S_IALLUGO; mode |= S_IFREG; error = security_inode_create(dir, dentry, mode); if (error) return error; error = dir->i_op->create(dir, dentry, mode, nd); if (!error) fsnotify_create(dir, dentry); printk("leaves Exit %s \n", __FUNCTION__); return error;}
基本上就是直接调用父节点的inode_operations的create方法,这里以在/dev目录下面创建文件为例,我们知道,/dev目录的文件系统为tmpfs
在系统启动的时候,一般有mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
而在创建/dev目录的时候,就会将其i_op设置为shmem_dir_inode_operations,所以这时对应调用shmem_create这个方法。static int shmem_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd){ return shmem_mknod(dir, dentry, mode | S_IFREG, 0);}
这个函数只是一个简单的封装
/* * File creation. Allocate an inode, and we're done.. */static intshmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev){ struct inode *inode; int error = -ENOSPC; inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);//获取一个inode节点 if (inode) { error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, NULL, NULL); if (error) { if (error != -EOPNOTSUPP) { iput(inode); return error; } }#ifdef CONFIG_TMPFS_POSIX_ACL error = generic_acl_init(inode, dir); if (error) { iput(inode); return error; }#else error = 0;#endif dir->i_size += BOGO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; d_instantiate(dentry, inode);//为一个目录项填充索引节点信息 dget(dentry); /* Extra count - pin the dentry in core */ } return error;}
这里调用shmem_get_inode new一个i节点
static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev, unsigned long flags){ struct inode *inode; struct shmem_inode_info *info; struct shmem_sb_info *sbinfo = SHMEM_SB(sb); if (shmem_reserve_inode(sb)) return NULL; inode = new_inode(sb);//新建一个i节点 if (inode) { inode->i_ino = get_next_ino(); inode_init_owner(inode, dir, mode); inode->i_blocks = 0; inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_generation = get_seconds(); info = SHMEM_I(inode); memset(info, 0, (char *)inode - (char *)info); spin_lock_init(&info->lock); info->flags = flags & VM_NORESERVE; INIT_LIST_HEAD(&info->swaplist); INIT_LIST_HEAD(&info->xattr_list); cache_no_acl(inode); switch (mode & S_IFMT) {//设置i节点的i节点操作和文件操作 default: inode->i_op = &shmem_special_inode_operations; init_special_inode(inode, mode, dev); break; case S_IFREG: inode->i_mapping->a_ops = &shmem_aops; inode->i_op = &shmem_inode_operations; inode->i_fop = &shmem_file_operations; mpol_shared_policy_init(&info->policy, shmem_get_sbmpol(sbinfo)); break; case S_IFDIR: inc_nlink(inode); /* Some things misbehave if size == 0 on a directory */ inode->i_size = 2 * BOGO_DIRENT_SIZE; inode->i_op = &shmem_dir_inode_operations; inode->i_fop = &simple_dir_operations; break; case S_IFLNK: /* * Must not load anything in the rbtree, * mpol_free_shared_policy will not be called. */ mpol_shared_policy_init(&info->policy, NULL); break; } } else shmem_free_inode(sb); return inode;}
个人理解,创建一个文件和文件夹对linux来说没什么区别,都是新建一个i节点和一个目录项对象。
相关文章推荐
- linux设备驱动模型一字符设备open系统调用流程
- linux设备驱动模型一字符设备open系统调用流程
- linux设备驱动模型一字符设备open系统调用流程
- linux设备驱动模型一字符设备open系统调用流程
- linux设备驱动模型一字符设备open系统调用流程
- 从open系统调用的源码看文件的打开过程
- linux内核文件IO的系统调用实现分析(open)
- linux系统调用 创建文件 file_creat.c
- 文件打开时open系统调用
- 了解open/read/write/close等文件相关系统调用接口,纵向对比fd与FILE结构体
- 系统调用-文件访问 创建、打开、关闭、读、写
- 系统调用-文件访问 创建、打开、关闭、读、写
- 系统调用方式文件编程-open
- Linux文件编程之【系统调用】——open()
- open/read/write/close等文件系统调用接口以及fd与FILE的比较
- Linux C 文件操作,系统调用 -- open()、read() 和 标准I/O库 -- fopen()、fread()
- 创建以及打开文件文件“系统调用”
- 从open系统调用的源码看文件的打开过程
- 两种方式(系统调用、映射)实现文件的创建、移动、合并
- linux文件系统之open系统调用(基于3.4.9内核)