RBD Image映射到Object

該函數是將更新的image的範圍映射到具體的對象上.這個部分涉及到stripe的概念,需要預先了解這個概念(可以參考官網對其的解釋)

void aio_write(ImageCtx *ictx, uint64_t off, size_t len, const char *buf,
              ¦AioCompletion *c, int op_flags)
{            
...
  ¦ // map
  ¦ vector<ObjectExtent> extents;
  ¦ if (len > 0) {
  //將更新的image的範圍映射到具體的對象上
  ¦ ¦ Striper::file_to_extents(ictx->cct, ictx->format_string,
                         ¦ ¦ ¦ &ictx->layout, off, clip_len, 0, extents);
  ¦ }

  ¦ for (vector<ObjectExtent>::iterator p = extents.begin(); p != extents.end(); ++p) {
  ¦ ¦ ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
                ¦ ¦ ¦<< " from " << p->buffer_extents << dendl;
  ¦ ¦ // assemble extent
  ¦ ¦ bufferlist bl;
  ¦ ¦ for (vector<pair<uint64_t,uint64_t> >::iterator q = p->buffer_extents.begin();
         ¦ q != p->buffer_extents.end();
         ¦ ++q) {
        bl.append(buf + q->first, q->second);
  ¦ ¦ }
  }
  ...
}  

void Striper::file_to_extents(CephContext *cct, const char *object_format,
                              const ceph_file_layout *layout,
                              uint64_t offset, uint64_t len, uint64_t trunc_size,
                              map<object_t,vector<ObjectExtent> >& object_extents,
                              uint64_t buffer_offset)
                              //offset 是相對於image的偏移位置, len是影響的範圍
{
  ldout(cct, 10) << "file_to_extents " << offset << "~" << len 
                ¦<< " format " << object_format
                ¦<< dendl;
  assert(len > 0);

  /*
  ¦* we want only one extent per object!
  ¦* this means that each extent we read may map into different bits of the 
  ¦* final read buffer.. hence ObjectExtent.buffer_extents
  ¦*/

  __u32 object_size = layout->fl_object_size; //一個對象的字節大小
  __u32 su = layout->fl_stripe_unit;          //一個stripe的大小
  __u32 stripe_count = layout->fl_stripe_count; // 一個stripe中的unit(block)的數量
  assert(object_size >= su);
  uint64_t stripes_per_object = object_size / su;  //一個對象關聯的stripe的數量
  ldout(cct, 20) << " su " << su << " sc " << stripe_count << " os " << object_size
                ¦<< " stripes_per_object " << stripes_per_object << dendl;

  uint64_t cur = offset;
  uint64_t left = len;
  while (left > 0) {
  ¦ // layout into objects
  ¦ uint64_t blockno = cur / su;          // which block   //cur位置跨越的block數
  ¦ uint64_t stripeno = blockno / stripe_count;    // which horizontal stripe        (Y) //cur位置跨越的stripe數
  ¦ uint64_t stripepos = blockno % stripe_count;   // which object in the object set (X) // blockno在stripe中的偏移位置
  ¦ uint64_t objectsetno = stripeno / stripes_per_object;       // which object set      //cur位置跨越的object set數
  ¦ uint64_t objectno = objectsetno * stripe_count + stripepos;  // object id            //cur所在的object(image中的object從0開始自然排序)注object從0開始編號

  ¦ // find oid, extent
  ¦ char buf[strlen(object_format) + 32];
  ¦ snprintf(buf, sizeof(buf), object_format, (long long unsigned)objectno);   //獲取對象的oid,命名格式是{object_prefix}.%012llx,即對象的前綴+object的序號
  ¦ object_t oid = buf;

  ¦ // map range into object 映射到對象內,相對對象的偏移位置(x_offset)
  ¦ uint64_t block_start = (stripeno % stripes_per_object) * su;
  ¦ uint64_t block_off = cur % su;
  ¦ uint64_t max = su - block_off;

  ¦ uint64_t x_offset = block_start + block_off;
  //從偏移位置開始影響對象的範圍
  ¦ uint64_t x_len;
  ¦ if (left > max)
  ¦ ¦ x_len = max;
  ¦ else
  ¦ ¦ x_len = left;

  ¦ ldout(cct, 20) << " off " << cur << " blockno " << blockno << " stripeno " << stripeno
                ¦ ¦<< " stripepos " << stripepos << " objectsetno " << objectsetno
                ¦ ¦<< " objectno " << objectno
                ¦ ¦<< " block_start " << block_start
                ¦ ¦<< " block_off " << block_off
                ¦ ¦<< " " << x_offset << "~" << x_len
                ¦ ¦<< dendl;

  ¦ ObjectExtent *ex = 0;
  ¦ vector<ObjectExtent>& exv = object_extents[oid];
  //如果object對象的該次操作時第一個,或者與之前的操作在object內部地址不聯繫則重新申請一個ObjectExtent來存儲該次操作的一些信息(對象、偏移位置、範圍)
  //否則直接更新之前的ObjectExtent,擴大影響的範圍
  ¦ if (exv.empty() || exv.back().offset + exv.back().length != x_offset) {
  ¦ ¦ exv.resize(exv.size() + 1);
  ¦ ¦ ex = &exv.back();
  ¦ ¦ ex->oid = oid;
  ¦ ¦ ex->objectno = objectno;
  ¦ ¦ ex->oloc = OSDMap::file_to_object_locator(*layout);

  ¦ ¦ ex->offset = x_offset;
  ¦ ¦ ex->length = x_len;
  ¦ ¦ ex->truncate_size = object_truncate_size(cct, layout, objectno, trunc_size); //trunc_size == 0

  ¦ ¦ ldout(cct, 20) << " added new " << *ex << dendl;
  ¦ } else {
  ¦ ¦ // add to extent
  ¦ ¦ ex = &exv.back();
  ¦ ¦ ldout(cct, 20) << " adding in to " << *ex << dendl;
  ¦ ¦ ex->length += x_len;
  ¦ }
    //將該ObjectExtent與更新的數據做個映射(cur - offset + buffer_offset 相對更新數據的偏移位置,x_len範圍)  
  ¦ ex->buffer_extents.push_back(make_pair(cur - offset + buffer_offset, x_len));
  ¦ ¦ ¦
  ¦ ldout(cct, 15) << "file_to_extents  " << *ex << " in " << ex->oloc << dendl;
  ¦ ldout(cct, 15) << "file_to_extents  " << *ex << " in " << ex->oloc << dendl;
  ¦ //ldout(cct, 0) << "map: ino " << ino << " oid " << ex.oid << " osd " << ex.osd << " offset " << ex.offset << " len " << ex.len << " ... left " << left << dendl;
  ¦ //減去已經映射到object對象上的部分,繼續後續的映射。
  ¦ left -= x_len;
  ¦ cur += x_len;
  }
}


for (vector<ObjectExtent>::iterator p = extents.begin(); p != extents.end(); ++p) {
  ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
                 << " from " << p->buffer_extents << dendl;
  // assemble extent
  bufferlist bl;
  for (vector<pair<uint64_t,uint64_t> >::iterator q = p->buffer_extents.begin();
       q != p->buffer_extents.end();
       ++q) {
     //聚合同一個object上且object內地址連續的更新數據
    bl.append(buf + q->first, q->second);
  }
  ....
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章