您的位置:首页 > 运维架构 > Linux

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

2013-04-11 17:05 162 查看
前面 

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节点和一个目录项对象。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: