找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

320

积分

0

好友

40

主题
发表于 2025-12-28 23:28:38 | 查看: 27| 回复: 0

在 Ceph 对象存储网关(RGW)处理分段上传(Multipart Upload)请求时,获取已创建的分段上传任务的元信息是一个关键步骤。该功能主要由 get_multipart_info() 函数完成,其核心职责是读取并解析存储在 .rgw.non-ec 池中的分段上传元数据对象,这些数据包含了访问控制列表(ACL)、数据布局规则(placement rule)以及其他必要的元数据。

get_multipart_info() 函数入口

首先,我们来看 get_multipart_info 函数的初始入口。该函数接收一个元数据对象的名称(meta_oid),并将其封装为 rgw_obj 对象,然后调用其重载版本。

static int get_multipart_info(RGWRados *store, struct req_state *s,
                  const string& meta_oid,
                              RGWAccessControlPolicy *policy,
                  map<string, bufferlist> *attrs,
                              multipart_upload_info *upload_info)
{
  map<string, bufferlist>::iterator iter;
  bufferlist header;

  rgw_obj meta_obj;
  meta_obj.init_ns(s->bucket, meta_oid, mp_ns); // mp_ns是RGW_OBJ_NS_MULTIPART,也就是multipart
  meta_obj.set_in_extra_data(true);

  return get_multipart_info(store, s, meta_obj, policy, attrs, upload_info);
}

Ceph RGW分段上传元数据读取机制源码解析 - 图片 - 1

在实际调用前,通常会有如下步骤,将对象名和上传ID初始化为一个 RGWMPObj,并从中获取元数据对象名。

RGWMPObj mp(s->object.name, multipart_upload_id);
op_ret = get_multipart_info(store, s, mp.get_meta(), nullptr, nullptr, &upload_info);

mp.get_meta() 的返回格式通常为 oid.upload_id.meta,这即是传入上述函数的 meta_oid 参数。

核心逻辑:读取并解析对象数据

封装好 rgw_obj 后,程序调用另一个重载的 get_multipart_info() 函数执行核心操作。这个函数主要分为两步:从存储后端读取对象头数据,然后解析其中的关键信息。

static int get_multipart_info(RGWRados *store, struct req_state *s,
                  const rgw_obj& obj,
                              RGWAccessControlPolicy *policy,
                  map<string, bufferlist> *attrs,
                              multipart_upload_info *upload_info)
{
  // ... 变量声明等准备工作

  int op_ret = get_obj_head(store, s, obj, attrs, pheadbl);
  // ... 错误处理

  // 1. 解析分段上传信息(multipart_upload_info)
  if (upload_info && headbl.length() > 0) {
    auto hiter = headbl.cbegin();
    try {
      decode(*upload_info, hiter);
    }
    // ... 异常捕获
  }

  // 2. 解析访问控制策略(ACL)
  if (policy && attrs) {
    for (auto& iter : *attrs) {
      string name = iter.first;
      if (name.compare(RGW_ATTR_ACL) == 0) {
        bufferlist& bl = iter.second;
        auto bli = bl.cbegin();
        try {
          decode(*policy, bli);
        }
        // ... 异常捕获
      }
    }
  }

  return 0;
}

Ceph RGW分段上传元数据读取机制源码解析 - 图片 - 2

get_obj_head 的内部工作

get_obj_head 函数是数据读取的关键,它主要调用了 RGWRados::Object::Read::prepare()RGWRados::Object::Read::read() 两个方法。

  1. prepare() 阶段

    • 确定需要读取的元数据对象在 .rgw.non-ec 池中的完整路径。该路径格式通常为 “<bucket_id>_” + “_multipart_” + <key-name> + “.” + <upload_id> + “.meta”,此对象正是在 init-multipart 阶段创建的临时元数据对象。
    • 校验来自 HTTP 请求头(如 If-MatchIf-None-Match 等)的读取条件。
  2. read() 阶段

    • 向 Ceph 存储集群下发一个同步读请求,获取该元数据对象的全部内容(一个 bufferlist)。

信息解析与用途

在成功读取数据后,get_multipart_info 函数会进行解码:

  • multipart_upload_info:此结构体包含了目标对象遵循的数据放置规则(placement rule),这对于后续上传的分段(Part)数据写入哪个存储池至关重要。
  • RGWAccessControlPolicy:从对象的扩展属性(RGW_ATTR_ACL)中解码得出,定义了该分段上传任务的访问权限。

通过以上流程,RGW 便能够完整地恢复出一个分段上传任务的上下文信息,为后续的上传段(Upload Part)、完成分段上传(Complete Multipart Upload)等操作提供必要的依据。




上一篇:MySQL 8核心配置与故障处理完整指南
下一篇:迭代SIC-DFT算法详解:突破OFDM-ISAC中CP限制的原理与性能分析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 17:37 , Processed in 0.193314 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表