Loading...
Searching...
No Matches
bulkAioRead Class Reference

`#include <XrdCephBulkAioRead.hh>`

Collaboration diagram for bulkAioRead:

## Public Member Functions

| bulkAioRead (librados::IoCtx *ct, logfunc_pointer ptr, CephFileRef *fileref)
| ~bulkAioRead ()
void | clear ()
ssize_t | get_results ()
int | read (void *out_buf, size_t size, off64_t offset)
int | submit_and_wait_for_complete ()

## Detailed Description

Definition at line 10 of file XrdCephBulkAioRead.hh.

## Constructor & Destructor Documentation

## bulkAioRead()

bulkAioRead::bulkAioRead | ( | librados::IoCtx * | ct,
|  | logfunc_pointer | ptr,
|  | CephFileRef * | fileref )

Class is used to execute read operations against rados striper files without usage of rados striper. Reads are based on ceph read operations.

The interface is similar to the one that ceph's read operation objects has:

1. Instantiate the object.
2. Declare read operations using 'read' method, providing the output buffers, offset and length.
3. Submitn operation and wait for results using 'submit_and_wait_for_complete' method.
4. Copy results to buffers with 'get_results' method.

WARNING: there is no copy/move constructor in the class, so do not use temporary objects for initialization (i.e. something like bulkAioRead rop = bulkAioRead(...); will not work, use bulkAioRead rop(...); instead).

Constructor.

Parameters

  ct | Rados IoContext object
  logfunc_pointer | Pointer to the function that will be used for logging
  fileref | Ceph file reference

Definition at line 4 of file XrdCephBulkAioRead.cc.

{
context = ct;
file_ref = fileref;
log_func = logwrapper;
}
logwrapper
static void logwrapper(char *format, va_list argp)
Definition XrdCephOss.cc:62

References logwrapper().

Here is the call graph for this function:

## ~bulkAioRead()

bulkAioRead::~bulkAioRead | ( |  | ) |

Destructor. Just clears dynamically allocated memroy.

Definition at line 18 of file XrdCephBulkAioRead.cc.

{
clear();
}
bulkAioRead::clear
void clear()
Definition XrdCephBulkAioRead.cc:25

References clear().

Here is the call graph for this function:

## Member Function Documentation

## clear()

void bulkAioRead::clear | ( |  | ) |

Clear all dynamically alocated memory

Definition at line 25 of file XrdCephBulkAioRead.cc.

{
operations.clear();
buffers.clear();
}

Referenced by ~bulkAioRead(), and get_results().

Here is the caller graph for this function:

## get_results()

ssize_t bulkAioRead::get_results | ( |  | ) |

Copy the results of executed read requests from ceph's bufferlists to client's buffers

Note that this method should be called only after the submission and completion of read requests, i.e. after submit_and_wait_for_complete method.

Returns
  cumulative number of bytes read (by all read operations) on success, negative error code on failure

Definition at line 114 of file XrdCephBulkAioRead.cc.

{
ssize_t res = 0;
for (ReadOpData &op_data: buffers) {
if (op_data.rc < 0) {
//Is it possible to get here?
log_func((char*)"One of the reads failed with rc %d", op_data.rc);
return op_data.rc;
}
op_data.bl.begin().copy(op_data.bl.length(), op_data.out_buf);
res += op_data.bl.length();
}
//We should clear used completions to allow new operations
clear();
return res;
}

References clear().

Referenced by ceph_nonstriper_readv(), and ceph_posix_nonstriper_pread().

Here is the call graph for this function:
Here is the caller graph for this function:

## read()

int bulkAioRead::read | ( | void * | out_buf,
|  | size_t | size,
|  | off64_t | offset )

Declare a read operation for file.

Read coordinates are global, i.e. valid offsets are from 0 to the <file_size> -1, valid request sizes are from 0 to INF. Method can be called multiple times to declare multiple read operations on the same file.

