前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初探lustre文件创建的过程

初探lustre文件创建的过程

作者头像
用户4700054
发布2022-08-17 13:14:33
9250
发布2022-08-17 13:14:33
举报
文章被收录于专栏:存储内核技术交流

lustre中inode的operations

  • 不论是本地文件系统还是分布式文件系统,每个inode会有一些operations.针对上层的posix语义的实现。我们这里着重讨论文件的create操作,create涉及的file_operationll_file_operations_flockll_file_operations.
代码语言:javascript
复制
// 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文件系统决定。
代码语言:javascript
复制
// 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的创建。如下的核心链路函数分析忽略了网络的部分函数保留和核心的执行逻辑。
代码语言:javascript
复制
// 文件创建的开始函数
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()
		}
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • lustre中inode的operations
  • 文件创建核心函数流程
相关产品与服务
云 HDFS
云 HDFS(Cloud HDFS,CHDFS)为您提供标准 HDFS 访问协议,您无需更改现有代码,即可使用高可用、高可靠、多维度安全、分层命名空间的分布式文件系统。 只需几分钟,您就可以在云端创建和挂载 CHDFS,来实现您大数据存储需求。随着业务需求的变化,您可以实时扩展或缩减存储资源,CHDFS 存储空间无上限,满足您海量大数据存储与分析业务需求。此外,通过 CHDFS,您可以实现计算与存储分离,极大发挥计算资源灵活性,同时实现存储数据永久保存,降低您大数据分析资源成本。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档