当前位置: 首页 > news >正文

rbd块设备数据IO流程(client端)

一、rbd内核驱动写入流程

1)初始化

首先是rbd驱动的初始化工作:包括验证libceph的兼容性,分配内存,在sysfs中创建块设备控制文件、创建工作队列rbd_wq并调用INIT_WORK初始化它

module_init(rbd_init);
static int __init rbd_init(void)
{
if (!libceph_compatible(NULL)) { //兼容性
rbd_warn(NULL, "libceph incompatibility (quitting)");
return -EINVAL;
}
rbd_wq = alloc_workqueue(RBD_DRV_NAME, WQ_MEM_RECLAIM, 0);  //创建工作队列
if (!rbd_wq)
{rc = -ENOMEM;goto err_out_slab;
}
rc = rbd_slab_init(); //初始化内存分配器
if (rc)
return rc;
.......
rc = rbd_sysfs_init(); //创建/sys/bus/rbd/
if (rc)
goto err_out_blkdev;
...}static int rbd_init_request(void *data, struct request *rq,unsigned int hctx_idx, unsigned int request_idx,unsigned int numa_node)
{struct work_struct *work = blk_mq_rq_to_pdu(rq);INIT_WORK(work, rbd_queue_workfn);  //初始化一个work,work通过rbd_queue_workfn进行处理return 0;
}

2)块设备创建、工作队列中启动work

添加块设备,首先创建一个rbd client用来通信,然后选择一个pool存储池去创建rbd设备,创建完成后调用rbd_dev_device_setup初始化rbd设备,在初始化块设备的时候会启动工作队列rbd_wq,并将通用块设备层的请求转化为一个work添加到rbd_wq工作队列中,然后由cpu调度执行工作队列rbd_wq中的work,work对应的处理函数为rbd_queue_workfn,该work用于处理通用块设备层的IO请求。

启动work的调用关系: rbd_dev_device_setup → rbd_init_disk  → rbd_mq_ops → rbd_init_request → rbd_queue_workfn处理函数

static BUS_ATTR(add, S_IWUSR, NULL, rbd_add);
static BUS_ATTR(remove, S_IWUSR, NULL, rbd_remove);
static BUS_ATTR(add_single_major, S_IWUSR, NULL, rbd_add_single_major);
static BUS_ATTR(remove_single_major, S_IWUSR, NULL, rbd_remove_single_major);static int rbd_queue_rq(struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd)
{struct request *rq = bd->rq;struct work_struct *work = blk_mq_rq_to_pdu(rq);  //通用块设备层请求转为workqueue_work(rbd_wq, work);  //将work加入到工作队列,工作队列中的work由cpu调度处理return BLK_MQ_RQ_QUEUE_OK;
}static ssize_t rbd_add(struct bus_type *bus,const char *buf,size_t count)
{if (single_major)return -EINVAL;return do_rbd_add(bus, buf, count);
}static ssize_t do_rbd_add(struct bus_type *bus,const char *buf,size_t count)
{.....rbdc = rbd_get_client(ceph_opts);  //获取或创建rbd_clientif (IS_ERR(rbdc)) {rc = PTR_ERR(rbdc);goto err_out_args;}/* pick the pool */rc = rbd_add_get_pool_id(rbdc, spec->pool_name);  //选择存储池if (rc < 0) {if (rc == -ENOENT)pr_info("pool %s does not exist\n", spec->pool_name);goto err_out_client;}spec->pool_id = (u64)rc;rbd_dev = rbd_dev_create(rbdc, spec, rbd_opts);  //创建rbd设备down_write(&rbd_dev->header_rwsem);
......rc = rbd_dev_image_probe(rbd_dev, 0);  //探针更多的是检查rbd image是否被mapif (rc < 0) {up_write(&rbd_dev->header_rwsem);goto err_out_rbd_dev;}
......rc = rbd_dev_device_setup(rbd_dev);  //包括obj->pg映射等static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
{int ret;
....../* Set up the blkdev mapping. */ret = rbd_init_disk(rbd_dev); ......
}static int rbd_init_disk(struct rbd_device *rbd_dev)
{struct gendisk *disk;struct request_queue *q;u64 segment_size;int err;
.....memset(&rbd_dev->tag_set, 0, sizeof(rbd_dev->tag_set));rbd_dev->tag_set.ops = &rbd_mq_ops;                        //rbd_dev初始化rbd_dev->tag_set.queue_depth = rbd_dev->opts->queue_depth;rbd_dev->tag_set.numa_node = NUMA_NO_NODE;
.....
}static struct blk_mq_ops rbd_mq_ops = {.queue_rq   = rbd_queue_rq,.init_request   = rbd_init_request,   //调用rbd_init_request
};static int rbd_init_request(void *data, struct request *rq,unsigned int hctx_idx, unsigned int request_idx,unsigned int numa_node)
{struct work_struct *work = blk_mq_rq_to_pdu(rq);INIT_WORK(work, rbd_queue_workfn);  //通过work_struct启动线程return 0;
}

3)work处理函数rbd_queue_workfn内流程分析

