mirror of
https://github.com/ceph/ceph
synced 2025-01-03 01:22:53 +00:00
librados: add read to c object operation api
Do the usual bufferlist to buffer conversion in a callback from the objecter before the librados user gets called. Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
parent
6503f21a26
commit
0dc4309b08
@ -240,6 +240,7 @@ typedef void *rados_write_op_t;
|
||||
* executed atomically. For usage, see:
|
||||
* - Creation and deletion: rados_create_read_op() rados_release_read_op()
|
||||
* - Object properties: rados_read_op_stat(), rados_read_op_assert_exists()
|
||||
* - IO on objects: rados_read_op_read()
|
||||
* - Request properties: rados_read_op_set_flags()
|
||||
* - Performing the operation: rados_read_op_operate(),
|
||||
* rados_aio_read_op_operate()
|
||||
@ -1964,6 +1965,28 @@ void rados_read_op_stat(rados_read_op_t read_op,
|
||||
time_t *pmtime,
|
||||
int *prval);
|
||||
|
||||
/**
|
||||
* Read bytes from offset into buffer.
|
||||
*
|
||||
* prlen will be filled with the number of bytes read if successful.
|
||||
* A short read can only occur if the read reaches the end of the
|
||||
* object.
|
||||
*
|
||||
* @param read_op operation to add this action to
|
||||
* @param offset offset to read from
|
||||
* @param buffer where to put the data
|
||||
* @param len length of buffer
|
||||
* @param prval where to store the return value of this action
|
||||
* @param bytes_read where to store the number of bytes read by this action
|
||||
*/
|
||||
void rados_read_op_read(rados_read_op_t read_op,
|
||||
uint64_t offset,
|
||||
size_t len,
|
||||
char *buf,
|
||||
size_t *bytes_read,
|
||||
int *prval);
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Perform a write operation synchronously
|
||||
|
@ -3208,6 +3208,45 @@ extern "C" void rados_read_op_stat(rados_read_op_t read_op,
|
||||
((::ObjectOperation *)read_op)->stat(psize, pmtime, prval);
|
||||
}
|
||||
|
||||
class C_bl_to_buf : public Context {
|
||||
char *out_buf;
|
||||
size_t out_len;
|
||||
size_t *bytes_read;
|
||||
int *prval;
|
||||
public:
|
||||
bufferlist out_bl;
|
||||
C_bl_to_buf(char *out_buf,
|
||||
size_t out_len,
|
||||
size_t *bytes_read,
|
||||
int *prval) : out_buf(out_buf), out_len(out_len),
|
||||
bytes_read(bytes_read), prval(prval) {}
|
||||
void finish(int r) {
|
||||
if (out_bl.length() > out_len) {
|
||||
if (prval)
|
||||
*prval = -ERANGE;
|
||||
if (bytes_read)
|
||||
*bytes_read = 0;
|
||||
return;
|
||||
}
|
||||
if (bytes_read)
|
||||
*bytes_read = out_bl.length();
|
||||
if (out_buf && out_bl.c_str() != out_buf)
|
||||
out_bl.copy(0, out_bl.length(), out_buf);
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" void rados_read_op_read(rados_read_op_t read_op,
|
||||
uint64_t offset,
|
||||
size_t len,
|
||||
char *buf,
|
||||
size_t *bytes_read,
|
||||
int *prval)
|
||||
{
|
||||
C_bl_to_buf *ctx = new C_bl_to_buf(buf, len, bytes_read, prval);
|
||||
ctx->out_bl.push_back(buffer::create_static(len, buf));
|
||||
((::ObjectOperation *)read_op)->read(offset, len, &ctx->out_bl, prval, ctx);
|
||||
}
|
||||
|
||||
extern "C" int rados_read_op_operate(rados_read_op_t read_op,
|
||||
rados_ioctx_t io,
|
||||
const char *oid,
|
||||
|
@ -75,6 +75,104 @@ TEST_F(CReadOpsTest, AssertExists) {
|
||||
remove_object();
|
||||
}
|
||||
|
||||
TEST_F(CReadOpsTest, Read) {
|
||||
write_object();
|
||||
|
||||
char buf[len];
|
||||
// check that using read_ops returns the same data with
|
||||
// or without bytes_read and rval out params
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
rados_read_op_read(op, 0, len, buf, NULL, NULL);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
int rval;
|
||||
rados_read_op_read(op, 0, len, buf, NULL, &rval);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(0, rval);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
size_t bytes_read = 0;
|
||||
rados_read_op_read(op, 0, len, buf, &bytes_read, NULL);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(len, (int)bytes_read);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
size_t bytes_read = 0;
|
||||
int rval;
|
||||
rados_read_op_read(op, 0, len, buf, &bytes_read, &rval);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(len, (int)bytes_read);
|
||||
ASSERT_EQ(0, rval);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
remove_object();
|
||||
}
|
||||
|
||||
TEST_F(CReadOpsTest, ShortRead) {
|
||||
write_object();
|
||||
|
||||
char buf[len * 2];
|
||||
// check that using read_ops returns the same data with
|
||||
// or without bytes_read and rval out params
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
rados_read_op_read(op, 0, len * 2, buf, NULL, NULL);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
int rval;
|
||||
rados_read_op_read(op, 0, len * 2, buf, NULL, &rval);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(0, rval);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
size_t bytes_read = 0;
|
||||
rados_read_op_read(op, 0, len * 2, buf, &bytes_read, NULL);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(len, (int)bytes_read);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
{
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
size_t bytes_read = 0;
|
||||
int rval;
|
||||
rados_read_op_read(op, 0, len * 2, buf, &bytes_read, &rval);
|
||||
ASSERT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
|
||||
ASSERT_EQ(len, (int)bytes_read);
|
||||
ASSERT_EQ(0, rval);
|
||||
ASSERT_EQ(0, memcmp(data, buf, len));
|
||||
rados_release_read_op(op);
|
||||
}
|
||||
|
||||
remove_object();
|
||||
}
|
||||
|
||||
TEST_F(CReadOpsTest, Stat) {
|
||||
rados_read_op_t op = rados_create_read_op();
|
||||
uint64_t size = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user