GFS2集群文件系统分析——gfs2_open()函数分析


今天来分析下 如何打开一个gfs2文件。


vfs在打开文件时,首先调用vfs的sys_open()函数,sys_open()函数经过一系列准备工作,最终会调用特定文件系统的打开函数,这里就是gfs2_open()函数。


先来看下代码。注释是我自己加上去的


static int gfs2_open(struct inode *inode, struct file *file)
{
	struct gfs2_inode *ip = GFS2_I(inode);//将inode节点转换为gfs2的inode节点
	struct gfs2_holder i_gh;
	struct gfs2_file *fp;
	int error;

	fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL);
	if (!fp)
		return -ENOMEM;

	mutex_init(&fp->f_fl_mutex);

	gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
	file->private_data = fp;//把gfs文件对象等特殊结构放到vfs文件对象的私有数据成员中。

	if (S_ISREG(ip->i_inode.i_mode)) {//判断是否为普通文件
		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
					   &i_gh);
		if (error)
			goto fail;

		if (!(file->f_flags & O_LARGEFILE) &&
		    i_size_read(inode) > MAX_NON_LFS) {
			error = -EOVERFLOW;
			goto fail_gunlock;
		}

		gfs2_glock_dq_uninit(&i_gh);
	}

	return 0;

fail_gunlock:
	gfs2_glock_dq_uninit(&i_gh);
fail:
	file->private_data = NULL;
	kfree(fp);
	return error;
}

当上面的if判断为普通文件时,调用函数

gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,&i_gh);

下面来看下gfs2_glock_nq_init()函数,这个函数初始化一个glock锁,参数是共享锁


/**
 * gfs2_glock_nq_init - initialize a holder and enqueue it on a glock
 * @gl: the glock
 * @state: the state we're requesting
 * @flags: the modifier flags
 * @gh: the holder structure
 *
 * Returns: 0, GLR_*, or errno
 */

static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
				     unsigned int state, int flags,
				     struct gfs2_holder *gh)
{
	int error;

	gfs2_holder_init(gl, state, flags, gh);

	error = gfs2_glock_nq(gh);
	if (error)
		gfs2_holder_uninit(gh);

	return error;
}

这个函数又调用了 gfs2_holder_init()

/**
 * gfs2_holder_init - initialize a struct gfs2_holder in the default way
 * @gl: the glock
 * @state: the state we're requesting
 * @flags: the modifier flags
 * @gh: the holder structure
 *
 */

void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
		      struct gfs2_holder *gh)
{
	INIT_LIST_HEAD(&gh->gh_list);
	gh->gh_gl = gl;
	gh->gh_ip = (unsigned long)__builtin_return_address(0);
	gh->gh_owner_pid = get_pid(task_pid(current));
	gh->gh_state = state;
	gh->gh_flags = flags;
	gh->gh_error = 0;
	gh->gh_iflags = 0;
	gfs2_glock_hold(gl);//增加一次对glock的引用
}

到这里为止,还没看到具体在哪里初始化了glock,一直是指针在传来传去(个人觉得glock其实在分配或者查找inode的时候就初始化完成了,这部分不确定,一会分析)。

继续看下去,初始化holder后,有一行代码gfs2_glock_nq(gh);//将一个gfs2_holder结构插入到一个glock的队列中

/**
 * gfs2_glock_nq - enqueue a struct gfs2_holder onto a glock (acquire a glock)
 * @gh: the holder structure
 *
 * if (gh->gh_flags & GL_ASYNC), this never returns an error
 *
 * Returns: 0, GLR_TRYFAILED, or errno on failure
 */

int gfs2_glock_nq(struct gfs2_holder *gh)
{
	struct gfs2_glock *gl = gh->gh_gl;
	struct gfs2_sbd *sdp = gl->gl_sbd;
	int error = 0;

	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		return -EIO;

	spin_lock(&gl->gl_spin);
	add_to_queue(gh);
	if ((LM_FLAG_NOEXP & gh->gh_flags) &&
	    test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
		set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
	run_queue(gl, 1);
	spin_unlock(&gl->gl_spin);

	if (!(gh->gh_flags & GL_ASYNC))
		error = gfs2_glock_wait(gh);

	return error;
}

到这里分析不下去了,必须的看glock结构,和gfs创建inode的过程,那就一会再补充吧!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值