Skip to content

Commit

Permalink
rbd: add rbd_resize2 for allow_shrink option
Browse files Browse the repository at this point in the history
  • Loading branch information
neurodrone committed Jul 13, 2016
1 parent e489cd4 commit d1f2c55
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 73 deletions.
2 changes: 2 additions & 0 deletions src/include/rbd/librbd.h
Expand Up @@ -272,6 +272,8 @@ CEPH_RBD_API int rbd_aio_open_read_only(rados_ioctx_t io, const char *name,
CEPH_RBD_API int rbd_close(rbd_image_t image);
CEPH_RBD_API int rbd_aio_close(rbd_image_t image, rbd_completion_t c);
CEPH_RBD_API int rbd_resize(rbd_image_t image, uint64_t size);
CEPH_RBD_API int rbd_resize2(rbd_image_t image, uint64_t size, bool allow_shrink,
librbd_progress_fn_t cb, void *cbdata);
CEPH_RBD_API int rbd_resize_with_progress(rbd_image_t image, uint64_t size,
librbd_progress_fn_t cb, void *cbdata);
CEPH_RBD_API int rbd_stat(rbd_image_t image, rbd_image_info_t *info,
Expand Down
1 change: 1 addition & 0 deletions src/include/rbd/librbd.hpp
Expand Up @@ -191,6 +191,7 @@ class CEPH_RBD_API Image
int aio_close(RBD::AioCompletion *c);

int resize(uint64_t size);
int resize2(uint64_t size, bool allow_shrink, ProgressContext& pctx);
int resize_with_progress(uint64_t size, ProgressContext& pctx);
int stat(image_info_t &info, size_t infosize);
int parent_info(std::string *parent_poolname, std::string *parent_name,
Expand Down
9 changes: 5 additions & 4 deletions src/librbd/ImageWatcher.cc
Expand Up @@ -213,7 +213,7 @@ void ImageWatcher::notify_flatten(uint64_t request_id,
}

void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size,
ProgressContext &prog_ctx,
bool allow_shrink, ProgressContext &prog_ctx,
Context *on_finish) {
assert(m_image_ctx.owner_lock.is_locked());
assert(m_image_ctx.exclusive_lock &&
Expand All @@ -222,7 +222,7 @@ void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size,
AsyncRequestId async_request_id(get_client_id(), request_id);

bufferlist bl;
::encode(NotifyMessage(ResizePayload(size, async_request_id)), bl);
::encode(NotifyMessage(ResizePayload(size, allow_shrink, async_request_id)), bl);
notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish);
}

Expand Down Expand Up @@ -711,8 +711,9 @@ bool ImageWatcher::handle_payload(const ResizePayload &payload,
if (new_request) {
ldout(m_image_ctx.cct, 10) << this << " remote resize request: "
<< payload.async_request_id << " "
<< payload.size << dendl;
m_image_ctx.operations->execute_resize(payload.size, *prog_ctx, ctx, 0);
<< payload.size << " "
<< payload.allow_shrink << dendl;
m_image_ctx.operations->execute_resize(payload.size, payload.allow_shrink, *prog_ctx, ctx, 0);
}

::encode(ResponseMessage(r), ack_ctx->out);
Expand Down
2 changes: 1 addition & 1 deletion src/librbd/ImageWatcher.h
Expand Up @@ -33,7 +33,7 @@ class ImageWatcher {

void notify_flatten(uint64_t request_id, ProgressContext &prog_ctx,
Context *on_finish);
void notify_resize(uint64_t request_id, uint64_t size,
void notify_resize(uint64_t request_id, uint64_t size, bool allow_shrink,
ProgressContext &prog_ctx, Context *on_finish);
void notify_snap_create(const std::string &snap_name, Context *on_finish);
void notify_snap_rename(const snapid_t &src_snap_id,
Expand Down
12 changes: 6 additions & 6 deletions src/librbd/Operations.cc
Expand Up @@ -558,7 +558,7 @@ void Operations<I>::execute_rename(const char *dstname, Context *on_finish) {
}

template <typename I>
int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
int Operations<I>::resize(uint64_t size, bool allow_shrink, ProgressContext& prog_ctx) {
CephContext *cct = m_image_ctx.cct;

m_image_ctx.snap_lock.get_read();
Expand All @@ -581,18 +581,18 @@ int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
uint64_t request_id = ++m_async_request_seq;
r = invoke_async_request("resize", false,
boost::bind(&Operations<I>::execute_resize, this,
size, boost::ref(prog_ctx), _1, 0),
size, allow_shrink, boost::ref(prog_ctx), _1, 0),
boost::bind(&ImageWatcher::notify_resize,
m_image_ctx.image_watcher, request_id,
size, boost::ref(prog_ctx), _1));
size, allow_shrink, boost::ref(prog_ctx), _1));

m_image_ctx.perfcounter->inc(l_librbd_resize);
ldout(cct, 2) << "resize finished" << dendl;
return r;
}

template <typename I>
void Operations<I>::execute_resize(uint64_t size, ProgressContext &prog_ctx,
void Operations<I>::execute_resize(uint64_t size, bool allow_shrink, ProgressContext &prog_ctx,
Context *on_finish,
uint64_t journal_op_tid) {
assert(m_image_ctx.owner_lock.is_locked());
Expand All @@ -619,8 +619,8 @@ void Operations<I>::execute_resize(uint64_t size, ProgressContext &prog_ctx,
m_image_ctx.snap_lock.put_read();

operation::ResizeRequest<I> *req = new operation::ResizeRequest<I>(
m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), size, prog_ctx,
journal_op_tid, false);
m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), size, allow_shrink,
prog_ctx, journal_op_tid, false);
req->send();
}

Expand Down
4 changes: 2 additions & 2 deletions src/librbd/Operations.h
Expand Up @@ -39,8 +39,8 @@ class Operations {
int rename(const char *dstname);
void execute_rename(const char *dstname, Context *on_finish);

int resize(uint64_t size, ProgressContext& prog_ctx);
void execute_resize(uint64_t size, ProgressContext &prog_ctx,
int resize(uint64_t size, bool allow_shrink, ProgressContext& prog_ctx);
void execute_resize(uint64_t size, bool allow_shrink, ProgressContext &prog_ctx,
Context *on_finish, uint64_t journal_op_tid);

int snap_create(const char *snap_name);
Expand Down
14 changes: 10 additions & 4 deletions src/librbd/WatchNotifyTypes.cc
Expand Up @@ -207,17 +207,23 @@ void AsyncCompletePayload::dump(Formatter *f) const {
}

void ResizePayload::encode(bufferlist &bl) const {
::encode(size, bl);
AsyncRequestPayloadBase::encode(bl);
::encode(size, bl);
::encode(allow_shrink, bl);
}

void ResizePayload::decode(__u8 version, bufferlist::iterator &iter) {
::decode(size, iter);
AsyncRequestPayloadBase::decode(version, iter);
::decode(size, iter);

if (version >= 4) {
::decode(allow_shrink, iter);
}
}

void ResizePayload::dump(Formatter *f) const {
f->dump_unsigned("size", size);
f->dump_bool("allow_shrink", allow_shrink);
AsyncRequestPayloadBase::dump(f);
}

Expand Down Expand Up @@ -275,7 +281,7 @@ bool NotifyMessage::check_for_refresh() const {
}

void NotifyMessage::encode(bufferlist& bl) const {
ENCODE_START(3, 1, bl);
ENCODE_START(4, 1, bl);
boost::apply_visitor(EncodePayloadVisitor(bl), payload);
ENCODE_FINISH(bl);
}
Expand Down Expand Up @@ -354,7 +360,7 @@ void NotifyMessage::generate_test_instances(std::list<NotifyMessage *> &o) {
o.push_back(new NotifyMessage(AsyncProgressPayload(AsyncRequestId(ClientId(0, 1), 2), 3, 4)));
o.push_back(new NotifyMessage(AsyncCompletePayload(AsyncRequestId(ClientId(0, 1), 2), 3)));
o.push_back(new NotifyMessage(FlattenPayload(AsyncRequestId(ClientId(0, 1), 2))));
o.push_back(new NotifyMessage(ResizePayload(123, AsyncRequestId(ClientId(0, 1), 2))));
o.push_back(new NotifyMessage(ResizePayload(123, true, AsyncRequestId(ClientId(0, 1), 2))));
o.push_back(new NotifyMessage(SnapCreatePayload("foo")));
o.push_back(new NotifyMessage(SnapRemovePayload("foo")));
o.push_back(new NotifyMessage(SnapProtectPayload("foo")));
Expand Down
7 changes: 4 additions & 3 deletions src/librbd/WatchNotifyTypes.h
Expand Up @@ -200,11 +200,12 @@ struct ResizePayload : public AsyncRequestPayloadBase {
static const NotifyOp NOTIFY_OP = NOTIFY_OP_RESIZE;
static const bool CHECK_FOR_REFRESH = true;

ResizePayload() : size(0) {}
ResizePayload(uint64_t size_, const AsyncRequestId &id)
: AsyncRequestPayloadBase(id), size(size_) {}
ResizePayload() : size(0), allow_shrink(true) {}
ResizePayload(uint64_t size_, bool allow_shrink_, const AsyncRequestId &id)
: AsyncRequestPayloadBase(id), size(size_), allow_shrink(allow_shrink_) {}

uint64_t size;
bool allow_shrink;

void encode(bufferlist &bl) const;
void decode(__u8 version, bufferlist::iterator &iter);
Expand Down
2 changes: 1 addition & 1 deletion src/librbd/journal/Replay.cc
Expand Up @@ -76,7 +76,7 @@ struct ExecuteOp : public Context {
}

void execute(const journal::ResizeEvent &_) {
image_ctx.operations->execute_resize(event.size, no_op_progress_callback,
image_ctx.operations->execute_resize(event.size, true, no_op_progress_callback,
on_op_complete, event.op_tid);
}

Expand Down
28 changes: 24 additions & 4 deletions src/librbd/librbd.cc
Expand Up @@ -615,7 +615,16 @@ namespace librbd {
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::NoOpProgressContext prog_ctx;
int r = ictx->operations->resize(size, prog_ctx);
int r = ictx->operations->resize(size, true, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}

int Image::resize2(uint64_t size, bool allow_shrink, librbd::ProgressContext& pctx)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
int r = ictx->operations->resize(size, allow_shrink, pctx);
tracepoint(librbd, resize_exit, r);
return r;
}
Expand All @@ -624,7 +633,7 @@ namespace librbd {
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
int r = ictx->operations->resize(size, pctx);
int r = ictx->operations->resize(size, true, pctx);
tracepoint(librbd, resize_exit, r);
return r;
}
Expand Down Expand Up @@ -1969,7 +1978,18 @@ extern "C" int rbd_resize(rbd_image_t image, uint64_t size)
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::NoOpProgressContext prog_ctx;
int r = ictx->operations->resize(size, prog_ctx);
int r = ictx->operations->resize(size, true, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}

extern "C" int rbd_resize2(rbd_image_t image, uint64_t size, bool allow_shrink,
librbd_progress_fn_t cb, void *cbdata)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::CProgressContext prog_ctx(cb, cbdata);
int r = ictx->operations->resize(size, allow_shrink, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}
Expand All @@ -1980,7 +2000,7 @@ extern "C" int rbd_resize_with_progress(rbd_image_t image, uint64_t size,
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::CProgressContext prog_ctx(cb, cbdata);
int r = ictx->operations->resize(size, prog_ctx);
int r = ictx->operations->resize(size, true, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}
Expand Down
15 changes: 11 additions & 4 deletions src/librbd/operation/ResizeRequest.cc
Expand Up @@ -25,11 +25,11 @@ using util::create_rados_safe_callback;

template <typename I>
ResizeRequest<I>::ResizeRequest(I &image_ctx, Context *on_finish,
uint64_t new_size, ProgressContext &prog_ctx,
uint64_t new_size, bool allow_shrink, ProgressContext &prog_ctx,
uint64_t journal_op_tid, bool disable_journal)
: Request<I>(image_ctx, on_finish, journal_op_tid),
m_original_size(0), m_new_size(new_size), m_prog_ctx(prog_ctx),
m_new_parent_overlap(0), m_disable_journal(disable_journal),
m_original_size(0), m_new_size(new_size), m_allow_shrink(allow_shrink),
m_prog_ctx(prog_ctx), m_new_parent_overlap(0), m_disable_journal(disable_journal),
m_xlist_item(this)
{
}
Expand Down Expand Up @@ -114,12 +114,19 @@ Context *ResizeRequest<I>::handle_pre_block_writes(int *result) {
template <typename I>
Context *ResizeRequest<I>::send_append_op_event() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;

if (m_new_size < m_original_size && !m_allow_shrink) {
ldout(cct, 1) << " shrinking the image is not permitted" << dendl;
this->async_complete(-EINVAL);
return nullptr;
}

if (m_disable_journal || !this->template append_op_event<
ResizeRequest<I>, &ResizeRequest<I>::handle_append_op_event>(this)) {
return send_grow_object_map();
}

CephContext *cct = image_ctx.cct;
ldout(cct, 5) << this << " " << __func__ << dendl;
return nullptr;
}
Expand Down
10 changes: 6 additions & 4 deletions src/librbd/operation/ResizeRequest.h
Expand Up @@ -18,14 +18,15 @@ template <typename ImageCtxT = ImageCtx>
class ResizeRequest : public Request<ImageCtxT> {
public:
static ResizeRequest *create(ImageCtxT &image_ctx, Context *on_finish,
uint64_t new_size, ProgressContext &prog_ctx,
uint64_t journal_op_tid, bool disable_journal) {
return new ResizeRequest(image_ctx, on_finish, new_size, prog_ctx,
uint64_t new_size, bool allow_shrink,
ProgressContext &prog_ctx, uint64_t journal_op_tid,
bool disable_journal) {
return new ResizeRequest(image_ctx, on_finish, new_size, allow_shrink, prog_ctx,
journal_op_tid, disable_journal);
}

ResizeRequest(ImageCtxT &image_ctx, Context *on_finish, uint64_t new_size,
ProgressContext &prog_ctx, uint64_t journal_op_tid,
bool allow_shrink, ProgressContext &prog_ctx, uint64_t journal_op_tid,
bool disable_journal);
virtual ~ResizeRequest();

Expand Down Expand Up @@ -106,6 +107,7 @@ class ResizeRequest : public Request<ImageCtxT> {

uint64_t m_original_size;
uint64_t m_new_size;
bool m_allow_shrink = true;
ProgressContext &m_prog_ctx;
uint64_t m_new_parent_overlap;
bool m_shrink_size_visible = false;
Expand Down
2 changes: 1 addition & 1 deletion src/librbd/operation/SnapshotRollbackRequest.cc
Expand Up @@ -137,7 +137,7 @@ void SnapshotRollbackRequest<I>::send_resize_image() {
SnapshotRollbackRequest<I>,
&SnapshotRollbackRequest<I>::handle_resize_image>(this);
ResizeRequest<I> *req = ResizeRequest<I>::create(image_ctx, ctx, m_snap_size,
m_no_op_prog_ctx, 0, true);
true, m_no_op_prog_ctx, 0, true);
req->send();
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/librbd/journal/test_Replay.cc
Expand Up @@ -617,7 +617,7 @@ TEST_F(TestJournalReplay, Resize) {

// verify lock ordering constraints
librbd::NoOpProgressContext no_op_progress;
ASSERT_EQ(0, ictx->operations->resize(0, no_op_progress));
ASSERT_EQ(0, ictx->operations->resize(0, true, no_op_progress));
}

TEST_F(TestJournalReplay, Flatten) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/librbd/journal/test_mock_Replay.cc
Expand Up @@ -138,8 +138,8 @@ class TestMockJournalReplay : public TestMockFixture {

void expect_resize(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
uint64_t size, uint64_t op_tid) {
EXPECT_CALL(*mock_image_ctx.operations, execute_resize(size, _, _, op_tid))
.WillOnce(DoAll(SaveArg<2>(on_finish),
EXPECT_CALL(*mock_image_ctx.operations, execute_resize(size, _, _, _, op_tid))
.WillOnce(DoAll(SaveArg<3>(on_finish),
NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/librbd/mock/MockOperations.h
Expand Up @@ -18,8 +18,8 @@ struct MockOperations {
MOCK_METHOD2(execute_rebuild_object_map, void(ProgressContext &prog_ctx,
Context *on_finish));
MOCK_METHOD2(execute_rename, void(const char *dstname, Context *on_finish));
MOCK_METHOD4(execute_resize, void(uint64_t size, ProgressContext &prog_ctx,
Context *on_finish,
MOCK_METHOD5(execute_resize, void(uint64_t size, bool allow_shrink,
ProgressContext &prog_ctx, Context *on_finish,
uint64_t journal_op_tid));
MOCK_METHOD2(snap_create, void(const char *snap_name, Context *on_finish));
MOCK_METHOD4(execute_snap_create, void(const char *snap_name,
Expand Down

0 comments on commit d1f2c55

Please sign in to comment.