rbd: add rbd_resize2 for allow_shrink option

This commit is contained in:
Vaibhav Bhembre 2016-06-21 20:17:25 -04:00
parent e489cd4f07
commit d1f2c557b2
23 changed files with 142 additions and 73 deletions

View File

@ -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,

View File

@ -191,6 +191,7 @@ public:
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,

View File

@ -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 &&
@ -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);
}
@ -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);

View File

@ -33,7 +33,7 @@ public:
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,

View File

@ -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();
@ -581,10 +581,10 @@ 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;
@ -592,7 +592,7 @@ int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
}
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());
@ -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();
}

View File

@ -39,8 +39,8 @@ public:
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);

View File

@ -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);
}
@ -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);
}
@ -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")));

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}
@ -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;
}
@ -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;
}
@ -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;
}

View File

@ -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)
{
}
@ -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;
}

View File

@ -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();
@ -106,6 +107,7 @@ private:
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;

View File

@ -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();
}

View File

@ -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) {

View File

@ -138,8 +138,8 @@ public:
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)));
}

View File

@ -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,

View File

@ -129,12 +129,13 @@ public:
}
int when_resize(MockImageCtx &mock_image_ctx, uint64_t new_size,
uint64_t journal_op_tid, bool disable_journal) {
bool allow_shrink, uint64_t journal_op_tid,
bool disable_journal) {
C_SaferCond cond_ctx;
librbd::NoOpProgressContext prog_ctx;
MockResizeRequest *req = new MockResizeRequest(
mock_image_ctx, &cond_ctx, new_size, prog_ctx, journal_op_tid,
disable_journal);
mock_image_ctx, &cond_ctx, new_size, allow_shrink, prog_ctx,
journal_op_tid, disable_journal);
{
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
req->send();
@ -159,7 +160,7 @@ TEST_F(TestMockOperationResizeRequest, NoOpSuccess) {
expect_append_op_event(mock_image_ctx, 0);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, 0);
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size, 0, false));
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, GrowSuccess) {
@ -182,7 +183,7 @@ TEST_F(TestMockOperationResizeRequest, GrowSuccess) {
expect_update_header(mock_image_ctx, 0);
expect_commit_op_event(mock_image_ctx, 0);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size * 2, 0, false));
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size * 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, ShrinkSuccess) {
@ -209,7 +210,25 @@ TEST_F(TestMockOperationResizeRequest, ShrinkSuccess) {
expect_commit_op_event(mock_image_ctx, 0);
expect_shrink_object_map(mock_image_ctx);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size / 2, 0, false));
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, ShrinkError) {
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
MockExclusiveLock mock_exclusive_lock;
MockJournal mock_journal;
MockObjectMap mock_object_map;
initialize_features(ictx, mock_image_ctx, mock_exclusive_lock, mock_journal,
mock_object_map);
InSequence seq;
expect_block_writes(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, false, 0, false));
}
TEST_F(TestMockOperationResizeRequest, PreBlockWritesError) {
@ -226,7 +245,7 @@ TEST_F(TestMockOperationResizeRequest, PreBlockWritesError) {
InSequence seq;
expect_block_writes(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, TrimError) {
@ -248,7 +267,7 @@ TEST_F(TestMockOperationResizeRequest, TrimError) {
MockTrimRequest mock_trim_request;
expect_trim(mock_image_ctx, mock_trim_request, -EINVAL);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, InvalidateCacheError) {
@ -271,7 +290,7 @@ TEST_F(TestMockOperationResizeRequest, InvalidateCacheError) {
expect_trim(mock_image_ctx, mock_trim_request, 0);
expect_invalidate_cache(mock_image_ctx, -EINVAL);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, PostBlockWritesError) {
@ -293,7 +312,7 @@ TEST_F(TestMockOperationResizeRequest, PostBlockWritesError) {
expect_block_writes(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size * 2, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size * 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, UpdateHeaderError) {
@ -316,7 +335,7 @@ TEST_F(TestMockOperationResizeRequest, UpdateHeaderError) {
expect_update_header(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size * 2, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size * 2, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, JournalAppendError) {
@ -336,7 +355,7 @@ TEST_F(TestMockOperationResizeRequest, JournalAppendError) {
expect_block_writes(mock_image_ctx, 0);
expect_append_op_event(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size, 0, false));
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size, true, 0, false));
}
TEST_F(TestMockOperationResizeRequest, JournalDisabled) {
@ -353,7 +372,7 @@ TEST_F(TestMockOperationResizeRequest, JournalDisabled) {
InSequence seq;
expect_block_writes(mock_image_ctx, 0);
expect_unblock_writes(mock_image_ctx);
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size, 0, true));
ASSERT_EQ(0, when_resize(mock_image_ctx, ictx->size, true, 0, true));
}
} // namespace operation

View File

@ -32,8 +32,9 @@ struct ResizeRequest<MockOperationImageCtx> {
Context *on_finish = nullptr;
static ResizeRequest* create(MockOperationImageCtx &image_ctx, Context *on_finish,
uint64_t new_size, ProgressContext &prog_ctx,
uint64_t journal_op_tid, bool disable_journal) {
uint64_t new_size, bool allow_shrink,
ProgressContext &prog_ctx, uint64_t journal_op_tid,
bool disable_journal) {
assert(s_instance != nullptr);
assert(journal_op_tid == 0);
assert(disable_journal);

View File

@ -274,7 +274,7 @@ struct ResizeTask {
void operator()() {
RWLock::RLocker l(ictx->owner_lock);
C_SaferCond ctx;
ictx->image_watcher->notify_resize(0, 0, *progress_context, &ctx);
ictx->image_watcher->notify_resize(0, 0, true, *progress_context, &ctx);
result = ctx.wait();
}
};

View File

@ -113,7 +113,7 @@ TEST_F(TestInternal, ResizeLocksImage) {
ASSERT_EQ(0, open_image(m_image_name, &ictx));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(0, ictx->operations->resize(m_image_size >> 1, no_op));
ASSERT_EQ(0, ictx->operations->resize(m_image_size >> 1, true, no_op));
bool is_owner;
ASSERT_EQ(0, librbd::is_exclusive_lock_owner(ictx, &is_owner));
@ -128,7 +128,7 @@ TEST_F(TestInternal, ResizeFailsToLockImage) {
ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(-EROFS, ictx->operations->resize(m_image_size >> 1, no_op));
ASSERT_EQ(-EROFS, ictx->operations->resize(m_image_size >> 1, true, no_op));
}
TEST_F(TestInternal, SnapCreateLocksImage) {
@ -336,7 +336,7 @@ TEST_F(TestInternal, CancelAsyncResize) {
size -= MIN(size, 1<<18);
{
RWLock::RLocker l(ictx->owner_lock);
ictx->operations->execute_resize(size, prog_ctx, &ctx, 0);
ictx->operations->execute_resize(size, true, prog_ctx, &ctx, 0);
}
// try to interrupt the in-progress resize
@ -384,7 +384,7 @@ TEST_F(TestInternal, MultipleResize) {
RWLock::RLocker l(ictx->owner_lock);
contexts.push_back(new C_SaferCond());
ictx->operations->execute_resize(new_size, prog_ctx, contexts.back(), 0);
ictx->operations->execute_resize(new_size, true, prog_ctx, contexts.back(), 0);
}
for (uint32_t i = 0; i < contexts.size(); ++i) {
@ -610,9 +610,9 @@ TEST_F(TestInternal, ResizeCopyup)
// verify full / partial object removal properly copyup
librbd::NoOpProgressContext no_op;
ASSERT_EQ(0, ictx2->operations->resize(m_image_size - (1 << order) - 32,
no_op));
true, no_op));
ASSERT_EQ(0, ictx2->operations->resize(m_image_size - (2 << order) - 32,
no_op));
true, no_op));
ASSERT_EQ(0, librbd::snap_set(ictx2, "snap1"));
{
@ -699,7 +699,7 @@ TEST_F(TestInternal, ShrinkFlushesCache) {
ictx->aio_work_queue->aio_write(c, 0, buffer.size(), buffer.c_str(), 0);
librbd::NoOpProgressContext no_op;
ASSERT_EQ(0, ictx->operations->resize(m_image_size >> 1, no_op));
ASSERT_EQ(0, ictx->operations->resize(m_image_size >> 1, true, no_op));
ASSERT_TRUE(c->is_complete());
ASSERT_EQ(0, c->wait_for_complete());
@ -781,7 +781,7 @@ TEST_F(TestInternal, WriteFullCopyup) {
ASSERT_EQ(0, open_image(m_image_name, &ictx));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(0, ictx->operations->resize(1 << ictx->order, no_op));
ASSERT_EQ(0, ictx->operations->resize(1 << ictx->order, true, no_op));
bufferlist bl;
bl.append(std::string(1 << ictx->order, '1'));

View File

@ -420,6 +420,16 @@ TEST_F(TestLibRBD, ResizeAndStat)
ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info)));
ASSERT_EQ(info.size, size / 2);
// downsizing without allowing shrink should fail
// and image size should not change
ASSERT_EQ(-EINVAL, rbd_resize2(image, size / 4, false, NULL, NULL));
ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info)));
ASSERT_EQ(info.size, size / 2);
ASSERT_EQ(0, rbd_resize2(image, size / 4, true, NULL, NULL));
ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info)));
ASSERT_EQ(info.size, size / 4);
ASSERT_PASSED(validate_object_map, image);
ASSERT_EQ(0, rbd_close(image));

