static int onode_populate_extents(struct kv_onode *onode, struct http_request *req) { ssize_t size; uint64_t start = 0, count, done = 0, total, offset; int ret; char *data_buf = NULL; uint32_t data_vid = onode->data_vid; uint64_t write_buffer_size = MIN(MAX_RW_BUFFER, req->data_length); count = DIV_ROUND_UP(req->data_length, SD_DATA_OBJ_SIZE); sys->cdrv->lock(data_vid); ret = oalloc_new_prepare(data_vid, &start, count); sys->cdrv->unlock(data_vid); if (ret != SD_RES_SUCCESS) { sd_err("oalloc_new_prepare failed for %s, %s", onode->name, sd_strerror(ret)); goto out; } data_buf = xmalloc(write_buffer_size); offset = start * SD_DATA_OBJ_SIZE; total = req->data_length; while (done < total) { size = http_request_read(req, data_buf, write_buffer_size); ret = vdi_read_write(data_vid, data_buf, size, offset, false); if (ret != SD_RES_SUCCESS) { sd_err("Failed to write data object for %s, %s", onode->name, sd_strerror(ret)); goto out; } done += size; offset += size; } sys->cdrv->lock(data_vid); ret = oalloc_new_finish(data_vid, start, count); sys->cdrv->unlock(data_vid); if (ret != SD_RES_SUCCESS) { sd_err("oalloc_new_finish failed for %s, %s", onode->name, sd_strerror(ret)); goto out; } onode->o_extent[0].start = start; onode->o_extent[0].count = count; onode->nr_extent = 1; out: free(data_buf); return ret; }
static int onode_read_extents(struct kv_onode *onode, struct http_request *req) { struct onode_extent *ext; uint64_t size, total, total_size, offset, done = 0, i, ext_len; uint64_t off = req->offset, len = req->data_length; int ret; char *data_buf = NULL; uint64_t read_buffer_size = MIN(kv_rw_buffer, onode->size); data_buf = xmalloc(read_buffer_size); total_size = len; for (i = 0; i < onode->nr_extent; i++) { ext = onode->o_extent + i; ext_len = ext->count * SD_DATA_OBJ_SIZE; if (off >= ext_len) { off -= ext_len; continue; } total = min(ext_len - off, total_size); offset = ext->start * SD_DATA_OBJ_SIZE + off; off = 0; done = 0; while (done < total) { size = MIN(total - done, read_buffer_size); ret = vdi_read_write(onode->data_vid, data_buf, size, offset, true); sd_debug("vdi_read_write size: %"PRIx64", offset: %" PRIx64, size, offset); if (ret != SD_RES_SUCCESS) { sd_err("Failed to read for vid %"PRIx32, onode->data_vid); goto out; } http_request_write(req, data_buf, size); done += size; offset += size; total_size -= size; } } out: free(data_buf); return ret; }