From ae91911c7588b30999a895a636641bd34731d8be Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Mon, 24 Oct 2011 12:36:03 -0700 Subject: [PATCH] librbd: resize if necessary before rolling back This is a partial fix for test_rbd.TestImage.test_rollback_with_resize Signed-off-by: Josh Durgin --- src/librbd.cc | 117 +++++++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 44 deletions(-) diff --git a/src/librbd.cc b/src/librbd.cc index d5f79ea6c1858..ed6734f03b2e1 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -137,6 +137,16 @@ namespace librbd { return CEPH_NOSNAP; } + int get_snap_size(std::string snap_name, uint64_t *size) const + { + std::map::const_iterator it = snaps_by_name.find(snap_name); + if (it != snaps_by_name.end()) { + *size = it->second.size; + return 0; + } + return -ENOENT; + } + void add_snap(std::string snap_name, snap_t id, uint64_t size) { snapc.snaps.push_back(id); @@ -332,6 +342,7 @@ namespace librbd { int info(ImageCtx *ictx, image_info_t& info, size_t image_size); int remove(IoCtx& io_ctx, const char *imgname, ProgressContext& prog_ctx); int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx); + int resize_helper(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx); int snap_create(ImageCtx *ictx, const char *snap_name); int snap_list(ImageCtx *ictx, std::vector& snaps); int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx); @@ -863,17 +874,9 @@ int remove(IoCtx& io_ctx, const char *imgname, ProgressContext& prog_ctx) return 0; } -int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx) +int resize_helper(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx) { CephContext *cct = ictx->cct; - ldout(cct, 20) << "resize " << ictx << " " << ictx->header.image_size << " -> " << size << dendl; - - int r = ictx_check(ictx); - if (r < 0) - return r; - - Mutex::Locker l(ictx->lock); - // trim if (size == ictx->header.image_size) { ldout(cct, 2) << "no change in size (" << size << " -> " << ictx->header.image_size << ")" << dendl; return 0; @@ -891,7 +894,7 @@ int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx) // rewrite header bufferlist bl; bl.append((const char *)&(ictx->header), sizeof(ictx->header)); - r = ictx->md_ctx.write(ictx->md_oid(), bl, bl.length(), 0); + int r = ictx->md_ctx.write(ictx->md_oid(), bl, bl.length(), 0); if (r == -ERANGE) lderr(cct) << "operation might have conflicted with another client!" << dendl; @@ -902,6 +905,21 @@ int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx) notify_change(ictx->md_ctx, ictx->md_oid(), NULL, ictx); } + return 0; +} + +int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx) +{ + CephContext *cct = ictx->cct; + ldout(cct, 20) << "resize " << ictx << " " << ictx->header.image_size << " -> " << size << dendl; + + int r = ictx_check(ictx); + if (r < 0) + return r; + + Mutex::Locker l(ictx->lock); + resize_helper(ictx, size, prog_ctx); + ldout(cct, 2) << "done." << dendl; return 0; @@ -1063,6 +1081,38 @@ int ictx_refresh(ImageCtx *ictx, const char *snap_name) return 0; } +ProgressContext::~ProgressContext() +{ +} + +class NoOpProgressContext : public librbd::ProgressContext +{ +public: + NoOpProgressContext() + { + } + int update_progress(uint64_t offset, uint64_t src_size) + { + return 0; + } +}; + +class CProgressContext : public librbd::ProgressContext +{ +public: + CProgressContext(librbd_progress_fn_t fn, void *data) + : m_fn(fn), m_data(data) + { + } + int update_progress(uint64_t offset, uint64_t src_size) + { + return m_fn(offset, src_size, m_data); + } +private: + librbd_progress_fn_t m_fn; + void *m_data; +}; + int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx) { CephContext *cct = ictx->cct; @@ -1079,6 +1129,17 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_c return -ENOENT; } + uint64_t new_size = ictx->get_image_size(); + ictx->get_snap_size(snap_name, &new_size); + ldout(cct, 2) << "resizing to snapshot size..." << dendl; + NoOpProgressContext no_op; + r = resize_helper(ictx, new_size, no_op); + if (r < 0) { + lderr(cct) << "Error resizing to snapshot size: " + << cpp_strerror(-r) << dendl; + return r; + } + r = rollback_image(ictx, snapid, prog_ctx); if (r < 0) { lderr(cct) << "Error rolling back image: " << cpp_strerror(-r) << dendl; @@ -1088,11 +1149,11 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_c // refresh without setting the snapid we read from ictx_refresh(ictx, NULL); snap_t new_snapid = ictx->get_snapid(snap_name); - ldout(ictx->cct, 20) << "snapid is " << ictx->snapid << " new snapid is " << new_snapid << dendl; + ldout(cct, 20) << "snapid is " << ictx->snapid << " new snapid is " << new_snapid << dendl; notify_change(ictx->md_ctx, ictx->md_oid(), NULL, ictx); - return 0; + return r; } struct CopyProgressCtx { @@ -1116,38 +1177,6 @@ int do_copy_extent(uint64_t offset, size_t len, const char *buf, void *data) return ret; } -ProgressContext::~ProgressContext() -{ -} - -class NoOpProgressContext : public librbd::ProgressContext -{ -public: - NoOpProgressContext() - { - } - int update_progress(uint64_t offset, uint64_t src_size) - { - return 0; - } -}; - -class CProgressContext : public librbd::ProgressContext -{ -public: - CProgressContext(librbd_progress_fn_t fn, void *data) - : m_fn(fn), m_data(data) - { - } - int update_progress(uint64_t offset, uint64_t src_size) - { - return m_fn(offset, src_size, m_data); - } -private: - librbd_progress_fn_t m_fn; - void *m_data; -}; - int copy(ImageCtx& ictx, IoCtx& dest_md_ctx, const char *destname, ProgressContext &prog_ctx) { -- 2.39.5