View File

@ -144,7 +144,7 @@ TEST_F(TestImageSync, SnapshotStress) {
librbd::NoOpProgressContext no_op_progress_ctx;
uint64_t size = 1 + rand() % m_image_size;
ASSERT_EQ(0, m_remote_image_ctx->operations->resize(size,
ASSERT_EQ(0, m_remote_image_ctx->operations->resize(size, true,
no_op_progress_ctx));
ASSERT_EQ(0, m_remote_image_ctx->state->refresh());

View File

@ -15,10 +15,10 @@ namespace resize {
namespace at = argument_types;
namespace po = boost::program_options;
static int do_resize(librbd::Image& image, uint64_t size, bool no_progress)
static int do_resize(librbd::Image& image, uint64_t size, bool allow_shrink, bool no_progress)
{
utils::ProgressContext pc("Resizing image", no_progress);
int r = image.resize_with_progress(size, pc);
int r = image.resize2(size, allow_shrink, pc);
if (r < 0) {
pc.fail();
return r;
@ -70,14 +70,13 @@ int execute(const po::variables_map &vm) {
return r;
}
if (info.size > size && !vm["allow-shrink"].as<bool>()) {
std::cerr << "rbd: shrinking an image is only allowed with the "
<< "--allow-shrink flag" << std::endl;
return -EINVAL;
}
r = do_resize(image, size, vm[at::NO_PROGRESS].as<bool>());
r = do_resize(image, size, vm["allow-shrink"].as<bool>(), vm[at::NO_PROGRESS].as<bool>());
if (r < 0) {
if (r == -EINVAL && !vm["allow-shrink"].as<bool>()) {
std::cerr << "rbd: shrinking an image is only allowed with the "
<< "--allow-shrink flag" << std::endl;
return r;
}
std::cerr << "rbd: resize error: " << cpp_strerror(r) << std::endl;
return r;
}