从上层取出通用块设备层请求后,转换为image对象,再从image对象批量转为object对象,再计算出object到pg,pg到osd的映射关系。

3.1 获取通用块设备层信息

在rbd_queue_workfn中,通过blk_mq_rq_from_pdu获取到通用块设备层IO请求rq、通过blk_rq_bytes(rq)获取到请求中需要写入的数据长度length(length表示的是客户端需要写到磁盘总的数据长度),通过blk_rq_pos(rq)获取块设备写入偏移量offset。

static void rbd_queue_workfn(struct work_struct *work)
{struct request *rq = blk_mq_rq_from_pdu(work);  //通用块设备层请求struct rbd_device *rbd_dev = rq->q->queuedata;struct rbd_img_request *img_request;struct ceph_snap_context *snapc = NULL;u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;  //块设备的偏移量u64 length = blk_rq_bytes(rq);  //enum obj_operation_type op_type;
.....
}

3.2 通用块设备层信息转换image请求,image请求批量转换为object

在rbd_queue_workfn中从通用块设备层请求中获取到块设备偏移offset和长度length后,再使用这些指标来创建img_request并将img_request→offset进行填充中,然后调用rbd_img_request_fill函数,在该函数中,基于rados object的大小(4M)与rados对象在rbd中的segment排列,对请求进行拆分,最终将rbd_img_request拆分成多个rbd_obj_request对象,通过这样的过程实现从linux内核的通用块请求到ceph rados object的转换。

