微视linux 文件系统之打开文件create模式

struct file *do_last(struct nameidata *nd, struct path *path,
			    int open_flag, int acc_mode,
			    int mode, const char *pathname)
{
	struct dentry *dir = nd->path.dentry;
	/* just plain open? */
	if (!(open_flag & O_CREAT)){
		error = do_lookup(nd, &nd->last, path);
		if (error)
			goto exit;
		/*#define	ENOENT		 2	/* No such file or directory */*/
		error = -ENOENT; //非创建模式如果找不到就上报错误
		if (!path->dentry->d_inode)
			goto exit_dput;
		if (path->dentry->d_inode->i_op->follow_link)
			return NULL;
		/*#define	ENOTDIR		20	/* Not a directory */*/
		error = -ENOTDIR;
	}
	
	/* OK, it's O_CREAT */
	path->dentry = lookup_hash(nd);
	=>struct dentry *lookup_hash(struct nameidata *nd)
	{
		return __lookup_hash(&nd->last, nd->path.dentry, nd);
		=>struct dentry *__lookup_hash(struct qstr *name,
		struct dentry *base, struct nameidata *nd)
		{
			inode = base->d_inode;
			dentry = __d_lookup(base, name);
			if (!dentry)
				dentry = d_lookup(base, name);
				
			if (!dentry) {
				struct dentry *new;
				new = d_alloc(base, name);//申请dentry空间
				
				dentry = inode->i_op->lookup(inode, new, nd);
				=>struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
				{
					/*根据文件名找节点号,找不到则返回空*/
					ino = ext2_inode_by_name(dir, &dentry->d_name);
					if (ino) {
						inode = ext2_iget(dir->i_sb, ino);
					}
					return d_splice_alias(inode, dentry);
				}
				/*不存在则创建新dentry*/
				if (!dentry)
					dentry = new;
				else
					dput(new);
			}
			return dentry;
		}
	}
	path->mnt = nd->path.mnt;
	
	/* Negative dentry, just create the file */
	if (!path->dentry->d_inode) {
		error = __open_namei_create(nd, path, open_flag, mode);
		=>int __open_namei_create(struct nameidata *nd, struct path *path,
				int open_flag, int mode)
		{
			struct dentry *dir = nd->path.dentry;
			error = vfs_create(dir->d_inode, path->dentry, mode, nd);
			/*创建dentry对应的inode节点*/
			=>int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
				struct nameidata *nd)
			{
				error = dir->i_op->create(dir, dentry, mode, nd);
				=>int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
				{
					inode = ext2_new_inode(dir, mode);
					inode->i_op = &ext2_file_inode_operations;
					if (ext2_use_xip(inode->i_sb)) {
						inode->i_mapping->a_ops = &ext2_aops_xip;
						inode->i_fop = &ext2_xip_file_operations;
					} else if (test_opt(inode->i_sb, NOBH)) {
						inode->i_mapping->a_ops = &ext2_nobh_aops;
						inode->i_fop = &ext2_file_operations;
					} else {
						inode->i_mapping->a_ops = &ext2_aops;
						inode->i_fop = &ext2_file_operations;
					}
					mark_inode_dirty(inode);
					return ext2_add_nondir(dentry, inode);
				}
				return error;
			}
			dput(nd->path.dentry);
			nd->path.dentry = path->dentry;
			return may_open(&nd->path, 0, open_flag & ~O_TRUNC);
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值