2012-07-24 17:13:39 +00:00
|
|
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
|
|
// vim: ts=8 sw=2 smarttab
|
|
|
|
#ifndef CEPH_LIBRBD_AIOREQUEST_H
|
|
|
|
#define CEPH_LIBRBD_AIOREQUEST_H
|
|
|
|
|
2013-09-07 12:07:52 +00:00
|
|
|
#include "include/int_types.h"
|
2012-07-24 17:13:39 +00:00
|
|
|
|
2013-09-07 12:07:52 +00:00
|
|
|
#include <map>
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
#include "common/snap_types.h"
|
|
|
|
#include "include/buffer.h"
|
|
|
|
#include "include/Context.h"
|
|
|
|
#include "include/rados/librados.hpp"
|
|
|
|
|
|
|
|
namespace librbd {
|
|
|
|
|
2013-08-09 09:58:58 +00:00
|
|
|
struct AioCompletion;
|
|
|
|
struct ImageCtx;
|
2015-01-14 15:52:46 +00:00
|
|
|
class CopyupRequest;
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class represents an I/O operation to a single RBD data object.
|
|
|
|
* Its subclasses encapsulate logic for dealing with special cases
|
|
|
|
* for I/O due to layering.
|
|
|
|
*/
|
|
|
|
class AioRequest
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AioRequest();
|
2012-10-04 23:53:27 +00:00
|
|
|
AioRequest(ImageCtx *ictx, const std::string &oid,
|
2015-01-14 15:52:46 +00:00
|
|
|
uint64_t objectno, uint64_t off, uint64_t len,
|
|
|
|
const ::SnapContext &snapc, librados::snap_t snap_id,
|
|
|
|
Context *completion, bool hide_enoent);
|
2012-07-24 17:13:39 +00:00
|
|
|
virtual ~AioRequest();
|
|
|
|
|
|
|
|
void complete(int r)
|
|
|
|
{
|
|
|
|
if (should_complete(r)) {
|
2012-08-17 19:10:05 +00:00
|
|
|
if (m_hide_enoent && r == -ENOENT)
|
|
|
|
r = 0;
|
2012-07-24 17:13:39 +00:00
|
|
|
m_completion->complete(r);
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool should_complete(int r) = 0;
|
|
|
|
virtual int send() = 0;
|
|
|
|
|
|
|
|
protected:
|
2012-10-04 23:53:27 +00:00
|
|
|
void read_from_parent(vector<pair<uint64_t,uint64_t> >& image_extents);
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
ImageCtx *m_ictx;
|
2013-03-27 22:42:10 +00:00
|
|
|
librados::IoCtx *m_ioctx;
|
2012-07-24 17:13:39 +00:00
|
|
|
std::string m_oid;
|
2012-10-04 23:53:27 +00:00
|
|
|
uint64_t m_object_no, m_object_off, m_object_len;
|
2012-07-24 17:13:39 +00:00
|
|
|
librados::snap_t m_snap_id;
|
|
|
|
Context *m_completion;
|
|
|
|
AioCompletion *m_parent_completion;
|
|
|
|
ceph::bufferlist m_read_data;
|
2012-08-17 19:10:05 +00:00
|
|
|
bool m_hide_enoent;
|
2015-01-14 15:52:46 +00:00
|
|
|
std::vector<librados::snap_t> m_snaps;
|
|
|
|
ceph::bufferlist *m_entire_object;
|
2012-07-24 17:13:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class AioRead : public AioRequest {
|
|
|
|
public:
|
2012-10-04 23:53:27 +00:00
|
|
|
AioRead(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t objectno, uint64_t offset, uint64_t len,
|
2015-01-14 15:52:46 +00:00
|
|
|
vector<pair<uint64_t,uint64_t> >& be, const ::SnapContext &snapc,
|
2012-10-04 23:53:27 +00:00
|
|
|
librados::snap_t snap_id, bool sparse,
|
2014-12-11 06:06:19 +00:00
|
|
|
Context *completion, int op_flags)
|
2015-01-14 15:52:46 +00:00
|
|
|
: AioRequest(ictx, oid, objectno, offset, len, snapc, snap_id, completion,
|
2013-05-12 21:53:26 +00:00
|
|
|
false),
|
2014-12-11 06:06:19 +00:00
|
|
|
m_buffer_extents(be), m_tried_parent(false),
|
2015-01-14 15:52:46 +00:00
|
|
|
m_sparse(sparse), m_op_flags(op_flags), m_state(LIBRBD_AIO_READ_FLAT) {
|
|
|
|
guard_read();
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
virtual ~AioRead() {}
|
|
|
|
virtual bool should_complete(int r);
|
|
|
|
virtual int send();
|
2015-01-14 15:52:46 +00:00
|
|
|
void guard_read();
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
ceph::bufferlist &data() {
|
|
|
|
return m_read_data;
|
|
|
|
}
|
2012-10-04 23:53:27 +00:00
|
|
|
std::map<uint64_t, uint64_t> m_ext_map;
|
|
|
|
|
|
|
|
friend class C_AioRead;
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
private:
|
2012-10-04 23:53:27 +00:00
|
|
|
vector<pair<uint64_t,uint64_t> > m_buffer_extents;
|
2012-07-24 17:13:39 +00:00
|
|
|
bool m_tried_parent;
|
|
|
|
bool m_sparse;
|
2014-12-11 06:06:19 +00:00
|
|
|
int m_op_flags;
|
2015-01-14 15:52:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads go through the following state machine to deal with
|
|
|
|
* layering:
|
|
|
|
*
|
|
|
|
* need copyup
|
|
|
|
* LIBRBD_AIO_READ_GUARD ---------------> LIBRBD_AIO_READ_COPYUP
|
|
|
|
* | |
|
|
|
|
* v |
|
|
|
|
* done <------------------------------------/
|
|
|
|
* ^
|
|
|
|
* |
|
|
|
|
* LIBRBD_AIO_READ_FLAT
|
|
|
|
*
|
|
|
|
* Reads start in LIBRBD_AIO_READ_GUARD or _FLAT, depending on
|
|
|
|
* whether there is a parent or not.
|
|
|
|
*/
|
|
|
|
enum read_state_d {
|
|
|
|
LIBRBD_AIO_READ_GUARD,
|
|
|
|
LIBRBD_AIO_READ_COPYUP,
|
|
|
|
LIBRBD_AIO_READ_FLAT
|
|
|
|
};
|
|
|
|
|
|
|
|
read_state_d m_state;
|
2012-07-24 17:13:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class AbstractWrite : public AioRequest {
|
|
|
|
public:
|
|
|
|
AbstractWrite();
|
2012-10-04 23:53:27 +00:00
|
|
|
AbstractWrite(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t object_no, uint64_t object_off, uint64_t len,
|
|
|
|
vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
|
|
|
|
const ::SnapContext &snapc,
|
|
|
|
librados::snap_t snap_id,
|
|
|
|
Context *completion,
|
|
|
|
bool hide_enoent);
|
2012-07-24 17:13:39 +00:00
|
|
|
virtual ~AbstractWrite() {}
|
|
|
|
virtual bool should_complete(int r);
|
|
|
|
virtual int send();
|
|
|
|
void guard_write();
|
|
|
|
|
2012-10-04 23:53:27 +00:00
|
|
|
bool has_parent() const {
|
|
|
|
return !m_object_image_extents.empty();
|
|
|
|
}
|
|
|
|
|
2012-07-24 17:13:39 +00:00
|
|
|
private:
|
|
|
|
/**
|
2012-10-23 00:57:08 +00:00
|
|
|
* Writes go through the following state machine to deal with
|
|
|
|
* layering:
|
|
|
|
*
|
2012-07-24 17:13:39 +00:00
|
|
|
* need copyup
|
2012-10-23 00:57:08 +00:00
|
|
|
* LIBRBD_AIO_WRITE_GUARD ---------------> LIBRBD_AIO_WRITE_COPYUP
|
|
|
|
* | ^ |
|
|
|
|
* v \------------------------------/
|
|
|
|
* done
|
|
|
|
* ^
|
|
|
|
* |
|
|
|
|
* LIBRBD_AIO_WRITE_FLAT
|
2012-07-24 17:13:39 +00:00
|
|
|
*
|
2012-10-23 00:57:08 +00:00
|
|
|
* Writes start in LIBRBD_AIO_WRITE_GUARD or _FLAT, depending on whether
|
|
|
|
* there is a parent or not.
|
2012-07-24 17:13:39 +00:00
|
|
|
*/
|
|
|
|
enum write_state_d {
|
2012-10-23 00:57:08 +00:00
|
|
|
LIBRBD_AIO_WRITE_GUARD,
|
2012-07-24 17:13:39 +00:00
|
|
|
LIBRBD_AIO_WRITE_COPYUP,
|
2012-10-23 00:57:08 +00:00
|
|
|
LIBRBD_AIO_WRITE_FLAT
|
2012-07-24 17:13:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void add_copyup_ops() = 0;
|
|
|
|
|
|
|
|
write_state_d m_state;
|
2012-10-04 23:53:27 +00:00
|
|
|
vector<pair<uint64_t,uint64_t> > m_object_image_extents;
|
|
|
|
uint64_t m_parent_overlap;
|
2012-07-24 17:13:39 +00:00
|
|
|
librados::ObjectWriteOperation m_write;
|
|
|
|
librados::ObjectWriteOperation m_copyup;
|
2013-03-27 22:42:10 +00:00
|
|
|
uint64_t m_snap_seq;
|
2012-07-24 17:13:39 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void send_copyup();
|
|
|
|
};
|
|
|
|
|
|
|
|
class AioWrite : public AbstractWrite {
|
|
|
|
public:
|
2012-10-04 23:53:27 +00:00
|
|
|
AioWrite(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t object_no, uint64_t object_off,
|
|
|
|
vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
|
2012-07-24 17:13:39 +00:00
|
|
|
const ceph::bufferlist &data, const ::SnapContext &snapc,
|
2012-10-04 23:53:27 +00:00
|
|
|
librados::snap_t snap_id,
|
|
|
|
Context *completion)
|
|
|
|
: AbstractWrite(ictx, oid,
|
|
|
|
object_no, object_off, data.length(),
|
|
|
|
objectx, object_overlap,
|
|
|
|
snapc, snap_id,
|
|
|
|
completion, false),
|
2012-07-24 17:13:39 +00:00
|
|
|
m_write_data(data) {
|
|
|
|
guard_write();
|
2014-02-21 14:34:14 +00:00
|
|
|
add_write_ops(m_write);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
virtual ~AioWrite() {}
|
|
|
|
|
2014-12-11 06:10:45 +00:00
|
|
|
void set_op_flags(int op_flags) {
|
|
|
|
m_write.set_op_flags2(op_flags);
|
|
|
|
}
|
2012-07-24 17:13:39 +00:00
|
|
|
protected:
|
|
|
|
virtual void add_copyup_ops() {
|
2014-02-21 14:34:14 +00:00
|
|
|
add_write_ops(m_copyup);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-02-21 14:34:14 +00:00
|
|
|
void add_write_ops(librados::ObjectWriteOperation &wr);
|
2012-07-24 17:13:39 +00:00
|
|
|
ceph::bufferlist m_write_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AioRemove : public AbstractWrite {
|
|
|
|
public:
|
2012-10-04 23:53:27 +00:00
|
|
|
AioRemove(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t object_no,
|
|
|
|
vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
|
2012-07-24 17:13:39 +00:00
|
|
|
const ::SnapContext &snapc, librados::snap_t snap_id,
|
2012-10-04 23:53:27 +00:00
|
|
|
Context *completion)
|
|
|
|
: AbstractWrite(ictx, oid,
|
|
|
|
object_no, 0, 0,
|
|
|
|
objectx, object_overlap,
|
|
|
|
snapc, snap_id, completion,
|
|
|
|
true) {
|
|
|
|
if (has_parent())
|
2012-07-24 17:13:39 +00:00
|
|
|
m_write.truncate(0);
|
|
|
|
else
|
|
|
|
m_write.remove();
|
|
|
|
}
|
|
|
|
virtual ~AioRemove() {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void add_copyup_ops() {
|
|
|
|
// removing an object never needs to copyup
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class AioTruncate : public AbstractWrite {
|
|
|
|
public:
|
2012-10-04 23:53:27 +00:00
|
|
|
AioTruncate(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t object_no, uint64_t object_off,
|
|
|
|
vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
|
2012-07-24 17:13:39 +00:00
|
|
|
const ::SnapContext &snapc, librados::snap_t snap_id,
|
2012-10-04 23:53:27 +00:00
|
|
|
Context *completion)
|
|
|
|
: AbstractWrite(ictx, oid,
|
|
|
|
object_no, object_off, 0,
|
|
|
|
objectx, object_overlap,
|
|
|
|
snapc, snap_id, completion,
|
|
|
|
true) {
|
2012-07-24 17:13:39 +00:00
|
|
|
guard_write();
|
2012-10-04 23:53:27 +00:00
|
|
|
m_write.truncate(object_off);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
virtual ~AioTruncate() {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void add_copyup_ops() {
|
2012-10-04 23:53:27 +00:00
|
|
|
m_copyup.truncate(m_object_off);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class AioZero : public AbstractWrite {
|
|
|
|
public:
|
2012-10-04 23:53:27 +00:00
|
|
|
AioZero(ImageCtx *ictx, const std::string &oid,
|
|
|
|
uint64_t object_no, uint64_t object_off, uint64_t object_len,
|
|
|
|
vector<pair<uint64_t,uint64_t> >& objectx, uint64_t object_overlap,
|
|
|
|
const ::SnapContext &snapc, librados::snap_t snap_id,
|
|
|
|
Context *completion)
|
|
|
|
: AbstractWrite(ictx, oid,
|
|
|
|
object_no, object_off, object_len,
|
|
|
|
objectx, object_overlap,
|
|
|
|
snapc, snap_id, completion,
|
|
|
|
true) {
|
2012-07-24 17:13:39 +00:00
|
|
|
guard_write();
|
2012-10-04 23:53:27 +00:00
|
|
|
m_write.zero(object_off, object_len);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
virtual ~AioZero() {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void add_copyup_ops() {
|
2012-10-04 23:53:27 +00:00
|
|
|
m_copyup.zero(m_object_off, m_object_len);
|
2012-07-24 17:13:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|