int order;
uint64_t size;
uint64_t p_features;
- int remove_r;
+ int partial_r;
librbd::NoOpProgressContext no_op;
ImageCtx *c_imctx = NULL;
map<string, bufferlist> pairs;
}
ldout(cct, 2) << "done." << dendl;
- close_image(c_imctx);
- close_image(p_imctx);
- return 0;
+ r = close_image(c_imctx);
+ partial_r = close_image(p_imctx);
+ if (r == 0 && partial_r < 0) {
+ r = partial_r;
+ }
+ return r;
err_remove_child:
- remove_r = cls_client::remove_child(&c_ioctx, RBD_CHILDREN, pspec,
- c_imctx->id);
- if (remove_r < 0) {
+ partial_r = cls_client::remove_child(&c_ioctx, RBD_CHILDREN, pspec,
+ c_imctx->id);
+ if (partial_r < 0) {
lderr(cct) << "Error removing failed clone from list of children: "
- << cpp_strerror(remove_r) << dendl;
+ << cpp_strerror(partial_r) << dendl;
}
err_close_child:
close_image(c_imctx);
err_remove:
- remove_r = remove(c_ioctx, c_name, no_op);
- if (remove_r < 0) {
+ partial_r = remove(c_ioctx, c_name, no_op);
+ if (partial_r < 0) {
lderr(cct) << "Error removing failed clone: "
- << cpp_strerror(remove_r) << dendl;
+ << cpp_strerror(partial_r) << dendl;
}
err_close_parent:
close_image(p_imctx);
}
r = copy(src, dest, prog_ctx);
- close_image(dest);
+ int close_r = close_image(dest);
+ if (r == 0 && close_r < 0) {
+ r = close_r;
+ }
return r;
}
return r;
}
- void close_image(ImageCtx *ictx)
+ int close_image(ImageCtx *ictx)
{
ldout(ictx->cct, 20) << "close_image " << ictx << dendl;
ictx->flush_async_operations();
ictx->readahead.wait_for_pending();
+ int r;
if (ictx->object_cacher) {
- ictx->shutdown_cache(); // implicitly flushes
+ r = ictx->shutdown_cache(); // implicitly flushes
} else {
- flush(ictx);
+ r = flush(ictx);
+ }
+ if (r < 0) {
+ lderr(ictx->cct) << "error flushing IO: " << cpp_strerror(r)
+ << dendl;
}
ictx->op_work_queue->drain();
}
if (ictx->parent) {
- close_image(ictx->parent);
+ int close_r = close_image(ictx->parent);
+ if (r == 0 && close_r < 0) {
+ r = close_r;
+ }
ictx->parent = NULL;
}
{
RWLock::WLocker l(ictx->owner_lock);
if (ictx->image_watcher->is_lock_owner()) {
- int r = ictx->image_watcher->unlock();
- if (r < 0) {
- lderr(ictx->cct) << "error unlocking image: " << cpp_strerror(r)
- << dendl;
+ int unlock_r = ictx->image_watcher->unlock();
+ if (unlock_r < 0) {
+ lderr(ictx->cct) << "error unlocking image: "
+ << cpp_strerror(unlock_r) << dendl;
+ if (r == 0) {
+ r = unlock_r;
+ }
}
}
}
}
delete ictx;
+ return r;
}
// 'flatten' child image by copying all parent's blocks
Image::~Image()
{
+ close();
+ }
+
+ int Image::close()
+ {
+ int r = 0;
if (ctx) {
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, close_image_enter, ictx, ictx->name.c_str(), ictx->id.c_str());
- close_image(ictx);
- tracepoint(librbd, close_image_exit);
+ r = close_image(ictx);
+ ctx = NULL;
+ tracepoint(librbd, close_image_exit, r);
}
+ return r;
}
int Image::resize(uint64_t size)
{
librbd::ImageCtx *ctx = (librbd::ImageCtx *)image;
tracepoint(librbd, close_image_enter, ctx, ctx->name.c_str(), ctx->id.c_str());
- librbd::close_image(ctx);
- tracepoint(librbd, close_image_exit);
- return 0;
+ int r = librbd::close_image(ctx);
+ tracepoint(librbd, close_image_exit, r);
+ return r;
}
extern "C" int rbd_resize(rbd_image_t image, uint64_t size)