今天来分析下 如何打开一个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的过程,那就一会再补充吧!