Parameters

  out_buf | output buffer, where read results should be stored
  req_size | number of bytes to read
  offset | offset in bytes where the read should start. Note that the offset is global, i.e. refers to the whole file, not individual ceph objects

Returns
  zero on success, negative error code on failure

Definition at line 141 of file XrdCephBulkAioRead.cc.

{
if (req_size == 0) {
log_func((char*)"Zero-length read request for file %s, probably client error", file_ref->name.c_str());
return 0;
}
char* const buf_start_ptr = (char*) out_buf;
size_t object_size = file_ref->objectSize;
//The amount of bytes that is yet to be read
size_t to_read = req_size;
//block means ceph object here
size_t start_block = offset / object_size;
size_t buf_pos = 0;
size_t chunk_start = offset % object_size;
while (to_read > 0) {
size_t chunk_len = std::min(to_read, object_size - chunk_start);
if (buf_pos >= req_size) {
log_func((char*)"Internal bug! Attempt to read %lu data for block (%lu, %lu) of file %s\n", buf_pos, offset, req_size, file_ref->name.c_str());
return -EINVAL;
}
int rc = addRequest(start_block, buf_start_ptr + buf_pos, chunk_len, chunk_start);
if (rc < 0) {
log_func((char*)"Unable to submit async read request, rc=%d\n", rc);
return rc;
}
buf_pos += chunk_len;
start_block++;
chunk_start = 0;
if (chunk_len > to_read) {
log_func((char*)"Internal bug! Read %lu bytes, more than expected %lu bytes for block (%lu, %lu) of file %s\n", chunk_len, to_read, offset, req_size, file_ref->name.c_str());
return -EINVAL;
}
to_read = to_read - chunk_len;
}
return 0;
}

Referenced by ceph_nonstriper_readv(), and ceph_posix_nonstriper_pread().

Here is the caller graph for this function:

## submit_and_wait_for_complete()

int bulkAioRead::submit_and_wait_for_complete | ( |  | ) |

Submit previously prepared read requests and wait for their completion

To prepare read requests use read or addRequest methods.

Returns
  zero on success, negative error code on failure

Definition at line 64 of file XrdCephBulkAioRead.cc.

{
for (auto &op_data: operations) {
size_t obj_idx = op_data.first;
//16 bytes for object hex number, 1 for dot and 1 for null-terminator
char object_suffix[18];
int sp_bytes_written;
sp_bytes_written = snprintf(object_suffix, sizeof(object_suffix), ".%016zx", obj_idx);
if (sp_bytes_written >= (int) sizeof(object_suffix)) {
log_func((char*)"Can not fit object suffix into buffer for file %s -- too big\n", file_ref->name.c_str());
return -EFBIG;
}
std::string obj_name;
try {
obj_name = file_ref->name + std::string(object_suffix);
} catch (std::bad_alloc&) {
log_func((char*)"Can not create object string for file %s)", file_ref->name.c_str());
return -ENOMEM;
}
context->aio_operate(obj_name, op_data.second.cmpl.use(), &op_data.second.ceph_read_op, 0);
}
for (auto &op_data: operations) {
op_data.second.cmpl.wait_for_complete();
int rval = op_data.second.cmpl.get_return_value();
/*
* Optimization is possible here: cancel all remaining read operations after the failure.
* One way to do so is the following: add context as an argument to the `use` method of CmplPtr.
* Then inside the class this pointer can be saved and used by the destructor to call
* `aio_cancel` (and probably `wait_for_complete`) before releasing the completion.
* Though one need to clarify whether it is necessary to cal `wait_for_complete` after
* `aio_cancel` (i.e. may the status variable/bufferlist still be written to or not).
*/
if (rval < 0) {
log_func((char*)"Read of the object %ld for file %s failed", op_data.first, file_ref->name.c_str());
return rval;
}
}
return 0;
}

Referenced by ceph_nonstriper_readv(), and ceph_posix_nonstriper_pread().

Here is the caller graph for this function:

The documentation for this class was generated from the following files:

- XrdCephBulkAioRead.hh
- XrdCephBulkAioRead.cc