暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

初探lustre文件创建的过程

315


作者时间QQ技术交流群
perrynzhou@gmail.com2022/04/20672152841




lustre中inode的operations

  • 不论是本地文件系统还是分布式文件系统,每个inode会有一些operations
    .针对上层的posix语义的实现。我们这里着重讨论文件的create
    操作,create
    涉及的file_operation
    ll_file_operations_flock
    ll_file_operations
    .

// lustre客户端的file_oepration的函数
const struct file_operations *ll_select_file_operations(struct ll_sb_info *sbi)
{
const struct file_operations *fops = &ll_file_operations_noflock;

if (sbi->ll_flags & LL_SBI_FLOCK)
fops = &ll_file_operations_flock;
else if (sbi->ll_flags & LL_SBI_LOCALFLOCK)
fops = &ll_file_operations;

return fops;
}

int ll_read_inode2(struct inode *inode, void *opaque)
{
struct lustre_md *md = opaque;
struct ll_inode_info *lli = ll_i2info(inode);
inode->i_mapping->backing_dev_info = &s2lsi(inode->i_sb)->lsi_bdi;
if (S_ISREG(inode->i_mode)) {
struct ll_sb_info *sbi = ll_i2sbi(inode);
inode->i_op = &ll_file_inode_operations;
inode->i_fop = sbi->ll_fop;
inode->i_mapping->a_ops = (struct address_space_operations *)&ll_aops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &ll_dir_inode_operations;
inode->i_fop = &ll_dir_operations;
} else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &ll_fast_symlink_inode_operations;
} else {
inode->i_op = &ll_special_inode_operations;
}

return 0;
}

  • linux内核中针对creat
    语义定义SYSCALL_DEFINE2(creat....)
    ,实际是调用的是内核的ksys_open
    函数来执行。creat
    函数最终还是🈶具体open
    函数执行,open
    函数是具体单机或者分布式文件系统定义的ll_file_operations
    中的open函数。在vfs
    层,用户传入文件路径,在vfs
    解析文件父目录的路径,完成后在最最后文件的创建,具体的文件创建是由lustre
    文件系统决定。





// creat语义在内核中的定义
SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
{
return ksys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
}


static inline long ksys_open(const char __user *filename, int flags,
umode_t mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
// 进入内核的文件打开函数
return do_sys_open(AT_FDCWD, filename, flags, mode) {
// 开始创建文件
struct file *f = do_filp_open(dfd, tmp, &op) {
// 父目录路径解析
filp = path_openat(&nd, op, flags | LOOKUP_RCU) {
// 文件描述符申请
file = alloc_empty_file(op->open_flag, current_cred());
// 解析路径
link_path_walk(s, nd) {
for(;;) {
err = walk_component(nd, WALK_FOLLOW){
err = lookup_fast(nd, &path, &inode, &seq);
if (unlikely(err <= 0)) {
path.dentry = lookup_slow(&nd->last, nd->path.dentry, nd->flags){
// 这里调用的是ll_file_inode_operations中的lookup函数
old = inode->i_op->lookup(inode, dentry, flags);
}
}
}
// 最后完成文件的创建
do_last(nd, file, op){
// 进入vfs的open函数
error = vfs_open(&nd->path, file) {
// 开始创建文件
do_dentry_open(file, d_backing_inode(path->dentry), NULL){
// 获取inode的文件操作的函数表
f->f_op = fops_get(inode->i_fop);
open = f->f_op->open;
// 执行lustre文件系统的open函数
error = open(inode, f);
}
}
}
}
}
}
}



文件创建核心函数流程

  • 在lustre中客户端测,我使用touch touch mnt/lustre/file_aaaa
    来创建文件,在查找期间会先解析file_aaaa
    父目录,然后在进行file_aaaa
    的创建。如下的核心链路函数分析忽略了网络的部分函数保留和核心的执行逻辑。


// 文件创建的开始函数
ll_atomic_open() {
// 查找被创建的文件
ll_lookup_it(){
// 文件元数据的申请
lmv_fid_alloc(){
obd_fid_alloc()
}
// 元数据的intent意向锁方式打开
lmv_intent_open()
// 完成查找
ll_lookup_it_finish()
}
// 开始创建新文件的起点函数
ll_create_it(){
// 请求mds来创建新文件的inode
ll_create_node(){
// 准备inode的函数
ll_prep_inode(){
// 获取inode的函数
ll_iget() {
// inode设置lustre的文件或者目录的操作函数
ll_read_inode2(){
// lu_obejct申请
lov_object_alloc()
// lu_obejct初始化
lov_object_init(){
// 新文件的布局
lov_init_composite(){
// 新文件raid0的初始化
lov_init_raid0() {
// 查找cl_object对象
lov_sub_find(){
// 创建sub lov的lu_object对象
lovsub_object_alloc()
lovsub_object_init()
}
// 根据文件布局创建文件分片数据对象
lov_init_sub()
}

}
}

}

}
// 布局配置的获取
ll_layout_conf(){
lov_conf_set()
lov_object_layout_get()
}

}
}
}
// 执行文件打开
ll_file_open()
ll_local_open()
lmv_set_open_replay_data()

}
// 设置新文件的元数据扩展属性
lmv_setattr()
mdc_setattr()
// 设置新文件元数据属性
mdc_get_lustre_md()
/******下面是lustre客户端的执行device,从vvp->lov->lov_sub->osc*/
// vvp层IO对象初始化
vvp_io_init()
// lov层IO对象初始化
lov_io_init()
// lov层IO对象初始化
lov_io_iter_init()

// lov子对象的IO初始化
lov_io_subio_init()


//
lov_io_init_composite()
// osc层IO对象初始化
osc_io_iter_init()

// 启动lov层IO对象执行
lov_io_start() {
lov_io_call(){
osc_io_setattr_start(){
osc_setattr_async()
}
}
}



文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论