linux设备驱动模型–open系统调用(创建文件)


前面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_ACLerror = generic_acl_init(inode, dir);if (error) {iput(inode);return error;}#elseerror = 0;#endifdir->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;}} elseshmem_free_inode(sb);return inode;}

个人理解,创建一个文件和文件夹对linux来说没什么区别,都是新建一个i节点和一个目录项对象。如果有可能,我带你去远行。

linux设备驱动模型–open系统调用(创建文件)

相关文章:

你感兴趣的文章:

标签云: