From 78d14da8aa4e27a9b8591f38cececed36a6de2e9 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Fri, 13 Apr 2012 17:19:22 -0700 Subject: [PATCH] librbd: flush pending writes when a new snapshot is created This makes sure the state is as consistent as librbd can make it before the snapshot is actually created. Signed-off-by: Josh Durgin --- src/librbd.cc | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/librbd.cc b/src/librbd.cc index 07ddc04a43ee2..ded22b5249e48 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -434,6 +434,7 @@ namespace librbd { int aio_read(ImageCtx *ictx, uint64_t off, size_t len, char *buf, AioCompletion *c); int flush(ImageCtx *ictx); + int _flush(ImageCtx *ictx); ssize_t handle_sparse_read(CephContext *cct, bufferlist data_bl, @@ -751,12 +752,6 @@ int snap_create(ImageCtx *ictx, const char *snap_name) return r; Mutex::Locker l(ictx->lock); - // We need to flush the cache here so that reading our new snapshot - // won't just give us -ENOENT if we've never flushed an object and try - // to read from the new snapshot. - // TODO: Fix this in the ObjectCacher - if (ictx->object_cacher) - ictx->flush_cache(); r = add_snap(ictx, snap_name); if (r < 0) @@ -1126,6 +1121,13 @@ int ictx_refresh(ImageCtx *ictx, const char *snap_name) return r; } + std::map old_snap_ids; + for (std::map::iterator it = + ictx->snaps_by_name.begin(); it != ictx->snaps_by_name.end(); ++it) { + old_snap_ids[it->second.id] = it->first; + } + bool new_snap = false; + ictx->snaps.clear(); ictx->snapc.snaps.clear(); ictx->snaps_by_name.clear(); @@ -1141,6 +1143,15 @@ int ictx_refresh(ImageCtx *ictx, const char *snap_name) ::decode(image_size, iter); ::decode(s, iter); ictx->add_snap(s, id, image_size); + std::map::const_iterator it = old_snap_ids.find(id); + if (it == old_snap_ids.end()) { + new_snap = true; + ldout(cct, 20) << "new snapshot " << s << " size " << image_size << dendl; + } + } + + if (new_snap) { + _flush(ictx); } if (!ictx->snapc.is_valid()) { @@ -1614,6 +1625,13 @@ int flush(ImageCtx *ictx) if (r < 0) return r; + return _flush(ictx); +} + +int _flush(ImageCtx *ictx) +{ + CephContext *cct = ictx->cct; + int r; // flush any outstanding writes if (ictx->object_cacher) { ictx->flush_cache(); -- 2.39.5