static void rbd_queue_workfn(struct work_struct *work)
{struct request *rq = blk_mq_rq_from_pdu(work);struct rbd_device *rbd_dev = rq->q->queuedata;struct rbd_img_request *img_request;u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;  //块设备偏移u64 length = blk_rq_bytes(rq);  //长度
......img_request = rbd_img_request_create(rbd_dev, offset, length, op_type,  //创建img_requestsnapc); img_request->offset = offset;  //填充img_request→offsetresult = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,  //将rbd_img_request划分为一个个rbd_obj_requestrq->bio);
.....
}static int rbd_img_request_fill(struct rbd_img_request *img_request,enum obj_request_type type,void *data_desc)
{struct rbd_obj_request *obj_request = NULL;u64 img_offset;img_offset = img_request->offset;  //块设备当前写入的偏移位置resid = img_request->length;  //待写入的长度while (resid) {
......object_name = rbd_segment_name(rbd_dev, img_offset);  //对象名length = rbd_segment_length(rbd_dev, img_offset, resid);  //长度obj_request = rbd_obj_request_create(object_name,  //创建obj_request对象offset, length, type);
......img_offset += length;  //偏移增加lengthresid -= length;
......
}

3.3 rbd块设备offset到rados object的映射

rbd块设备到rados对象的映射是根据rados对象的大小以及当前块设备的偏移量来决定的,并且rados对象的命名方式采用前缀rbd_data.$image_id.16位16进制的序号构成。

3.3.1 rados对象大小与命名方式

每个rbd块设备都定义了一个2为底的指数来表示每个rbd对象的大小,这个指数称为rbd的obj order。obj order默认值为22,因此每个rbd对象大小2^22Bytes,即每个rados对象大小为4MB。

相关文章:

rbd块设备数据IO流程(client端)

一、rbd内核驱动写入流程 1&#xff09;初始化 首先是rbd驱动的初始化工作&#xff1a;包括验证libceph的兼容性&#xff0c;分配内存&#xff0c;在sysfs中创建块设备控制文件、创建工作队列rbd_wq并调用INIT_WORK初始化它 module_init(rbd_init); static int __init rbd_i…...

数据仓库、数据中台、大数据平台之间的关系

数据行业经常会出现数据仓库、数据中台、大数据平台等概念&#xff0c;容易产生疑问&#xff0c;它们中间是相等&#xff0c;还是包含的关系&#xff1f; 数据中台和数据仓库概念的关系 数据中台概念是包含数据仓库的&#xff0c;数据仓库是数据中台中的一部分&#xff0c;包含…...

python写页面自动截图

from selenium import webdriver def take_screenshot(url, file_path):driver webdriver.Chrome()driver.get(url)driver.save_screenshot(file_path)driver.quit() if __name__ __main__:take_screenshot(http://baidu.com, D:\桌面\wang.png)要安装selenium还要安装google…...

【Qt 学习笔记】Qt常用控件 | 布局管理器 | 空白项Spacer

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 布局管理器 | 添加空白Spacer 文章编号&#xff1a;Qt 学…...

es问题汇总--待完善

1. 查询某个索引库中数据总量 方式一&#xff1a; CountRequest 鄙人喜欢这种方式 public long getTotalNum(String indexName) throws IOException {CountRequest countRequest new CountRequest(indexName);// 如果需要&#xff0c;你可以在这里添加查询条件// countReques…...

新一代高性价比LTE Cat.1通信模组ML307R

...

python 线性回归模型

教材链接-3.2. 线性回归的从零开始实现 c实现 该博客仅用于记录一下自己的代码&#xff0c;可与c实现作为对照 from d2l import torch as d2l import torch import random # nn是神经网络的缩写 from torch import nn from torch.utils import data# 加载训练数据 # 加载训…...

pcl::transformPointCloud()用法及注意事项

函数用法 #include <pcl/common/transforms.h> pcl::transformPointCloud(const pcl::PointCloud<PointT> &cloud_in, pcl::PointCloud<PointT> &cloud_out, const Eigen::Matrix4f &transform) 其中cloud_in, cloud_out的类型为pcl::PointClo…...

图像超分辨率重建相关概念、评价指标、数据集、模型

1、图像超分辨率概念 1.1 基本定义 超分辨率&#xff08;Super-Resolution&#xff09;&#xff0c;简称超分&#xff08;SR&#xff09;。是指利用光学及其相关光学知识&#xff0c;根据已知图像信息恢复图像细节和其他数据信息的过程&#xff0c;简单来说就是增大图像的分辨…...

中移物联OneMO Cat.1模组推动联网POS规模应用

在第三方支付蓬勃发展和消费模式不断革新的时代背景下&#xff0c;新型联网POS终端以其智能化、便捷化的特点丰富人们生活便利度。在这一变革浪潮中&#xff0c;中移物联OneMO Cat.1模组ML307R凭借其卓越的性能和成本效益&#xff0c;成为推动联网POS规模应用的重要力量。 性能…...

二.常见算法--贪心算法

&#xff08;1&#xff09;单源点最短路径问题 问题描述&#xff1a; 给定一个图&#xff0c;任取其中一个节点为固定的起点&#xff0c;求从起点到任意节点的最短路径距离。 例如&#xff1a; 思路与关键点&#xff1a; 以下代码中涉及到宏INT_MAX,存在于<limits.h>中…...

LabVIEW高温往复摩擦测试系统中PID控制

在LabVIEW开发高温往复摩擦测试系统中实现PID控制&#xff0c;需要注意以下几个方面&#xff1a; 1. 系统建模与参数确定 物理模型建立: 首先&#xff0c;需要了解被控对象的物理特性&#xff0c;包括热惯性、摩擦系数等。这些特性决定了系统的响应速度和稳定性。实验数据获取…...

配置yum源

以下是在 Linux 系统中配置新的 yum 源的一般步骤和命令示例&#xff08;以 CentOS 系统为例&#xff09;&#xff1a; 备份原有 yum 源配置文件&#xff1a;mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 创建新的 yum 源配置文件&#xff08…...

深入理解数仓开发(二)数据技术篇之数据同步

1、数据同步 数据同步我们之前在数仓当中使用了多种工具&#xff0c;比如使用 Flume 将日志文件从服务器采集到 Kafka&#xff0c;再通过 Flume 将 Kafka 中的数据采集到 HDFS。使用 MaxWell 实时监听 MySQL 的 binlog 日志&#xff0c;并将采集到的变更日志&#xff08;json 格…...

C++语言学习(六)—— 类与对象(二)

目录 一、对象数组 二、对象指针 三、this 指针 四、类类型作为参数类型的三种形式 4.1 对象本身作为参数 4.2 对象指针作为参数 4.3 对象引用作为参数 五、静态成员 5.1 静态数据成员 5.2 静态成员函数 六、友元机制 6.1 友元函数 6.2 友元类 七、类的组合 八、…...

3d选择模型后不能旋转什么原因?怎么解决?---模大狮模型网

在3D建模和渲染的过程中&#xff0c;旋转模型是常见的操作。然而&#xff0c;有时在选择了模型后&#xff0c;却发现无法进行旋转&#xff0c;这可能会让许多用户感到困扰。本文将探讨3D选择模型后不能旋转的可能原因&#xff0c;并提供相应的解决方法。 一、3D选择模型后不能旋…...

从入门到精通:详解Linux环境基础开发工具的使用

前言 在这篇文章中&#xff0c;我将深入学习和理解Linux环境基础开发工具的使用。无论你是初学者还是有一定经验的开发者&#xff0c;相信这篇文章都会对你有所帮助。我们将详细讲解软件包管理器、编辑器、编译器、调试器、自动化构建工具以及版本控制工具的使用。 Linux软件…...

linux(centos 7)安装 node

linux&#xff08;centos 7&#xff09;安装 node 下载对应版本&安装解压配置环境变量使配置文件生效验证是否安装成功附加 目前node最新版本是 node-v22.0.0 官网下载地址&#xff1a;https://registry.npmmirror.com/binary.html?pathnode/latest-v22.x/node-v22.0.0-li…...

C++之第九课

课程列表 今天&#xff0c;我们要学习一种结构&#xff1a;循环结构。 循环的方法有3种。 今天先将第1种for学了&#xff1a; int a;//循环变量 int b; for(a1;a<10;a){//像if那样“打包”cout<<a<<" ";b; } 当然&#xff0c;也可以这样写&#…...

618精选编程书单推荐:优质知识提升你的代码力

前言 在这个快速发展的技术时代&#xff0c;不断学习和提升自己的编程技能是每位程序员的必修课。今天&#xff0c;我为大家精心挑选了一系列编程技术书籍&#xff0c;它们将是你技术成长道路上的宝贵财富。 文章目录 前言编程之路&#xff1a;为何阅读书籍是不可或缺的书籍的…...

Asterisk 实战速成:从零搭建企业级呼叫中心

1. 为什么选择Asterisk搭建企业级呼叫中心 第一次接触Asterisk是在2015年&#xff0c;当时公司需要快速搭建一个200坐席的客服系统。市面上商业解决方案动辄几十万的报价让我们望而却步&#xff0c;而Asterisk这个开源PBX系统完美解决了我们的需求。十年过去了&#xff0c;Aste…...

Bidili Generator效果展示:手绘草图→LoRA增强→高清成图三步流程

Bidili Generator效果展示&#xff1a;手绘草图→LoRA增强→高清成图三步流程 1. 引言&#xff1a;当手绘草图遇见AI魔法 你有没有过这样的经历&#xff1f;脑子里突然冒出一个绝妙的画面&#xff0c;抓起笔在纸上画了个草图&#xff0c;但想把它变成一张精美的数字图片&…...

SetDPI:Windows多显示器DPI缩放终极解决方案

SetDPI&#xff1a;Windows多显示器DPI缩放终极解决方案 【免费下载链接】SetDPI 项目地址: https://gitcode.com/gh_mirrors/se/SetDPI 关键词&#xff1a;Windows DPI缩放&#xff0c;多显示器显示设置&#xff0c;DPI精准控制&#xff0c;显示器缩放工具&#xff0c…...

3个核心功能解决Windows与Office批量激活难题:开源工具KMS_VL_ALL_AIO深度解析

3个核心功能解决Windows与Office批量激活难题&#xff1a;开源工具KMS_VL_ALL_AIO深度解析 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 在企业IT管理和个人系统维护中&#xff0c;Windows与O…...

嵌入式开发新助手:Phi-4-mini-reasoning在STM32项目中的代码审查与优化

嵌入式开发新助手&#xff1a;Phi-4-mini-reasoning在STM32项目中的代码审查与优化 1. 嵌入式开发的痛点与机遇 在STM32这类资源受限的嵌入式开发中&#xff0c;工程师们常常面临一个两难困境&#xff1a;既要保证代码执行效率满足实时性要求&#xff0c;又要严格控制ROM和RA…...

OpenClaw学术场景应用:Qwen3-32B镜像辅助论文数据处理

OpenClaw学术场景应用&#xff1a;Qwen3-32B镜像辅助论文数据处理 1. 为什么需要自动化论文数据处理&#xff1f; 作为一名经常需要处理实验数据的研究人员&#xff0c;我过去常常花费大量时间在Excel和Python之间来回切换。数据清洗、格式转换、异常值检测这些重复性工作不仅…...

【ProtoBuf 实战训练】网络版通讯录

文章目录1. 通讯录 4.0 实现&#xff08;网络版&#xff09;2. 环境搭建2.1 搭建服务端2.2 搭建客户端2.3 运行结果3. 新增联系人功能3.1 协议约定3.2 协议接口定义 (.proto)3.2.1 AddContactRequest&#xff08;请求消息&#xff09;3.2.2 AddContactResponse&#xff08;响应…...

次元画室结合Transformer架构:提升图像生成连贯性与细节

次元画室结合Transformer架构&#xff1a;提升图像生成连贯性与细节 你有没有遇到过这样的情况&#xff1f;想用AI画师创作一个漫画故事&#xff0c;第一格主角穿着红色外套&#xff0c;到了第三格&#xff0c;外套颜色莫名其妙变成了蓝色&#xff0c;或者背景里的建筑细节对不…...

Nunchaku FLUX.1-dev部署教程:Linux系统下CUDA驱动与PyTorch匹配指南

Nunchaku FLUX.1-dev部署教程&#xff1a;Linux系统下CUDA驱动与PyTorch匹配指南 想用最新的Nunchaku FLUX.1-dev模型生成惊艳的AI图片&#xff0c;结果卡在了环境配置上&#xff1f;别担心&#xff0c;这篇教程就是为你准备的。很多朋友在部署时遇到的最大障碍&#xff0c;往…...

RVC与ElevenLabs对比:开源可控性vs商业易用性深度分析

RVC与ElevenLabs对比&#xff1a;开源可控性vs商业易用性深度分析 想用AI克隆自己的声音&#xff0c;或者让喜欢的角色开口唱歌&#xff1f;现在市面上有两大主流选择&#xff1a;开源的RVC和商业化的ElevenLabs。一个免费但需要折腾&#xff0c;一个付费但开箱即用。到底哪个…...